Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 嵌套列表框如何设置父列表框在子列表框上选择编辑项鼠标双击_C#_Wpf_Mvvm_Listbox_Mvvm Light - Fatal编程技术网

C# 嵌套列表框如何设置父列表框在子列表框上选择编辑项鼠标双击

C# 嵌套列表框如何设置父列表框在子列表框上选择编辑项鼠标双击,c#,wpf,mvvm,listbox,mvvm-light,C#,Wpf,Mvvm,Listbox,Mvvm Light,我有一个嵌套的列表框。在内部列表框鼠标双击事件中,我需要根据一些逻辑打开一个新窗口,为此,我需要内部列表框SelectedItem及其相应的外部列表框SelectedItem。如何以MVVM的方式实现这一点 <ListBox ItemsSource="{Binding OuterCollection}"> <ListBox.ItemTemplate> <DataTemplate>

我有一个嵌套的
列表框
。在内部列表框鼠标双击事件中,我需要根据一些逻辑打开一个新窗口,为此,我需要内部列表框SelectedItem及其相应的外部
列表框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>

要记住的事情:


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

2) 我正在使用MVVMLight工具包,作为一个临时解决方案,我只是将内部ListBox鼠标双击事件参数传递给视图模型,并遍历树以查找外部ListBox项。
我知道这是违反MVVM规则的,所以我如何才能以正确的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>
您可以使用
列表框
上的属性
SelectedItem
属性

这是我用来解决你问题的代码。虽然我使用了Cinch,但它不应该是light框架的问题

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>
最后但并非最不重要的是我的模型

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();
        }
    }
}
使用System.Collections.ObjectModel;
使用System.Windows.Input;
使用安全带;
命名空间TestWPF
{
公共类ViewModel:ViewModelBase
{
公共ICommand TestCommand{get;private set;}
public observeCollection OuterCollection{get;private set;}
公共字符串OuterListBoxSelectedItem{get;set;}
public observeCollection InnerCollection{get;private set;}
公共字符串InnerListBoxSelectedItem{get;set;}
公共视图模型()
{
OuterCollection=新的可观测集合{“外部1”、“外部2”、“外部3”、“外部4”};
InnerCollection=新的可观测集合{“内部1”、“内部2”、“内部3”};
TestCommand=新的SimpleCommand(测试);
NotifyPropertyChanged(“OuterCollection”);
NotifyPropertyChanged(“InnerCollection”);
NotifyPropertyChanged(“TestCommand”);
}
公共无效测试(对象o)
{
var a=InnerListBoxSelectedItem;
var b=外部列表框SelectedItem;
“”.ToString();
}
}
}
我还需要添加一个对
System.Windows.Interactivity


我希望这有帮助

“内部收藏和外部收藏项目之间没有关系。”这并不意味着它们是不同的收藏。这是另一个收藏中的一个收藏。i、 e.每个OuterCollection记录由一个InnerCollection列表组成。还有,你是如何在内部列表框鼠标双击事件中选择外部列表框项目的?不必担心我使用的不同集合。那只是为了举例说明。好的,关于
CommandParameter
中的第二个疑问,您会注意到我已使用
相对资源将其绑定到第一个
列表框
。因此,它所做的是查找可视化树,并尝试查找满足
AncestorLevel
标准的
ListBox
。如果它找到一个,那么它就绑定到它。顺便问一下,你执行我的代码了吗?它是否按要求工作?假设我选择了外部列表框中的第一个项目,并双击位于外部列表框中第三个项目内的内部列表框项目。那么您的ancestotype将只返回第一个listbox项。不是第三个…是的,我知道这个问题。如果您案例中的内部收藏是独一无二的,那么您就很幸运了。您可以做的是,双击内部集合后,只需使用外部
列表框
SelectedItem
作为键添加一个验证,以查看内部选定项是否确实是外部选定项的一部分。