1

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?

Youngjae
  • 24,352
  • 18
  • 113
  • 198

2 Answers2

0

Did you try:

<WrapPanel Name="wrapPanel1" DataContext="{Binding ElementName=listBoxMaster, Path=SelectedItem}">
    <StackPanel>
        <TextBox Text="{Binding Path=DetailList.Name}" />
        <TextBox Text="{Binding Path=DetailList.Number}" />
    </StackPanel>
</WrapPanel>

or

<WrapPanel Name="wrapPanel1">
    <StackPanel>
        <TextBox Text="{Binding ElementName=listBoxMaster, Path=SelectedItem.DetailList.Name}" />
        <TextBox Text="{Binding ElementName=listBoxMaster, Path=SelectedItem.DetailList.Number}" />
    </StackPanel>
</WrapPanel>

These are to ensure whether the DataContext is actually cascading.

Xcalibur37
  • 2,305
  • 1
  • 17
  • 20
  • No, it didn't work. Is it right usage that dot operator comes with DetailList(ObservableCollection of DetailItemClass)? I tried your suggestion and DetailList/Name also but both expressions didn't work. – Youngjae Dec 18 '11 at 15:59
  • Yes, the dot works fine since SelectedItem is already in the context of the item it represents. So, the data type is actually the same as the list item. – Xcalibur37 Dec 18 '11 at 16:21
  • To better trouble-shoot this, can you possibly post your project somewhere so we can see the whole picture? – Xcalibur37 Dec 18 '11 at 16:22
  • Thanks for your kind help. Let me try with TreeView control first, and then I will post more detail if I cannot make it. – Youngjae Dec 19 '11 at 02:03
0

You shouldn't use multiple listboxes because there will be many issues related to the multiple selection. For example, you can select the first listbox, but the item from the second.

multiple list boxes fail

Replace the outer list box by the ItemsControl class so that it doesn't receive the selection and isn't focusable.

Also add the single property to the root model which contains the single selected item for all lists. I've reproduced your hierarchy by using very simple models and in this example this property is called SelectedDetailItem:

public class MasterListViewModel : INotifyPropertyChanged
{
    public ObservableCollection<DetailListViewModel> MasterList { get; set; }

    private ItemViewModel _selectedDetailItem;

    public ItemViewModel SelectedDetailItem
    {
        get { return _selectedDetailItem; }
        set
        {
            _selectedDetailItem = value;
            OnPropertyChanged("SelectedDetailItem");
        }
    }
}

public class DetailListViewModel
{
    public ObservableCollection<ItemViewModel> DetailList { get; set; }
}

public class ItemViewModel
{
    public string Title { get; set; }
}

And bind this property to both controls:

<ItemsControl x:Name="listBoxMaster" ItemsSource="{Binding Path=MasterList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ListBox x:Name="listBoxDetail" ItemsSource="{Binding Path=DetailList}" DisplayMemberPath="Title" 
                        SelectedItem="{Binding DataContext.SelectedDetailItem, Mode=TwoWay, ElementName=listBoxMaster}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

<WrapPanel Name="wrapPanel1" DataContext="{Binding SelectedDetailItem}" Grid.Column="1">
    <TextBox Text="{Binding Path=Title}" />
</WrapPanel>
vortexwolf
  • 13,967
  • 2
  • 54
  • 72
  • Thanks for your answer. I found that ItemsControl doesn't have SelectionMode property for multiple selection. Is there any way to make multiple selection of Master list? because I need to make user can select multiple Master item in order to delete or move to somewhere. (or TreeView control as your recommendation could be the best?) – Youngjae Dec 18 '11 at 17:14
  • @Youngjae There is no easy ways to work with multiple selection by using data binding: http://stackoverflow.com/questions/2511708/databinding-a-listbox-with-selectionmode-multiple. So it'll require much of code-behind to implement it correctly. – vortexwolf Dec 18 '11 at 19:52
  • @Youngjae By the way, Windows Explorer doesn't allow to select multiple items on the left panel. – vortexwolf Dec 18 '11 at 19:53