嵌套列表框如何在子列表框鼠标双击上设置父列表框selectedItem

Den*_*nis 7 c# wpf listbox mvvm mvvm-light

我有一个嵌套ListBox.在内部列表框鼠标双击事件,我需要基于一些逻辑打开一个新窗口,为此我需要内部ListBox SelectedItem及其相应的外部ListBox SelectedItem.如何以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>
Run Code Online (Sandbox Code Playgroud)

要记住的事情:

1)内部集合和外部集合项之间没有关系.

2)我正在使用MVVMLight Toolkit,作为临时解决方案,我只是将内部ListBox Mouse Double Click事件参数传递给View模型,并遍历树以查找Outer ListBox项.我知道这是违反MVVM规则的,所以我怎么能以适当的MVVM方式做到这一点?

San*_*esh 1

得到了一种可能的解决方案

您可以SelectedItem在两个ListBox.

这是我用来解决您的问题的代码。虽然我用的是Cinch,但轻框架应该不是问题

主窗口.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>
Run Code Online (Sandbox Code Playgroud)

MainWindow.xaml.cs

using System.Windows;

namespace TestWPF
{

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的一点是我的模型

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我还需要再添加一个参考System.Windows.Interactivity

我希望这有帮助