One line summary of my situation: when I select a detail item, the master is still unselected, so I get wrong detail item.
Assume that two ViewModel MasterList and DetailList are ObservableCollection, and try to make Explorer-like GUI. Left panel has master-detail listboxes, and right panel will show one of the selected detail item. there is no need to show master information in right panel.
On my left panel, ListBox controls are coded as below.
<ListBox x:Name="listBoxMaster" ItemsSource="{Binding Path=MasterList}" SelectionMode="Extended"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<ListBox x:Name="listBoxDetail" ItemsSource="{Binding Path=DetailList}" IsSynchronizedWithCurrentItem="True" />
</DataTemplate>
</ListBox.ItemTemplate>
Note that I set IsSynchronizedWithCurrentItem="True" to both ListBox controls.
and in right panel, the selected detail item information will be displayed with the Binding as below. Let's simplify the detail item class called DetailItemClass has Name and Number properties.
Trial 1
<WrapPanel Name="wrapPanel1" DataContext="{Binding ElementName=listBoxMaster, Path=SelectedItem}">
<StackPanel DataContext="{Binding Path="DetailList/">
<TextBox Text="{Binding Path=Name}" />
<TextBox Text="{Binding Path=Number}" />
</StackPanel>
</WrapPanel>
The weired GUI problem is happend. if we have.
- Master1 has detail 1,2,3.
- Master2 has detail 4,5,6.
When I select M1-D2, it works. after that, when I select detail M2-D4, it works. BUT, after that, when I select M1-D2 again, it does NOT works! the pre-selected item may not update its master to be selected. Moreover, sometimes M2-D5 selection gives M1-D2 in right panel. weired.
Trial 2
<WrapPanel Name="wrapPanel1" DataContext="{Binding Path=MasterList/DetailList/}">
<StackPanel>
<TextBox Text="{Binding Path=Name}" />
<TextBox Text="{Binding Path=Number}" />
</StackPanel>
</WrapPanel>
Just not works. AlThough I set IsSynchronizedWithCurrentItem to true, but failed. I don't know why.
Trial 3
I just get rid of DataContext XAML bindings and use event trigger at code-behind as below.
private void listBoxMaster_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 1)
{
if (e.AddedItems[0] is DetailItemClass)
{
var element = (DetailItemClass)e.AddedItems[0];
wrapPanel1.DataContext = element;
}
}
}
It works very well, but it does not use XAML Binding.
Could you teach me proper binding expression?