I have a TreeView implemented in WPF that is bound to some XML data via the XElement class. When loading the XML file the first time the binding works fine. All the data populates the tree as expected. The problem occurs when I add and remove elements because nothing happens in the TreeView. Now I’ve done this before’ and I believe I remember not having to do any extra work for this work correctly. At least for the simple case of adding and removing items from the tree. I remember being surprised that this worked without any extra coding effort. I don’t have access to that code anymore so I can’t just look at what I already did. So I’m kind of stumped as to why I can’t get this to work now.
My WPF code is as follows.
<Window.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Elements}" x:Key="ViewEditTreeTemplate">
<StackPanel Orientation="Horizontal" Margin="2">
<Label x:Name="ElementHeaderLabel" Padding="1" VerticalContentAlignment="Center" FontSize="16" Content="{Binding Path=DisplayName}" />
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView Name="DataTree" ItemTemplate ="{Binding Source={StaticResource ViewEditTreeTemplate}}" Margin="0,0,0,53" />
</Grid>
I’m attaching my XML document in the code behind as follows. Keep in mind that this appears to be working since the tree auto populates with the information from the XML data just fine.
XElement NewElement = new XElement(XElement.Load(FilePath));
List<XElement> TempList = new List<XElement>();
TempList.Add(NewElement);
DataTree.ItemsSource = TempList;
In the code behind when I go to add or remove elements I do as follows:
// When removing an element
Element.Remove(); //Element is of type XElement
// When adding an element
ParentElement.Add(NewElement); //ParentElement and NewElement are of type XElement
I have this strong feeling that when I did this before, I actually didn’t have to do anything special. The .Remove() and .Add() routines somehow notified the bindings that the items in .Elements() have changed and the screen updated automatically. Whatever the case, its not working this time around. Does anyone know why?
Ok, I have a solution to my own problem. I’m not sure why I thought this would originally work without having to do anything special, but that seems to not be the case.
To clarify the problem a little more, I was not using the the XElement object as is, I had it wrapped by another class so I could add a few more features to it. This was good though because it turns out I needed the INotifyPropertyChanged interface and to override a few methods in order to get the behavior I wanted. My actual class header looks like this.
Since my TreeView was binding on the XElement.Elements() routine, it was not receiving notifications when I added or removed elements. The reason why is because XElement.Elements() is NOT a dependency property. Its a routine. I knew this ahead of time but for some reason I was stubborn and still thought it was going to work. So what I needed to add was the INotifyPropertyChanged interface, and then invoke the NotifyPropertyChanged() routine whenever operations occurred that would cause the data from XElement.Elements() to be changed. Namely, they XElement.Add() and XElement.Remove() routine. There are several more but I’ll just talk about these two.
These routines are not overridable, but they can be hidden using the “new” key word. Here is the new implementation for those routines.
As you can see, even though .Elements() is not a property the NotifyPropertyChanged(“Elements”) method works just fine at notifying my binding ‘ItemsSource=”{Binding Path=Elements}”‘. So now when I update in the code behind using .Add() or .Remove() my tree auto updates.