2009-11-20 2 views
1

Я не реализовал этот шаблон некоторое время (и когда я сделал это было в 2, а не в 3), и у меня есть несколько примеров, которые кажутся прямолинейными, но я не может работать, что я сделал неправильно в приведенном ниже фрагменте кода (детали не обновляется, когда срабатывает событие свойство):Silverlight: INotifyPropertyChanged не работает

public partial class Index : Page 
{ 
    private IndexViewModel _vm; 

    public Index() 
    { 
     InitializeComponent(); 
     _vm = new IndexViewModel(19);   

     this.TheDataGrid.ItemsSource = _vm.Rows; 
    } 




public class IndexViewModel : INotifyPropertyChanged 
    { 
    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

     protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
     {   
      this.PropertyChanged(this, e); 
     } 

public SortableCollectionView Rows 
     { 
      get 
     { 
      return _rows; 
     } 
     set 
     { 
      if (_rows == value) 
       return; 

      _rows = value; 
      this.OnPropertyChanged(new PropertyChangedEventArgs("Rows"));         
     } 
    } 

Это не успокой мое DataGrid ... как «хак» Я должен был пройти DataGrid объект в мой ViewModel и связать его там:

public IndexViewModel(int containerModelId, DataGrid shouldNotNeed) 
     { 
      ContainerModelId = containerModelId; 

     LoadOperation<vwColumn> headings = _ttasContext.Load(_ttasContext.GetRecordColumnsQuery(ContainerModelId)); 
     headings.Completed += (sender2, e2) => 
     { 
      //load data 
      LoadOperation<vwDataValue> data = _ttasContext.Load(_ttasContext.GetRecordsQuery(ContainerModelId, null)); 
      data.Completed += (sender3, e3) => 
      { 

        Rows = FormatData(data, headings); 
shouldNotNeed.ItemsSource = Rows; 
       }; 
      }; 
     } 

ответ

2

Назначение _vm.Rows на TheDataGrid.ItemsSource автоматически не вызывает обратный вызов уведомления об изменении. Попробуйте это: в XAML:

<... x:Name=TheDataGrid ItemsSource={Binding Rows}> 

В коде:

this.DataContext = _vm; 
0

Как Codism указывает ваш основной проблемой является вам нужно использовать привязку, чтобы воспользоваться в INotifyPropertyChanged. Однако я бы рекомендовал эту модель реализации: -

public event PropertyChangedEventHandler PropertyChanged; 

void NotifyPropertyChanged(string name) 
{   
    if (PropertyChanged != null) 
    PropertyChanged(this, new PropertyChangedEventArgs(name); 
} 

...

set 
    { 
    if (_rows != value) 
    { 
     _rows = value; 
     NotifyPropertyChanged("Rows"); 
    } 
    } 

Следует отметить, что такой подход сводит к минимуму воздействие на экземпляр объекта, свойства которого не наблюдается. В исходном шаблоне вы создаете экземпляры PropertyChangedEventArgs и вызываете делегата события, выходящего независимо от того, что-то действительно слушает.

+0

я прочитал в другом посте где-то, что если вы имели = делегатом {} в конце объявления вам не нужно иметь если (свойство изменилось! = NULL) Однако, даже если это тот случай, о котором вы прокомментируете, делает вывод, что код менее ясен, поэтому я изменил его, спасибо! –

+0

@Grayson: Да, есть некоторые преимущества для этого делегирования {} трюка, однако обычный шаблон для событий в целом заключается в использовании виртуального защищенного метода OnXXXX, который получает соответствующий объект EventArgs. Проблема с этим подходом для INotifyPropertyChanged заключается в том, что значения свойств могут быстро меняться (например, при анимации). Это может привести к созданию большого количества экземпляров PropertyChangedEventArgs, но ничто не слушает, это, в свою очередь, создало бы ненужную нагрузку на GC. – AnthonyWJones

0

this.TheDataGrid.ItemsSource = _vm.Rows

Когда коллекция назначается в качестве ItemsSource о наличии DataGird, любые изменения, сделанные в коллекцию можно наблюдать с помощью DataGrid, если источник реализует INotifyCollectionChanged ,
Из вашего образца кода я не могу определить, реализует ли тип SortableCollectionView INotifyCollectionChanged или наследует от ObservableCollection.
Реализация INotifyCollectionChanged означает, что вы не можете сбросить поле поддержки _rows для строк свойств, вы можете очистить элементы в коллекции и добавить их по мере необходимости.
Надеюсь, что это помогает

Смежные вопросы