I'm populating an observable collection with the following:
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);
}
Before I populate a WPF datagrid with the elements from this collection I'd like to make it a unique list of personas and customers (no duplicate rows).
I tried to use the following for this:
customers = customers.Distinct();
However I received the error:
Cannot convert source type 'System.Collections.Generic.IEnumerable to target type 'System.Collections.ObjectModel.ObservableCollection
Is there an equivalent for an ObservableCollection
that I can use?
An ObservableCollection is a dynamic collection of objects of a given type. Objects can be added, removed or be updated with an automatic notification of actions. When an object is added to or removed from an observable collection, the UI is automatically updated.
Represents a dynamic data collection that provides notifications when items get added or removed, or when the whole list is refreshed.
Because Distinct
returns an IEnumerable<T>
, which is not an ObservableCollection
.
If you want to distinct ObservableCollection
you should create it again like this:
customers = new ObservableCollection<Customer>(customers.Distinct());
Or, as variant, you can modify your query and distinct at once:
foreach (
var customer in
collListItem.Select(
item =>
new Customer
{
Persona = item["Persona"].ToString(),
CustomerName = item["Title"].ToString()
}).Distinct())
{
customers.Add(customer);
}
Well this is an old question but I am just facing the same issue and I think I found an alternative way to do what the OP is attempting. First of all I think we are facing here an XY problem. The OP wants to hold an ObservableCollections with unique items, now, both answers existing answers solve the problem in a way, but I think this way is not the best.
This should be the responsibility of the data structure we are using. If that data structure does not exist let's create it!
The requirement is quite clear: To have an ObservableCollection with unique items. The way I foudn was to inherit from ObservableCollection and provide custom logic to do this:
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);
}
}
}
So now you don't have to worry about having repeated items in your collection (as long as your type implements IEquatable or you provide an IEqualityComparer)
This will work without having to implement your own compare on 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With