简体   繁体   中英

WPF ItemsControl not refreshing

I'm working on a WPF project. I have a class like this:

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

    public DelegateCommand FieldChangeCommand { get; set; }

    public bool Available { get; set; }
}

And I have a collection of it

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

My view looks like this

<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>

This works perfectly for the first time, when it loads. But later on I might have some values of Fields changed. For example: (part of the viewmodel code)

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

Is sure that Fields get updated after this, because other elements on the view (like textboxes) refresh. But the buttongrid on the view doesn't update with the new values of Fields.

Can somebody please tell me why, and how to solve this problem?

The Content of your button is bound to the Statusz property on your ReservationDTO class which means that will need to implement INotifyPropertyChanged in order for the Buttons content to change to "Sold". It is understandable you wouldn't want it on your DTO class.

Also the calls to OnPropertyChanged look wrong to me (I am assuming that your ViewModel has the Fields property on it and is the class that inherits from ViewModelBase?

You need to do something like the following (Please note I haven't added any null reference checks for your _reservation field):

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));       
        }
    }
}

And then change your buttons binding to:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM