Nested Listbox how to set the parent list selectedItem in the child list of the mouse double-click

I have a Nested ListBox . On the internal mouse drawer, double-click the event, I need to open a new window based on some logic, and for this I need the internal ListBox SelectedItem and its corresponding Outer ListBox SelectedItem . How can this be obtained using MVVM?

 <ListBox ItemsSource="{Binding OuterCollection}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding OuterProperty1}" /> <ListBox Width="200" ItemsSource="{Binding InnerCollection}"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding InnerProperty1}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> 

What you need to remember:

1) There is no connection between the internal collection and the external element of the collection.

2) I use the MVVMLight Toolkit and as a workaround, I simply pass the internal argument of the ClickBox Mouse Double Click event to the View model and traverse the tree to find the Outer ListBox. I know this is against the rules of MVVM, so how can I do this with the correct MVVM?

+7
c # wpf mvvm listbox mvvm-light
source share
1 answer

One possible solution received

The property of the SelectedItem property can be used as for a ListBox .

Here is the code I used to solve your problem. Although I used Cinch, this is not a light-frame problem

MainWindow.xaml

 <Window x:Class="TestWPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" Title="MainWindow" Height="350" Width="525"> <ListBox ItemsSource="{Binding OuterCollection}" SelectedItem="{Binding OuterListBoxSelectedItem}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding}" /> <ListBox Width="150" DataContext="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" ItemsSource="{Binding InnerCollection}" SelectedItem="{Binding InnerListBoxSelectedItem}"> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}, AncestorLevel=2},Path=SelectedItem}"/> </i:EventTrigger> </i:Interaction.Triggers> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window> 

MainWindow.xaml.cs

 using System.Windows; namespace TestWPF { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new ViewModel(); } } } 

Last but not least my model

 using System.Collections.ObjectModel; using System.Windows.Input; using Cinch; namespace TestWPF { public class ViewModel : ViewModelBase { public ICommand TestCommand { get; private set; } public ObservableCollection<string> OuterCollection { get; private set; } public string OuterListBoxSelectedItem { get; set; } public ObservableCollection<string> InnerCollection { get; private set; } public string InnerListBoxSelectedItem { get; set; } public ViewModel() { OuterCollection = new ObservableCollection<string> { "Outer 1", "Outer 2", "Outer 3", "Outer 4" }; InnerCollection = new ObservableCollection<string> { "Inner 1", "Inner 2", "Inner 3" }; TestCommand = new SimpleCommand<object, object>(Test); NotifyPropertyChanged("OuterCollection"); NotifyPropertyChanged("InnerCollection"); NotifyPropertyChanged("TestCommand"); } public void Test(object o) { var a = InnerListBoxSelectedItem; var b = OuterListBoxSelectedItem; "".ToString(); } } } 

I also needed to add another link to System.Windows.Interactivity

I hope this helps

+1
source share

All Articles