【问题标题】:WPF: Does a ListBox throw an event when the content of the ItemsSource changes?WPF:当 ItemsSource 的内容发生更改时,ListBox 是否会引发事件?
【发布时间】:2019-10-12 09:32:46
【问题描述】:

我有一个ListBox,它的ItemSource 绑定到一个ObservableCollection

我在此ListBox 中激活了附加行为。此附加行为挂钩到 ItemsSource 属性的更改事件。当这个事件被触发时,它会检查新的ItemsSource 值是否为INotifyCollectionChanged 类型,如果是,它也钩入它的CollectionChanged 事件。

但是当这个事件被触发时,我无法再访问ListBox,只能访问ObservableCollection

ListBox 中是否有一个事件在其ItemsSource 的内容发生更改时触发?这样我就可以访问ListBox

【问题讨论】:

    标签: wpf


    【解决方案1】:

    所以,没有这样的事件,但是,我们可以使用Items 属性来解决这个问题。

    首先,我们需要订阅Items属性的CollectionChanged事件:

    ((INotifyCollectionChanged)listBox.Items).CollectionChanged += Handler

    现在我们可以访问ItemCollection

    void Handler(object sender, NotifyCollectionChangedEventArgs e) 
    { 
       var items = (ItemCollection)sender; 
    }
    

    正如this 问题的答案所暗示的,ItemCollection 的父 ItemsControl 没有公共访问器。但是,this 的参考源向我们展示了该框架以this 字段和this 便捷属性的形式。现在我们只需要参考它。 您可以通过using delegates 加快速度(显然您会将它们缓存为静态字段,下面的代码用于演示目的)。

    var getterMethodInfo = typeof(ItemCollection).GetProperty("ModelParent", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true);
    var getterDelegate = (Func<ItemCollection, DependencyObject>)Delegate.CreateDelegate(typeof(Func<ItemCollection, DependencyObject>), getterMethodInfo);
    
    var listBox = (ListBox)getterDelegate(items);
    

    【讨论】:

    • 谢谢。对于尝试这样做的每个人,请务必连接到 ListBoxs ItemsCollectionCollectionChanged 事件,而不是绑定到 ObservableCollectionCollectionChanged 事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 2014-11-26
    • 1970-01-01
    相关资源
    最近更新 更多