IBindingList design flaw and lack of functionality

1) Design flaw

Ok, first focus of this is based on the flaw. IBindingList provides its notifications trough ListChanged event. And this event is really flawed. I will simply focus directly to the place where flaw exists.

public delegate void ListChangedEventHandler (object sender, ListChangedEventArgs e)
ListChangedEventArgs
ListChangedType ListChangedType
int NewIndex
int OldIndex
PropertyDescriptor PropertyDescriptor

Ok, so what is wrong with this picture? Well, ListChangedType.ItemDeleted is completely flawed and is usable only in corner cases. Why?

Event is always sent after item is deleted and item doesn't exist anymore in that list, so if one keeps cache in Hashtable or different hierarchy, he can't know what to remove. Keeping two lists and rely on IBindingList is also impossible. Which makes it only usable in corner cases which are directly involved to avoid the problem this event creates.

Ok, me saying "Event is always sent after item is deleted" isn't correct either. IBindingList is interface not class. Which now really means there is no way of knowing if deletition has already happened. This is simply defaulted to "you need to know handling of every single IBindingList provider if you wanna be sure what just happened"

Funny thing is that they still provide index with this but this one now points to either invalid or incorrect location.

2) Lack of functionality

Typical DataGrid in .Net is linear. Msking TreeView as dumb as this would be one of the easiest things on this world. But considering great work developers put into Gtk TreeView I felt kinda sad not to use that power. Gtk TreeView provides hierarchy and as such I also wanted to be implemented. By using complete raw power of TreeView.

Now... as soon as you start talking hierarchy... how can you provide hierarchical description with int? IBindingList only has
int NewIndex and int OldIndex. Which puts everything into question.
1) Searching manually for index?
2) Provide something which better suits this functionality

This is why IListEvents always provides int[] as index instead of int.

As I said in the start, providing linear only capability would be easiest, but I really wanted to go step forward and be able to do this for example.

public class MyList : ObservableArrayList
{
private string name = "unnamed";
public string Name {
get { return (name); }
set {
if (name == value)
return;
name = value;
OnPropertyChanged ("Name");
}
}

public MyList (string aName)
{
name = aName;
}
}

public class MyObject : BaseNotifyPropertyChanged
{
private string name = "unnamed";
public string Name {
get { return (name); }
set {
if (name == value)
return;
name = value;
OnPropertyChanged ("Name");
}
}

private string lastname = "unnamed";
public string LastName {
get { return (lastname); }
set {
if (lastname == value)
return;
lastname = value;
OnPropertyChanged ("LastName");
}
}

public MyObject (string aName, string aLastName)
{
name = aName;
}
}

....

And then do something like this:

MyList list = new MyList ("base");
list.Add (new MyList ("List A"));
list.Add (new MyList ("List B"));
(list[0] as MyList).Add (new MyObject ("Object with name A", "A"));
(list[1] as MyList).Add (new MyList ("List BA"));
((list[1] as MyList)[0] as MyList).Add (new MyObject ("Object with name B", "B"));

Assign this to TreeView with mapping

myTreeView.ItemsDataSource = list;
myTreeView.ColumnMappings = "{MyNamespace.MyObject} Name[Items name]<<; LastName[Items last name]";

which produces this final TreeView result:

Items name
Items last name
List A

Object with name A
A
List B

List BA

Object with name B
B

Except there is one really nice sugar. No mater where in code you add, change, delete items TreeView effect is instant as long as ItemsDataSource is specified. Items are always hierarchically in sync with original list. Data binding even avoids properties which do not exist in that specific class and shows only existing.