2013-11-26 35 views
7

我有一个嵌套的ListBox。内部列表框鼠标双击事件,我需要打开一个新的窗口基于一些逻辑,为此我需要内部ListBox SelectedItem及其相应的外部ListBox SelectedItem。如何以MVVM的方式获得这个?嵌套列表框如何设置父列表框selectedItem对子列表框中的鼠标双击

<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鼠标双击事件参数传递给View模型,并遍历树来查找外部列表框项目。 我知道这是违反MVVM规则,所以我如何以适当的MVVM方式来做到这一点?

回答

1

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

您可以使用属性SelectedItem财产上的ListBox两者。

这是我用来解决你的问题的代码。虽然我用腰带它不应该是轻的框架问题

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(); 
     } 
    } 
} 

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

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.Windows.Interactivity

我希望这有助于

+0

“内部收集和外部收集项目之间没有关系。”并不意味着它们是不同的集合。它是另一个集合中的集合。即每个OuterCollection记录由一个InnerCollection列表组成。此外,你是如何选择内部列表框鼠标双击事件的外部列表框项目? – Dennis

+0

没关系我用过的不同系列。这只是为了说明。好吧,在“CommandParameter”中,您会发现第二个疑问,那就是使用RelativeSource将它绑定到First ListBox。因此,它会查找Visual树并尝试查找符合'AncestorLevel'标准的'ListBox'。如果它找到一个,那么它绑定到它。顺便你执行我的代码?它是否按照它所要求的方式工作? – Sandesh

+0

假设我选择了外部列表框中的第一个项目,并双击位于外部列表框中第三个项目内部的内部列表框项目。那么你的祖先只会返回第一个列表框项目。不是第三个... – Dennis