在没有索引的集合上实现INotifyCollectionChanged
在ASP.Net专门工作了几年之后,我刚刚在WPF中弄湿了脚趾。 我目前正在努力解决的问题是我有一个自定义集合类,我需要绑定到列表框。 除了从集合中删除项目之外,一切似乎都在起作用。 当我尝试收到错误: “Collection Remove event must specify item position.”
是这个集合不使用索引,所以我没有看到指定位置的方法,到目前为止谷歌没有向我显示可行的解决方案……
该类被定义为实现ICollection
和INotifyCollectionChanged
。 我的内部项容器是一个Dictionary
,它使用项的名称(字符串)值作为键。 除了这两个接口定义的方法之外,此集合还有一个索引器,允许通过Name访问项目,并覆盖Contains
和Remove
方法,以便也可以使用项目Name调用它们。 这适用于添加和编辑,但在我尝试删除时会抛出上述exception。
以下是相关代码的摘录:
class Foo { public string Name { get; set; } } class FooCollection : ICollection, INotifyCollectionChanged { Dictionary Items; public FooCollection() { Items = new Dictionary(); } #region ICollection Members //***REMOVED FOR BREVITY*** public bool Remove(Foo item) { return this.Remove(item.Name); } public bool Remove(string name) { bool Value = this.Contains(name); if (Value) { NotifyCollectionChangedEventArgs E = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, Items[name]); Value = Items.Remove(name); if (Value) { RaiseCollectionChanged(E); } } return Value; } #endregion #region INotifyCollectionChanged Members public event NotifyCollectionChangedEventHandler CollectionChanged; private void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e) { if (CollectionChanged != null) { CollectionChanged(this, e); } } #endregion }
您的自定义集合似乎是KeyedCollection
的重新发明,它在内部使用字典, 并具有索引。 如果TKey
是int
或int
enum,则int
索引的索引器可以隐藏,但这可以修复 。
至于让KeyedCollection
与WPF一起工作,我找到了这篇文章 ,其中他基本上通过实现INotifyCollectionChanged
并重写SetItem()
, InsertItem()
, ClearItems()
和RemoveItem()
以及添加来生成ObservableKeyedCollection
AddRange()
并将Func
传递给构造函数以从TItem
获取TKey
。
采取一点间接,但你可以用Linq做。 不包括error handling你可以这样做:
var items = dict.Keys.Select((k, i) => new { idx = i, key = k }); var index = items.FirstOrDefault(f => f.key == name).idx;
只要保持一致,您也可以使用值而不是键。
所以我通过将remove事件更改为重置来暂时破解,并开始处理我的代码的其他一些区域。 当我回到这个问题时,我发现/意识到SortedList类将满足我的要求,并允许我正确地实现Collection Changed事件,只需对现有代码进行最少的更改。
对于那些不熟悉这个课程的人(我之前从未使用过),这里有一个基于我迄今为止所做的阅读的快速总结。 在大多数情况下,它看起来像字典,尽管内部结构不同。 此集合维护键和值的排序列表,而不是哈希表。 这意味着将数据输入和输出集合会产生更多的开销,但其内存消耗较低。 这种差异的显着程度似乎取决于您需要存储多少数据以及您为密钥使用的数据类型。
由于我在这个实例中的数据量相对较低,并且我需要将列表框中的项目按其名称值排序,因此在我的情况下使用此类似乎是一个很好的答案。 如果有人争论为什么不应该使用这个课程,请告诉我。
感谢所有人的建议和意见,希望这个主题可以帮助其他人。
我能够使用带有空NewItems
列表的NotifyCollectionChangedAction.Replace
操作来成功为非索引集合引发CollectionChanged
事件。
上述就是C#学习教程:在没有索引的集合上实现INotifyCollectionChanged分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/953331.html