我有Dictionary<string, MyClass>
,我需要将其值公开给UI(WPF应用程序)。所以我尝试创建一个ObservableCollection:
this.MyList = new ObservableCollection(this.MyDictionary.Values)
根据MSDN:返回的Dictionary<TKey, TValue>.ValueCollection
不是静态副本;相反,Dictionary<TKey, TValue>.ValueCollection
会引用原始Dictionary<TKey, TValue>
中的值。因此,对Dictionary<TKey, TValue>
的更改将继续反映在Dictionary<TKey, TValue>.ValueCollection
。
但是当我在字典中添加新项目时,更改不会反映在我的可观察集合中。
我害怕我不能做我想做的事,但可能有一个我不知道的伎俩。
解决方案
虽然接受的答案回答了这个问题,也就是说,我无法使用原生API做我想做的事情,但这就是我如何构建自己的对象:
private class LivingHashedCollection<T>
{
private HashSet<T> _set;
private ObservableCollection<T> _list;
public ReadOnlyObservableCollection<T> Values { get; private set; }
public LivingHashedCollection()
{
_set = new HashSet<T>();
_list = new ObservableCollection<T>();
this.Values = new ReadOnlyObservableCollection<T>(_list);
}
public void AddValues(ICollection<T> values)
{
foreach (var val in values)
{
if (!_set.Contains(val))
{
_set.Add(val);
_list.Add(val);
}
}
}
}
我最终为了通用目的选择了HashSet而不是Dictionary。显然,这个实现可以改进(例如可以实现IEnumerable,ICollection),但基础在这里!
答案 0 :(得分:2)
ObservableCollection
将始终复制您传递给构造函数的列表。这样做有几个原因,但主要原因(我认为)是ObservableCollection
主要目的是跟踪对其内容的更改,但它无法跟踪外部集合的更改传递给它的构造函数,因此对它的更改将被忽视(不会引发CollectionChanged
事件)。