2015-05-21 3 views
1

Я работаю над проектом WPF. У меня есть класс, как это:WPF ItemsControl not refreshing

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

    public DelegateCommand FieldChangeCommand { get; set; } 

    public bool Available { get; set; } 
} 

И у меня есть коллекция его

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> 

Это прекрасно работает в первый раз, когда он грузы. Но позже я мог бы изменить некоторые значения полей. Например: (часть кода ViewModel)

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

уверен, что поля обновляются после этого, потому что другие элементы на представлении (например, текстовые поля) обновить. Но buttongrid в представлении не обновляется новыми значениями полей.

Может кто-нибудь, пожалуйста, скажите мне, почему и как решить эту проблему?

+0

Вы implem INotifyPropertyChanged в вашем классе резервированияDTO. Если нет, пользовательский интерфейс не будет получать уведомления о том, что ваше свойство Statusz изменилось. – Bijington

+0

@Bijington У меня есть ViewModelBase вот так. public abstract class ViewModelBase: INotifyPropertyChanged { общественное событие PropertyChangedEventHandler PropertyChanged; защищен ViewModelBase() {} защищенный виртуальный аннулируются OnPropertyChanged ([CallerMemberName] Строка ИмениСвойства = NULL) { если (PropertyChanged! = NULL) { PropertyChanged (это, новые PropertyChangedEventArgs (ИмениСвойства)); } } } –

+0

@Bijington, если я создаю свой класс Field, полученный из ViewModelBase, достаточно? Потому что я не уверен, могу ли я изменить класс ReservationDTO. –

ответ

2

Содержимое вашей кнопки привязано к свойству Statusz в вашем классе ReservationDTO, что означает, что для реализации содержимого кнопок будет изменено значение «Продано», это будет необходимо для реализации INotifyPropertyChanged. Понятно, что вы не захотите этого в своем классе DTO.

Также призывы OnPropertyChanged выглядеть неправильно меня (я предполагаю, что ваш ViewModel имеет свойство Fields на нем и есть класс, который наследует от 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}"/> 
+0

Это выглядит очень красиво, и я понимаю причину. Хотя у меня есть проблема, что this.PropertyChanged дает ошибку (не содержит определения). Не могли бы вы рассказать, как решить эту проблему? Может быть, я должен перенести свой класс Field из viewmodel? класс ReservationViewModel: ViewModelBase –

+0

Извините, что я пропустил объявление измененного обработчика свойства. Я добавил его в свой ответ. Вы можете просто добавить следующее в свой класс Field: public event PropertyChangedEventHandler PropertyChanged; – Bijington