【问题标题】:Property Changed in DependencyPropertyDependencyProperty 中的属性已更改
【发布时间】:2013-11-02 17:50:04
【问题描述】:

previous post 中,我询问了如何将属性注册为 DependencyProperty。我得到了一个答案,它工作正常。

但现在我想在单击时向此 DependencyProperty 添加一些项目。这行不通。我注册 DependencyProperty 的代码是:

public static readonly DependencyProperty ChartEntriesProperty = DependencyProperty.Register(
        "ChartEntries", typeof(ObservableCollection<ChartEntry>), typeof(ChartView),
        new FrameworkPropertyMetadata(OnChartEntriesChanged));

    private static void OnChartEntriesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {

    }

OnChartEntriesChanged-Event 在我将 XAML 绑定到我的 c# 代码时被调用。但是,如果我之后添加 ChartEntry(单击按钮),则不会触发该事件。

有人知道为什么吗?

【问题讨论】:

    标签: c# wpf dependency-properties


    【解决方案1】:

    当您将项目添加到ChartEntries 集合时,您并没有实际更改该属性,因此不会调用 PropertyChangedCallback。为了获得有关集合更改的通知,您需要注册一个额外的CollectionChanged 事件处理程序:

    private static void OnChartEntriesChanged(
        DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var chartView = (ChartView)obj;
        var oldCollection = e.OldValue as INotifyCollectionChanged;
        var newCollection = e.NewValue as INotifyCollectionChanged;
    
        if (oldCollection != null)
        {
            oldCollection.CollectionChanged -= chartView.OnChartEntriesCollectionChanged;
        }
    
        if (newCollection != null)
        {
            newCollection.CollectionChanged += chartView.OnChartEntriesCollectionChanged;
        }
    }
    
    private void OnChartEntriesCollectionChanged(
        object sender, NotifyCollectionChangedEventArgs e)
    {
        ...
    }
    

    不使用ObservableCollection&lt;ChartEntry&gt; 作为属性类型也很有意义,而只需使用ICollectionIEnumerable。这将允许在具体集合类型中实现INotifyCollectionChanged 的其他实现。请参阅herehere 了解更多信息。

    【讨论】:

      【解决方案2】:

      当您设置ObservableCollection 的新实例时,将调用OnChartEntriesChanged 回调。您将不得不收听如下更改的集合:

          private static void OnChartEntriesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              ((ObservableCollection<ChartView>)e.OldValue).CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ChartView_CollectionChanged);   
              ((ObservableCollection<ChartView>)e.NewValue).CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ChartView_CollectionChanged);   
          }
      
          static void ChartView_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
          {
      
          }
      

      【讨论】:

        【解决方案3】:

        很抱歉,这不起作用,因为您已检测到自己。 DependencyProperty 更改的处理程序仅在属性值更改时才会触发,但在您的情况下不会触发,因为对象引用仍然相同。您必须在提供的集合的 CollectionChanged 事件处理程序上注册。 (您可以在依赖属性的 propertychanged 处理程序中执行此操作)

        【讨论】:

          【解决方案4】:

          Clemens 的答案看起来不错,对我帮助很大。但是,在许多情况下,您希望在将整个集合替换为另一个集合时也调用 CollectionChanged 事件处理程序。为此,只需从 PropertyChanged 事件处理程序显式直接调用 CollectionChanged 事件处理程序。完整的代码如下所示。

          private static void OnChartEntriesChanged(
              DependencyObject obj, DependencyPropertyChangedEventArgs e)
          {
              var chartView = (ChartView)obj;
              var oldCollection = e.OldValue as INotifyCollectionChanged;
              var newCollection = e.NewValue as INotifyCollectionChanged;
          
              if (oldCollection != null)
              {
                  oldCollection.CollectionChanged -= chartView.OnChartEntriesCollectionChanged;
              }
          
              if (newCollection != null)
              {
                  newCollection.CollectionChanged += chartView.OnChartEntriesCollectionChanged;
              }
          
              // The first parameter below can also be null
              chartView.OnChartEntriesCollectionChanged(newCollection, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
          }
          
          private void OnChartEntriesCollectionChanged(
              object sender, NotifyCollectionChangedEventArgs e)
          {
              ...
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-21
            • 1970-01-01
            • 1970-01-01
            • 2019-07-08
            • 2019-01-16
            • 2021-07-31
            • 1970-01-01
            • 2014-12-17
            相关资源
            最近更新 更多