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

如何将Dictionary<int,foo>绑定DataGrid并实时同步变更?

解决方案:自定义可观察字典实现实时UI更新

问题根源在于.NET原生Dictionary<TKey, TValue>没有实现INotifyCollectionChanged和INotifyPropertyChanged接口,所以当你对字典执行增、删、替换元素操作时,UI无法自动感知这些变化,只有在集合引用被替换或UI强制刷新时才会更新。

要解决这个问题,你可以自定义一个ObservableDictionary,让它同时具备字典的高效查找能力和集合变更通知功能。以下是具体实现步骤:

1. 实现ObservableDictionary<TKey, TValue>

创建一个继承自Dictionary<TKey, TValue>并实现INotifyCollectionChanged、INotifyPropertyChanged接口的类:

using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;

public class ObservableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
{
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    public event PropertyChangedEventHandler PropertyChanged;

    public new void Add(TKey key, TValue value)
    {
        base.Add(key, value);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value)));
    }

    public new bool Remove(TKey key)
    {
        if (base.TryGetValue(key, out var value))
        {
            var result = base.Remove(key);
            if (result)
            {
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value)));
            }
            return result;
        }
        return false;
    }

    public new void Clear()
    {
        var items = new List<KeyValuePair<TKey, TValue>>(this);
        base.Clear();
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    public new TValue this[TKey key]
    {
        get => base[key];
        set
        {
            if (base.TryGetValue(key, out var oldValue))
            {
                base[key] = value;
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, 
                    new KeyValuePair<TKey, TValue>(key, value), 
                    new KeyValuePair<TKey, TValue>(key, oldValue)));
            }
            else
            {
                base[key] = value;
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value)));
            }
            OnPropertyChanged(nameof(Count));
            OnPropertyChanged(nameof(Keys));
            OnPropertyChanged(nameof(Values));
        }
    }

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        CollectionChanged?.Invoke(this, e);
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 修改你的Database1定义

将原来的Dictionary<int, ToolType>替换为自定义的ObservableDictionary<int, ToolType>:

public ObservableDictionary<int, ToolType> DicToolType { get; set; } = new ObservableDictionary<int, ToolType>();

3. 确保ToolType实现属性变更通知

如果需要实时更新ToolType内部属性(比如Name、Type)的变化,你的ToolType类必须实现INotifyPropertyChanged接口:

public class ToolType : INotifyPropertyChanged
{
    private string _name;
    private string _type;

    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged(nameof(Name));
            }
        }
    }

    public string Type
    {
        get => _type;
        set
        {
            if (_type != value)
            {
                _type = value;
                OnPropertyChanged(nameof(Type));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

4. 保持原有XAML绑定不变

你的DataGrid绑定代码不需要修改,因为ObservableDictionary的枚举结果仍然是KeyValuePair<int, ToolType>,和原生Dictionary一致:

<DataGrid ItemsSource="{Binding DicToolType}"
          AutoGenerateColumns="False"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          CanUserReorderColumns="False"
          IsReadOnly="True">
    <DataGrid.Columns>
        <DataGridTextColumn FontSize="12" Width="60"
                            Header="T" Binding="{Binding Key}"/>
        <DataGridTextColumn FontSize="12" Width="100"
                            Header="Name" Binding="{Binding Value.Name}"/>
        <DataGridTextColumn FontSize="12" Width="90"
                            Header="Type" Binding="{Binding Value.Type}"/>
    </DataGrid.Columns>
</DataGrid>

关键说明

  • 自定义的ObservableDictionary在执行增、删、替换元素操作时,会触发CollectionChanged事件,通知UI更新。
  • 当修改字典中已有键对应的值时,会触发Replace类型的变更通知;新增键值对触发Add,删除触发Remove,清空触发Reset。
  • ToolType实现INotifyPropertyChanged后,其内部属性的修改会自动同步到UI,无需额外处理。

内容的提问来源于stack exchange,提问作者tstx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:24:55