The error message tells you directly that the return value of the Property must be the expected Type of the Property. That indicates to me you need another strategy here ... if ...
I assume that your
intention is:
1. to implement an Observable Collection of instances of DtSource, where you generate notifications of basic actions on the Collection like: 'Add, 'Remove.
2. at the same time, to maintain an updated data structure in which the DtSource instances are 'Grouped using Linq by the Class 'Name property/key.
The code shown here is based on those two assumptions; if either is incorrect, let me know, and I will remove this post.
using System.Collections.Generic;
using System.Collections.Specialized;
public class GroupedObservableCollection<T> : List<T>, INotifyCollectionChanged
{
public GroupedObservableCollection(){}
private int baseCount = 0;
public event NotifyCollectionChangedEventHandler CollectionChanged;
public new void Add(T item)
{
base.Add(item);
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, base.Count));
}
baseCount++;
}
public new void Remove(T item)
{
if (!base.Contains(item)) return;
int ndx = base.IndexOf(item);
Remove(ndx, item);
}
public void Remove(int ndx, T item = default(T))
{
if (ndx > baseCount) return;
base.RemoveAt(ndx);
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, ndx));
}
baseCount--;
}
public new void Clear()
{
if (baseCount == 0) return;
base.Clear();
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
baseCount = 0;
}
public void Move(int ndx1, int ndx2)
{
if (ndx1 >= baseCount || ndx2 >= baseCount) return;
T temp = base[ndx1];
base[ndx1] = base[ndx2];
base[ndx2] = temp;
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, this, ndx1, ndx2));
}
}
public void Replace(int ndx1, T item)
{
if (ndx1 >= baseCount) return;
base[ndx1] = item;
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, base[ndx1]));
}
}
}
I made this class Generic, so I could re-use it with different Types of Objects. An outcome of making it generic is that you can't stick a function in it to return the Collection (List) GroupedBy some specific property (Key) of the Type of T (while you
might be able to do that using Reflection, I'd say that would be
crazy).
So, strategy 2 is to use an instance of this generic class in a way that keeps a GroupedBy collection updated as notifications are generated:
public GroupedObservableCollection<AnyOldClass> test = new GroupedObservableCollection<AnyOldClass>();
public IEnumerable<Igrouping><string,>> CollectionCurrentGroups;
private void TestOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
UpdateGroupCollection(test);
break;
case NotifyCollectionChangedAction.Remove:
UpdateGroupCollection(test);
break;
case NotifyCollectionChangedAction.Move:
break;
case NotifyCollectionChangedAction.Replace:
UpdateGroupCollection(test);
break;
case NotifyCollectionChangedAction.Reset:
CollectionCurrentGroups = null;
break;
}
}
private void UpdateGroupCollection(GroupedObservableCollection<AnyOldClass> collection)
{
CollectionCurrentGroups = collection.GroupBy(nm => nm.Name);
}
test.CollectionChanged += TestOnCollectionChanged;
test.Add(new AnyOldClass("hello"));
test.Remove(test[0]);
test.Clear();
test.Add(new AnyOldClass("goodbye"));
test.Add(new AnyOldClass("hello again"));
test.Add(new AnyOldClass("goodbye"));
test.Add(new AnyOldClass("hello again"));
test.Move(0,1);
test.Replace(1, new AnyOldClass("what"));
test.Clear();
test.Clear();
Here's the simple Class used for testing here:
public class AnyOldClass
{
public string Name { set; get; }
public AnyOldClass(string name)
{
Name = name;
}
}
Caution: as with all code examples you might see here, or on StackOverFlow, etc., it is your responsibility to make sure they work in the context you use them in. Code like this should be regarded as an example for educational purposes only, and used in "production" code only after extensive, careful, testing !