代码之家  ›  专栏  ›  技术社区  ›  pfinferno

更改所选项目时UI不更新

  •  0
  • pfinferno  · 技术社区  · 7 年前

    我有一个 ListBox 谁的 ItemSource 绑定到 PointStyleModel 包含在我的 PointStylesViewModel . 这个 点样式模型

    A TextBox 是与 Name IntegerUpDown 是和大小有关的。 xceed工具箱 ColorPicker 一定是彩色的。

    文本框 绑定到 姓名 很好用。我尝试过各种绑定模式和updatesourcetrigger,但没有成功。

    这是我的模型课:

    public class PointStyleModel
    {
        public int Size
        {
            get;
            set;
        }
    
        public string Name
        {
            get;
            set;
        }
    
        public GeoColor Color
        {
            get;
            set;
        }
    }
    

    以下是我的viewmodel:

    public class PointStylesViewModel : ViewModelBase //using Fody's PropertyChangedInterface in the base class
    {
        public ObservableCollection<PointStyleModel> PointStyles { get; set; } //the listbox is bound to this
    
        public PointStyleModel SelectedPointStyle { get; set; } //bound to the listboxe's selected item
    
        public string PointStyleName { get { return SelectedPointStyle.Name; } }
    
        public Color PointStyleColor
        {
            get
            {
                return Color.FromArgb(SelectedPointStyle.Color.AlphaComponent, SelectedPointStyle.Color.RedComponent, SelectedPointStyle.Color.GreenComponent, SelectedPointStyle.Color.BlueComponent); //Need to convert GeoColor to Color
            }
        }
    
        public int PointStyleSize { get { return SelectedPointStyle.Size; } }
    
        public PointStylesViewModel()
        {
            PointStyles = new ObservableCollection<PointStyleModel>();
            AddDefaultPointStyles(); //add some default styles
    
            SelectedPointStyle = PointStyles.First(); //select the first item in the list when starting up
        }
    }
    

    以下是我观点的相关部分:

    <TabItem DataContext="{Binding Path=PointStylesViewModel, Source={StaticResource ViewModelLocator}}">
        <Grid>
            <ListBox ItemsSource="{Binding PointStyles}" SelectedItem="{Binding SelectedPointStyle}" DisplayMemberPath="Name"/>
            <TextBox Text="{Binding PointStyleName, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
            <GroupBox Header="Paint">
                <Grid>
                    <xctk:ColorPicker SelectedColor="{Binding Path=PointStyleColor, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" DisplayColorAndName="False" DisplayColorTooltip="True"/>
                    <xctk:IntegerUpDown Value="{Binding PointStyleSize, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Maximum="20" Minimum="0" />
                </Grid>
            </GroupBox>
        </Grid>
    </TabItem>
    

    首先,我在列表框中选择一个项目。所有内容都已正确填充。 enter image description here

    enter image description here

    然后我将从列表中选择另一项: enter image description here

    在第一张图片中,我选择了RedSquare6,它用VM中的PointStyleColor属性填充ColorPicker。它从SelectedPointStyle的Color属性中获取该值。这个很好用。

    在第二幅图中,我从ColorPicker控件中选择了一种新颜色,在本例中为粉红色。这不应改变任何属性。我只是在改变控件的颜色。RedSquare6的颜色属性仍应为红色。

    在第三张图中,我选择了GreenSquare6。ColorPicker控件现在应该显示为绿色,但它保持为粉红色,并且不再命中VM中的PointStyleColor getter。

    同样适用于 Size 积分下降控制。

    选择新颜色时,颜色选择器和intupdown没有更新。我注意到在更改选择时没有命中属性。这个 PointStyleName 不过是这样。

    using PropertyChanged;
    using System.ComponentModel;
    
    namespace WpfApp1.ViewModels
    {
        /// <summary>
        /// A base model that fires Property Changed events as needed
        /// </summary>
        [AddINotifyPropertyChangedInterface]
        public class ViewModelBase : INotifyPropertyChanged
        {
            /// <summary>
            /// The event is fired when any child property changes its value
            /// </summary>
            public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
        }
    }
    

    这是正在发生的事情的gif。我正在测试intupdown控件: enter image description here

    编辑:下面是一个显示问题的小示例应用程序: https://www.dropbox.com/s/l3gu3nj915cstoa/TestApp.zip?dl=0

    1 回复  |  直到 7 年前
        1
  •  0
  •   Clayton Harbich    7 年前

    首先,需要在ViewModelBase中正确实现INotifyPropertyChanged。

    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    

    第二,需要在PointStylesViewModel上更改的选定项上使用它:

    private PointStyleModel _selectedPointStyle;
    public PointStyleModel SelectedPointStyle
    {
        get => _selectedPointStyle;
        set
        {
            _selectedPointStyle = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(PointStyleColor)); 
            OnPropertyChanged(nameof(PointStyleSize)); 
        }
     }