WPF ItemsControl 不刷新

WPF ItemsControl not refreshing

我正在处理一个 WPF 项目。我有一个 class 这样的:

public class Field
{
    public ReservationDTO reservation { get; set; }

    public DelegateCommand FieldChangeCommand { get; set; }

    public bool Available { get; set; }
}

我有 collection 个

public ObservableCollection<Field> Fields { get; set; }

我的观点是这样的

<ItemsControl ItemsSource="{Binding Fields}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid
                Columns="{Binding Columns}"
                Rows="{Binding Rows}"
                />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Command="{Binding FieldChangeCommand}" CommandParameter="{Binding}" Content="{Binding reservation.Statusz}" FontSize="5" IsEnabled="{Binding Available}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

这是第一次加载时完美运行。但稍后我可能会更改 Fields 的一些值。例如:(部分viewmodel代码)

Fields[SelectedIndex].reservation.Statusz = "Sold";
Fields[SelectedIndex].Available = false;
OnPropertyChanged("Fields");
OnPropertyChanged("Available");

确保在此之后更新字段,因为视图上的其他元素(如文本框)会刷新。但是视图上的按钮网格不会更新为字段的新值。

谁能告诉我为什么,以及如何解决这个问题?

按钮的内容绑定到 ReservationDTO class 上的 Statusz 属性,这意味着需要实施 INotifyPropertyChanged 才能将按钮内容更改为 "Sold" .可以理解,您不希望它出现在您的 DTO class.

对 OnPropertyChanged 的​​调用在我看来也是错误的(我假设您的 ViewModel 上有字段 属性 并且 class 是从 ViewModelBase 继承的吗?

您需要执行如下操作(请注意我没有为您的 _reservation 字段添加任何空引用检查):

public class Field : INotifyPropertyChanged
{
    private bool _available;
    private ReservationDTO _reservation;

    public string Statusz
    {
        get
        {
            return _reservation.Statusz;
        }
        set
        {
            if (_reservation.Statusz != value)
            {
                _reservation.Statusz = value;

                OnPropertyChanged("Available");
            }
        }
    }

    public DelegateCommand FieldChangeCommand { get; set; }

    public bool Available
    {
        get
        {
            return _available;
        }
        set
        {
            if (_available != value)
            {
                _available = value;

                OnPropertyChanged("Available");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var localHandler = this.PropertyChanged;

        if (localHandler != null)
        {
            localHandler(this, new PropertyChangedEventArgs(propertyName));       
        }
    }
}

然后将您的按钮绑定更改为:

<Button Command="{Binding FieldChangeCommand}" CommandParameter="{Binding}" Content="{Binding Statusz}" FontSize="5" IsEnabled="{Binding Available}"/>