WPF - 如何实现ObservableCollection 用一把钥匙(比如一本字典)?

问题描述 投票:8回答:4

我已经使用带有WPF的ObservableCollection进行绑定,这很有效。我现在真正想要的是像一个字典,它有一个我可以使用的键,所以有效地像“ObservableCollection”。

你能建议可以用来提供这样一个ObservableCollection的代码吗?我的目标是拥有一个类似于Dictionary的结构,我可以从WPF绑定它。

谢谢

c# .net wpf observablecollection
4个回答
5
投票

Someone already made it。我还没有尝试过,但没有什么可失去的。


1
投票

创建一个实现IDictionary,INotifyCollectionChanged和INotifyPropertyChanged接口的类。该类将具有一个Dictionary实例,它将用于实现IDictionary(其中一个Add方法在下面作为示例编写)。 INotifyCollectionChanged和INotifyProperyChanged都需要存在事件,这些事件应该在包装函数的适当位置触发(再次参考下面的Add方法获取示例)

class ObservableDictionary<TKey, TValue> : IDictionary, INotifyCollectionChanged, INotifyPropertyChanged
{
    private Dictionary<TKey, TValue> mDictionary;
    // Methods & Properties for IDictionary implementation would defer to mDictionary:
    public void Add(TKey key, TValue value){
        mDictionary.Add(key, value);
        OnCollectionChanged(NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, value)
        return;
    }
    // Implementation of INotifyCollectionChanged:
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    protected void OnCollectionChanged(NotifyCollectionChangedEventArgs args){
        // event fire implementation
    }
    // Implementation of INotifyProperyChanged:
    public event ProperyChangedEventHandler ProperyChanged;
    protected void OnPropertyChanged(PropertyChangedEventArgs args){
        // event fire implementation
    }
}

编辑:

请注意,直接或间接实现IDictionary接口需要实现三个额外的接口:

ICollection<KeyValuePair<TKey,TValue>>
IEnumerable<KeyValuePair<TKey,TValue>>
IEnumerable.

根据您的需要,您可能不必实现整个IDictionary接口,如果您只是调用几个方法,那么只需实现这些方法,IDictionary接口就变得很奢侈。您必须实现INotifyCollectionChanged和INotifyPropertyChanged接口才能使绑定正常工作.Blockquote


1
投票
public class ObservableDictonary<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);
        if (!TryGetValue(key, out _)) return;
        var index = Keys.Count;
        OnPropertyChanged(nameof(Count));
        OnPropertyChanged(nameof(Values));
        OnCollectionChanged(NotifyCollectionChangedAction.Add, value, index);
    }

    public new void Remove(TKey key)
    {
        if (!TryGetValue(key, out var value)) return;
        var index = IndexOf(Keys, key);
        OnPropertyChanged(nameof(Count));
        OnPropertyChanged(nameof(Values));
        OnCollectionChanged(NotifyCollectionChangedAction.Remove, value, index);
        base.Remove(key);
    }

    public new void Clear()
    {

    }

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

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

    private void OnPropertyChanged(string propertyName)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    private void OnCollectionChanged(NotifyCollectionChangedAction action, object item)
    {
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item));
    }

    private void OnCollectionChanged(NotifyCollectionChangedAction action, object item, int index)
    {
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(action, item, index));
    }

    private int IndexOf(KeyCollection keys, TKey key)
    {
        var index = 0;
        foreach (var k in keys)
        {
            if (Equals(k, key))
                return index;
            index++;
        }
        return -1;
    }
}

我重写添加,删除和清除。你必须明白,如果你使用扩展方法或简单方法,它采取Dictionary参数,你不会看到改变,因为在这种情况下,Add或Remove方法将使用Dictionary(而不是ObservableDictonary)。因此,您必须指导ObservableDictonary的方法(添加或删除)


0
投票

怎么样的:

ObservableCollection<Tuple<string, object>>()

其中字符串和对象以及样本类型当然

© www.soinside.com 2019 - 2024. All rights reserved.