简体   繁体   English

在CommandParameter中传递项DataContext

[英]Pass the item DataContext in CommandParameter

I have a treeview which is created from ItemsSource of SecondViewModel instances, different from my Window DataContext. 我有一个TreeView,它是从SecondViewModel实例的ItemsSource创建的,不同于我的Window DataContext。

I want to send the ViewModel that belongs to the TreeViewItem via a `CommandParameter. 我想通过`CommandParameter发送属于TreeViewItem的ViewModel。

The window data context is: MyViewModel . 窗口数据上下文是: MyViewModel The treeviewitems data context is: SecondViewModel treeviewitems数据上下文是: SecondViewModel

I want to pass the SecondViewModel and not MyViewModel . 我想传递SecondViewModel而不是MyViewModel

Therefore, 因此,

CommandParameter ="{Binding}" 

Won't work (as it will send MyViewModel ) 不会工作(因为它会发送MyViewModel

Edit: Some Code: 编辑:一些代码:

 <TreeView Name="treeView" ItemContainerStyle="{StaticResource TreeViewItemStyle}"  Grid.Row="1" Grid.Column="1">
        <TreeViewItem Header="{Binding ProjectName}">
            <TreeViewItem commandBehaviors:MouseDoubleClick.Command="{Binding SelectOtherTab}" 
                          commandBehaviors:MouseDoubleClick.CommandParameter="{Binding}" //this returns the data context of the window, I want to return the Item Source
                ContextMenu="{StaticResource AddClassMenu}" ItemTemplate="{DynamicResource ClassDataTemplate}" ItemsSource="{Binding ClassCollection}">

How can I send the SecondViewModel ? 我如何发送SecondViewModel

EDIT: 编辑:

I want to enable deleting the current item, but the command never gets called for some reason. 我想启用删除当前项目,但该命令永远不会因某种原因被调用。

Here's the code: 这是代码:

<TreeViewItem x:Name="treeViewItem"
                ContextMenu="{StaticResource AddClassMenu}" ItemTemplate="{DynamicResource ClassDataTemplate}" ItemsSource="{Binding ClassCollection}">
                <TreeViewItem.ItemContainerStyle>
                    <Style TargetType="TreeViewItem">
              HERE->>          <Setter Property="ContextMenu" Value="{StaticResource RemoveClassMenu}"/>
                        <Setter Property="commandBehaviors:MouseDoubleClick.Command" 
        Value="{Binding ElementName=treeViewItem, Path=DataContext.SelectOtherTab}" />
                        <Setter Property="commandBehaviors:MouseDoubleClick.CommandParameter" 
        Value="{Binding }" />
                    </Style>
</TreeViewItem>

My Context Menu: 我的上下文菜单:

 <ContextMenu x:Key="RemoveClassMenu">
    <MenuItem Header="Delete" Command="{Binding ElementName=treeViewItem, Path=DataContext.RemoveClass}" CommandParameter="{Binding}"/>
</ContextMenu>

As mentions before, the command just never gets called. 如前所述,命令永远不会被调用。 What is the problem with my code? 我的代码有什么问题?

I think what you're looking to do is set your DoubleClick commands on your child TreeViewItems , not your parent TreeViewItem which sets the ItemsSource 我认为您要做的是在您的子TreeViewItems上设置DoubleClick命令,而不是设置ItemsSourceTreeViewItem

Right now your XAML is saying to build a parent TreeViewItem , and under that build a bunch of child TreeViewItems for each item in ClassCollection . 现在你的XAML正在建立一个父TreeViewItem ,并在该构建下为ClassCollection每个项构建一堆子TreeViewItems When you double click on the parent TreeViewItem then run the SelectOtherTab command, however there's nothing to specify which child TreeViewItem got clicked. 双击父TreeViewItem然后运行SelectOtherTab命令,但是没有任何内容可以指定单击哪个子TreeViewItem

Here's a simplified view of the XAML you have now. 这是您现在拥有的XAML的简化视图。

<TreeView x:Name="treeView">
    <TreeViewItem OnDoubleClick="SelectOtherTab"> <!-- Parent TreeViewItem -->
        <TreeViewItem /><!-- Child TreeViewItems -->
        <TreeViewItem />
        <TreeViewItem />
        ...
    </TreeViewItem>
</TreeView>

Instead you want to attach the Command and CommandParameter properties to each child TreeViewItem , like this: 相反,您希望将CommandCommandParameter属性附加到每个子TreeViewItem ,如下所示:

<TreeViewItem.ItemContainerStyle>
  <Style TargetType="TreeViewItem">
    <Setter Property="commandBehaviors:MouseDoubleClick.Command" 
            Value="{Binding ElementName=treeView, Path=DataContext.SelectOtherTab}" />
    <Setter Property="commandBehaviors:MouseDoubleClick.CommandParameter" 
            Value="{Binding }" />
  </Style>
</TreeViewItem.ItemContainerStyle>

Which will make your simplified XAML look something like this: 这将使您的简化XAML看起来像这样:

<TreeView x:Name="treeView">
    <TreeViewItem> <!-- Parent TreeViewItem -->
        <TreeViewItem OnDoubleClick="SelectOtherTab" /><!-- Child TreeViewItems -->
        <TreeViewItem OnDoubleClick="SelectOtherTab"/>
        <TreeViewItem OnDoubleClick="SelectOtherTab" />
        ...
    </TreeViewItem>
</TreeView>

I'm still a bit confused by why you have a parent TreeViewItem and are building child TreeViewItems using it's ItemsSource , however if that's not necessary you can simplify your VisualTree by eliminating the parent TreeViewItem like this: 我仍然有点混淆为什么你有一个父TreeViewItem并使用它的ItemsSource构建子TreeViewItems ,但是如果没有必要你可以通过消除这样的父TreeViewItem来简化你的VisualTree:

<TreeView Name="treeView" 
          ItemsSource="{Binding ClassCollection}"
          ItemContainerStyle="{StaticResource TreeViewItemStyle}"  
          Grid.Row="1" Grid.Column="1">
    <TreeView.Resources>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="Header" Value="ProjectName" />
            <Setter Property="ContextMenu" Value="{StaticResource AddClassMenu}" />
            <Setter Property="ItemTemplate" Value="{DynamicResource ClassDataTemplate}" />

            <Setter Property="commandBehaviors:MouseDoubleClick.Command" 
                    Value="{Binding ElementName=treeView, Path=DataContext.SelectOtherTab}" />
            <Setter Property="commandBehaviors:MouseDoubleClick.CommandParameter" 
                    Value="{Binding }" />
        </Style>
    </TreeView.Resources>
</TreeView>

Which will make your TreeView look like this: 这将使您的TreeView看起来像这样:

<TreeView x:Name="treeView">
    <TreeViewItem OnDoubleClick="SelectOtherTab" />
    <TreeViewItem OnDoubleClick="SelectOtherTab"/>
    <TreeViewItem OnDoubleClick="SelectOtherTab" />
    ...
</TreeView>

you must declare a property of type SecondViewModel in MyViewModel.then you can bind the data to inner items too. 你必须在MyViewModel中声明一个SecondViewModel类型的属性。然后你也可以将数据绑定到内部项目。

CommandParameter ="{Binding SecondViewModelProp.CommandParam}" CommandParameter =“{Binding SecondViewModelProp.CommandParam}”

if command parameter is defined inside the SecondViewModelProp. if命令参数是在SecondViewModelProp中定义的。

Let me know if I understood something wrong. 如果我理解错误,请告诉我。

 public class MyViewModel
 {
    public SecondViewModel  SecondViewModelProp
    {
        get { return new SecondViewModel(); }
    }

   public MyViewModel()
   {

   }
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM