Свойство зависимости и проблема инициализации ViewModel - PullRequest
0 голосов
/ 27 января 2010

Я пытаюсь добавить свой собственный ItemsSource, чтобы предоставить список GraphViewModels для диаграммы. Хотя я не думаю, что у меня все в порядке, поскольку, когда я создаю свою первую GraphViewModel и добавляю ее в Графики, мой DP обновляется, но OnGraphsCollectionChanged не вызывается.

Как это должно работать? Если я добавлю графики к своему свойству виртуальной машины с помощью кнопки, привязанной к команде, то все будет хорошо.

Вот код DP, кто-нибудь может объяснить, как это должно работать или что я делаю неправильно, чтобы отображать мои данные во время инициализации?

public static readonly DependencyProperty GraphsProperty = 
    DependencyProperty.Register("ItemsSource", 
    typeof(ObservableCollection<GraphViewModel>), 
    typeof(DynamicPlotter), 
    new FrameworkPropertyMetadata(new PropertyChangedCallback(ChangeGraphs)));

public ObservableCollection<GraphViewModel> ItemsSource
{
    get { return (ObservableCollection<GraphViewModel>)GetValue(GraphsProperty); }
    set
    {
        SetValue(GraphsProperty, value);
        ItemsSource.CollectionChanged += new NotifyCollectionChangedEventHandler(OnGraphsCollectionChanged);
    }
}

public static void ChangeGraphs(DependencyObject source, DependencyPropertyChangedEventArgs eventArgs)
{
    (source as   DynamicPlotter).UpdateGraphs((ObservableCollection<GraphViewModel>)eventArgs.NewValue);
}

private void UpdateLineGraphs(ObservableCollection<GraphViewModel> grphs)
{
    this.ItemsSource = grphs;
}

private void OnGraphsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // This never gets called when you set the ItemsSource, but is where all the work is done
}

1 Ответ

1 голос
/ 27 января 2010

CollectionChanged вызывается только при изменении коллекции, если коллекция уже заполнена до ее установки, вы никогда не получите уведомление, пока что-то не будет добавлено / удалено.

Во-вторых, если вы устанавливаете свойство зависимости из xaml, то метод получения / установки не используется, механизм зависимости использует свои собственные внутренние процедуры установки. Вы должны прикрепить событие collectionChanged в функцию обратного вызова свойства ChangeGraphs, так как она вызывается всякий раз, когда свойство устанавливается / изменяется. Вы также можете использовать это, чтобы отсоединить старое событие collectionChanged, аргументы события приведут к старому и новому значению.

Но на самом деле, это наблюдаемая коллекция, которую вы не должны знать, когда коллекция изменяется, поскольку вы должны привязывать коллекцию и когда она изменится, механизм привязки обновит ваш интерфейс.

Я бы изменил свой код, чтобы он выглядел следующим образом

  public ObservableCollection<GraphViewModel> ItemsSource {
     get { return (ObservableCollection<GraphViewModel>)GetValue(ItemsSourceProperty); }
     set { SetValue(ItemsSourceProperty, value); }
  }

  // Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
  public static readonly DependencyProperty ItemsSourceProperty =
      DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<GraphViewModel>), typeof(DynamicPlotter), new UIPropertyMetadata(null, (o, e) => { ((DynamicPlotter)o).ItemsSourceChanged(); }));

  private void ItemsSourceChanged() {
     if (this.ItemsSource != null){
        //attach the collection changed listener, this will listen to all FUTURE collection changes, items that are added and removed
        this.ItemsSource.CollectionChanged +=new NotifyCollectionChangedEventHandler(ItemsSource_CollectionChanged);
        //do some inital processing with the items that are in the collection already when it is set
        this.UpdateGraphs(this.ItemsSource);
  }

  private void ItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e){
          //this will get called if an item gets added or removed from the collection
  }
...