In my WPF app, I have an ItemsControl whose items values are dependant upon the previous item displayed.
The ViewModel is an audio file split into parts of variable length, and i need to display it in such manner, with a DateTime displayed on the right, and that's what i need to calculate (I only know each part's length, i need to calculate the actual time it starts and ends, and the position on the ItemsControl).
--
----
------------
--
--------------------
My first approach was to use an ObservableCollection<MyviewModel>
but soon enough some horrors occured :
5-way multibinding in which's IMultiValueConverter
I'd calculate the value to return and set a property of the DataContext to that value, because I only knew the previous element at runtime.
The previous element was sent using a binding on Relativesource.PreviousData
.
Now my problem is that after setting a value from the Converter (which is obviously a bad thing), and actually getting it to work, a regular Collection doesn't have a notion of order in its elements, so when further down the road when i want to add an audio part in the middle of the rest, the display is messed up.
Furthermore, when I'll implement more business logic, I may need to access the audio parts's start and end that are calculated in this converter, and what if it's not displayed yet...?
So that approach was wrong on several levels.
That's where i started googling and found out about LinkedList
. Now I'm trying to make a class that is basically an Observable LinkedList (I don't need it to be generic):
public class ObservableSegmentLinkedList : LinkedList<MyViewModel>, INotifyCollectionChanged
{
//Overrides ???
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
public void OnNotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(this, e);
}
}
#endregion
}
And the heart of the problem is that i can't override the methods that modify the collection (Addfirst, AddLast etc), so i can't call OnNotifyCollectionChanged properly...
So I'm thinking i could make overloads for each of these methods, but that sounds quite nasty...
In short: I need some kind of collection in which each item knows details of the previous one in order to calculate one of its own properties.
Any clues? is this even a good solution?
Thanks!
Appendix, the ViewModel looks like:
public class MyViewModel : INotifyPropertyChanged
{
private DateTime m_SegmentLength;
public DateTime SegmentLength
{
get { return m_SegmentLength; }
set
{
m_SegmentLength = value;
NotifyPropertyChanged("SegmentLength");
}
}
private DateTime m_SegmentAdvert;
public DateTime SegmentAdvert
{
get { return m_SegmentAdvert; }
set
{
m_SegmentAdvert = value;
NotifyPropertyChanged("SegmentAdvert");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String prop)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
#endregion
}
EDIT: i think i will try to combine Thomas and Will's answers: I'll use composition (i.e I keep an instance of LinkedList in my custom object instead of inheriting from it) and redefine methods that are meant to be used (AddAfter, AddFirst etc) in which i'll just call OnNotifyPropertychanged after calling the actual LinkedList method. It's a bit of work but i guess there won't be any elegant solution to my problem...