You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF ListBox设置NotifyOnSourceUpdated后SourceUpdated事件未触发

解决WPF ListBox SourceUpdated事件未触发的问题

你遇到的问题其实是对SourceUpdated事件的触发时机理解有偏差哦!咱们先理清楚这个事件到底什么时候会触发,再给你对应的解决方案。

为什么SourceUpdated没触发?

SourceUpdated事件监听的是绑定的源属性本身的引用变化,而不是集合内部项的添加/删除/修改。换句话说:

  • 当你给ListBox.ItemsSource绑定的Collection属性重新赋值(比如Collection = new ObservableCollection<string>())时,源属性的引用变了,这时候SourceUpdated才会触发。
  • 而你现在是向已有的ObservableCollection里添加项,这属于集合内部的变更,ObservableCollection通过INotifyCollectionChanged接口通知UI更新,所以ListBox能显示新项,但这不会触发SourceUpdated事件。

正确的解决方案

根据你的需求,分两种情况处理:

1. 要监听集合内部项的变化(添加/删除/修改)

直接订阅ObservableCollection的CollectionChanged事件就可以了,这才是监听集合内部变更的正确方式:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public ObservableCollection<string> Collection { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        Collection = new ObservableCollection<string>();
        // 订阅集合变更事件
        Collection.CollectionChanged += Collection_CollectionChanged;
        DataContext = this;
    }

    private void Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // 根据变更类型处理逻辑
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                foreach (var newItem in e.NewItems)
                {
                    Console.WriteLine($"新增了项:{newItem}");
                }
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (var oldItem in e.OldItems)
                {
                    Console.WriteLine($"移除了项:{oldItem}");
                }
                break;
            // 还可以处理Move、Replace等类型
        }
    }

    // 如果你需要重新赋值Collection,要实现INotifyPropertyChanged通知UI
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 确实需要触发SourceUpdated事件(监听集合引用变化)

如果你是想监听Collection属性本身被重新赋值的情况,那需要确保:

  • 绑定设置了NotifyOnSourceUpdated="true"(你已经做了)
  • Collection属性实现INotifyPropertyChanged接口,这样重新赋值时UI能收到通知,同时触发SourceUpdated

XAML绑定示例:

<ListBox ItemsSource="{Binding Collection, NotifyOnSourceUpdated=True}"
         SourceUpdated="ListBox_SourceUpdated"/>

然后在代码里重新赋值Collection并触发通知:

private void ResetCollectionBtn_Click(object sender, RoutedEventArgs e)
{
    // 重新赋值集合
    Collection = new ObservableCollection<string> { "新项1", "新项2" };
    // 通知UI属性变化
    OnPropertyChanged(nameof(Collection));
}

// 处理SourceUpdated事件
private void ListBox_SourceUpdated(object sender, DataTransferEventArgs e)
{
    Console.WriteLine("SourceUpdated事件触发了!");
}

这样当你点击按钮重新赋值Collection时,SourceUpdated就会正常触发了。

内容的提问来源于stack exchange,提问作者Rob.Ak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:14:33