I'm having a problem with Nested controls with ItemSources when the outermost control's DataContext changes. The inner controls appear to update to reflect the new DataContext, but its like there is some "Ghost" binding that is still tied to the old DataContext.
I suspect that having Nested controls that have DataTemplates prevents in inner control's bindings from updating when the outer control's DataContext is changed. I've read somewhere that only the binding only responds to PropertyChanged events that are raised from object that are expictly defined in the PATH.
My question is: How do you fully define a binding PATH from within nexted controls with ItemsSources? In my case:
<DataGrid name="OuterGrid" ItemsSource={Binding SelectedSchool.Classes}">
<ItemsControl ItemsSource={Binding Students}">
<ComboBox SelectedItem={Binding Grade}" />
</ItemsControl>
</DataGrid>
I would like fully specify the inner ComboBox's SeletedItem PATH, something like the following, but I need it to be bound to the specific item within the collection (not just the one at index 0).
<ComboBox SelectedItem="{Binding ElementName=OuterGrid,
Path=DataContext.SelectedSchool.Classes[0].Students[0].Grade}" />
I have a more detailed example of my problem below, I'm not able to post actual code or describe the ACTUAL objects that I am working with (security reasons), so I've tried to describe it in the easiest way to understand.
MODEL:
I have a fairly complicated Biz object that has a collection of other objects. Items in the collection also have collections within them.
- Schools have many classes
- Classes have many students
- Each student has a letter grade for the class.
- The list of possible letter grades is diffrent for each school.
Every class (including my ViewModel) implements INotifyPropertyChanged, and each collection is an ObservableCollection.
VIEWMODEL:
My ViewModel has the following propeties:
- An ObservableCollection of Schools... (AllSchools).
- A SelectedSchool
- A boolean (IsEditing)
- An ObservableCollection of possible Grades (which gets updated when IsEditing changes, and is based on the Selected School).
The important thing to note here is that diffrent schools may have diffrent possible Grades (i.e one may have A+, A, and A- while another only has A).
XAML:
I have a Datagrid bound to my ViewModel's AllSchools collection and SelectedSchool property of my ViewModel. When the user double-clicks a row, an event-handler opens an "edit panel" for the selected school by changing the ViewModel's IsEditing property (the edit panel's Visibily is bound to IsEditing property). Inside the edit panel I have a Datagrid (Bound to the collection of Classes for the selected School), Inside the Datagrid I have a TemplatedColumn with an ItemsControl (Bound to the collection of the current Class's Students). For each student there is a ComboBox for the student's grade in the class. The ItemsSource for the ComboBox is the ViewModel's PossibleGrades collection.
THE PROBLEM:
The problem is that when the SelectedSchool changes, any student in the previously SelectedSchool with a letter grade that does not exist for the newly-SelectedSchool, suddenly has their letter grade set to null (because the ItemsSource for the ComboBox no longer has the grade).
Visually, everything seems to work fine. The edit panel correctly shows the properties for the selected school, and gets updated when the SelectedSchool property changes. But if I re-open the edit panel for the the fist school, none of the comboboxes have values selected anymore because they were all set to null when I selected the second School.
Its like the old ComboBoxes still have their Bindings hooked-up, even though they no longer show up on the screen. But if only affects the previously SelectedSchool (not the one before it).