如何判断我的自定义控件的 ItemsSource 何时更改

How can I tell when the ItemsSource of my Custom control has changed

在努力学习wpf自定义控件开发的过程中,我有一个处于开发初期的自定义控件。自定义控件继承自 ItemsControls,它使我可以访问 ItemsSource 属性,我将绑定一个可枚举集合。

目前我有一个简单的两个项目解决方案,其中一个是我的自定义控件,另一个是测试项目以测试前者。在我的测试项目中,我有一个简单的 mainwindow,我在上面放置了自定义控件并绑定了它的 ItemsSource.

    <WpfControls:VtlDataNavigator x:Name="MyDataNavigator"
                                      ItemsSource="{Binding ElementName=MainWindow, Path=Orders}" />

在主要 window(实现 INotifyPropertyChanged)的加载事件中,我实例化了 Orders 集合。自定义控件在主 window 加载之前初始化,但我可以通过检查 visual studio 中的实时可视化树看到,一旦主窗体加载自定义控件,项目源 属性 确实设置为订单.现在当然我实际上想要计算订单并让我的自定义控件显示它(它是一个简单的数据导航器所以我所追求的是记录计数)。我知道如何获取计数,但我如何知道 itemsSource 何时更改,以便我可以对其做出反应并获取计数。我看不到 itemsSourceChanged 事件。

我看过 this 博客文章,但我想知道是否有更直接的方法来解决这个问题,因为这似乎是一件显而易见的事情,我想知道。

ItemsSource 是一个 DependencyProperty,创建 DP 时您可以选择指定一个 "property changed" 事件。不幸的是 ItemsSource 被锁定在基础 class 中,所以我开始想知道是否有办法将您自己的事件添加到现有的 DP。我发现 this article 看起来很有希望。基本上你会做这样的事情(未经测试所以阅读文章!):-

var dpd = DependencyPropertyDescriptor.FromProperty(
    VtlDataNavigator.ItemsSourceProperty, 
    typeof(VtlDataNavigator));

if (dpd != null)
{
    dpd.AddValueChanged(
        vtlDataNavigatorInstance, 
        delegate
          {
              var count = VtlDataNavigatorInstance.ItemsSource.Count; // Or whatever...
          });
}

您可以使用 OverrideMetaData 来做到这一点。

试试这个:

public class Class1 : ItemsControl
{
    static Class1()
    {
        ItemsSourceProperty.OverrideMetadata(typeof(Class1), 
        new FrameworkPropertyMetadata(null, OnItemSourceChanged));
    }

    private static void OnItemSourceChanged(DependencyObject d, 
                                            DependencyPropertyChangedEventArgs e)
    {
        Debug.WriteLine("Why you haz Changed me!");
    }
}