如何使ObservableCollection中的项唯一
本文关键字:唯一 何使 ObservableCollection | 更新日期: 2023-09-27 18:08:29
我正在用以下内容填充一个可观察集合:
var customers = new ObservableCollection<Customer>();
foreach (
var customer in
collListItem.Select(
item =>
new Customer
{
Persona = item["Persona"].ToString(),
CustomerName = item["Title"].ToString()
}))
{
customers.Add(customer);
}
在我用这个集合中的元素填充WPF数据网格之前,我想让它成为一个唯一的人物角色和客户列表(没有重复的行)。
我试着使用以下命令:
customers = customers.Distinct();
但是我收到了错误:
不能转换源类型'System.Collections.Generic.IEnumerable到目标类型"System.Collections.ObjectModel.ObservableCollection
是否有一个等价的ObservableCollection
,我可以使用?
因为Distinct
返回的是IEnumerable<T>
,而不是ObservableCollection
。
如果你想区分ObservableCollection
,你应该重新创建它,像这样:
customers = new ObservableCollection<Customer>(customers.Distinct());
或者,作为变体,您可以修改查询并立即区分:
foreach (
var customer in
collListItem.Select(
item =>
new Customer
{
Persona = item["Persona"].ToString(),
CustomerName = item["Title"].ToString()
}).Distinct())
{
customers.Add(customer);
}
这是一个老问题,但我只是面临同样的问题,我想我找到了一种替代方法来做OP正在尝试的事情。首先,我认为我们面临的是XY问题。OP想要持有一个具有唯一项的ObservableCollections,现在,两个答案都在某种程度上解决了问题,但我认为这种方式不是最好的。
这应该是我们正在使用的数据结构的责任。如果这个数据结构不存在,那就让我们创建它吧!
需求非常明确:要有一个具有唯一项的ObservableCollection。我发现的方法是从ObservableCollection继承,并提供自定义逻辑来实现:
public class ObservableUniqueCollection <T> : ObservableCollection<T>
{
private readonly HashSet<T> _hashSet;
public ObservableUniqueCollection() : this(EqualityComparer<T>.Default) { }
public ObservableUniqueCollection(IEqualityComparer<T> equalityComparer) => _hashSet = new HashSet<T>(equalityComparer);
public void AddRange(IEnumerable<T> items)
{
foreach (var item in items)
{
InsertItem(Count, item);
}
}
protected override void InsertItem(int index, T item)
{
if (_hashSet.Add(item))
{
base.InsertItem(index, item);
}
}
protected override void ClearItems()
{
base.ClearItems();
_hashSet.Clear();
}
protected override void RemoveItem(int index)
{
var item = this [index];
_hashSet.Remove(item);
base.RemoveItem(index);
}
protected override void SetItem(int index, T item)
{
if (_hashSet.Add(item))
{
var oldItem = this[index];
_hashSet.Remove(oldItem);
base.SetItem(index, item);
}
}
}
所以现在你不必担心在你的集合中有重复的项目(只要你的类型实现了IEquatable或者你提供了一个IEqualityComparer)
无需在Customer
上实现自己的比较就可以工作
foreach (var customer in collListItem.Select(
item =>
new {
Persona = item["Persona"].ToString(),
CustomerName = item["Title"].ToString()
}).Distinct()
.Select(r => new Customer { Persona = r.Persona,
CustomerName = r.CustomerName }))
{
customers.Add(customer);
}