【问题标题】:How can I tell when the ItemsSource of my Custom control has changed如何判断我的自定义控件的 ItemsSource 何时更改
【发布时间】:2015-11-12 14:42:52
【问题描述】:

我在开发的早期阶段有一个自定义控件,因为我努力学习 wpf 自定义控件开发。自定义控件继承自 ItemsControls,这使我可以访问绑定可枚举集合的 ItemsSource 属性。

目前我有一个简单的两个项目解决方案,其中一个包含我的自定义控件,另一个包含一个测试项目来测试前者。在我的测试项目中,我有一个简单的主窗口,我在上面放置了我的自定义控件并绑定了它的 ItemsSource。

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

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

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

【问题讨论】:

    标签: wpf vb.net custom-controls itemscontrol itemssource


    【解决方案1】:

    您可以使用 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!");
        }
    }
    

    【讨论】:

    • 非常好的解决方案,而且肯定比我想出的临时解决方案更优雅。谢谢。
    • 当然!此外,如果您想为控件的使用者提供支持,您可以添加一个事件处理程序。
    【解决方案2】:

    ItemsSource 是一个 DependencyProperty,在创建 DP 时,您可以选择指定“属性更改”事件。不幸的是,ItemsSource 被锁定在基类中,所以我开始想知道是否有办法将您自己的事件添加到现有的 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...
              });
    }
    

    【讨论】:

    • 安德鲁,感谢您的意见,我会好好阅读这篇文章,看看有什么收获。与此同时,我发现以下内容至少给了我一些东西可以玩。由于我是从 ItemsControl 继承的,因此我似乎可以利用它的 Items 属性,该属性恰好暴露了 CurrentChanged 事件,因此我目前在控件 AddHandler MyBase.Items.CurrentChanged, AddressOf 的构造函数中有以下内容.好像行得通,对不对就是另外一回事了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多