简体   繁体   中英

Bind contextMenu to a different viewmodel from treeview

I want to show a contextMenu item when I am using rightclick on a treeview item.

After that, I want to use a command when I click on my MenuItem, but I need to bind the command with a different viewmodel and the command parameter with the good viewmodel who come from my treeview selected item.

So for the moment, I have something like that :

<TreeView x:Name="TreeViewProtocolsAndEquipments" AllowDrop="True"
        ItemsSource="{Binding ModuleParams}">

        <TreeView.Resources>
            <!-- CONTEXT MENU -->
            <!-- Protocol -->    
            <ContextMenu x:Key="ContextMenuProtocol">
                <MenuItem Header="Add new equipment" Command="{Binding AddNewEquipmentCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">
                    <MenuItem.Icon>
                        <Image Source="Images/Add.png" />
                    </MenuItem.Icon>
                </MenuItem>
                <Separator />
            </ContextMenu>

            <!-- MODULE XXX -->
            <!-- ModuleParam > xxx -->
            <HierarchicalDataTemplate DataType="{x:Type xxx:ModuleParamXXXViewModel}" ItemsSource="{Binding ModuleItems}">
                <TextBlock Text="XXX" Foreground="Green" ContextMenu="{StaticResource ContextMenuProtocol}"/>
            </HierarchicalDataTemplate>
        </TreeView.Resources>

    </TreeView>

For the moment my command is bind to xxx:ModuleParamXXXViewModel if I just let { binding }

  1. Can I bind my Command to my ActivatedProtocolsAndEquipmentsTreeViewModel (the datacontext of this usercontrol) and keep on the CommandParameter my xxx:ModuleParamXXXViewModel (who is the Item from the treeview where we triggered the right click to show the contextMenu) ?
  2. How can I achieve this in an other way with MVVM practice ?

I also tried to use this but it didn't work too :

<MenuItem Header="Add new equipment" Command="{Binding Path=DataContext.AddNewEquipmentCommand, Source={x:Reference TreeViewProtocolsAndEquipments}}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">

And with this i get Object Reference not set to an instance of an object

The UserControl is not a visual ancestor of the MenuItem since a ContextMenu resides in its own visual tree.

Bind the Tag property of the TextBlock to the UserControl and then bind the Command property to the PlacementTarget of the ContextMenu :

<TreeView x:Name="TreeViewProtocolsAndEquipments" AllowDrop="True"
                  ItemsSource="{Binding ModuleParams}">
    <TreeView.Resources>
        <!-- CONTEXT MENU -->
        <!-- Protocol -->
        <ContextMenu x:Key="ContextMenuProtocol">
            <MenuItem Header="Add new equipment"
                              Command="{Binding PlacementTarget.Tag.DataContext.AddNewEquipmentCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" 
                              CommandParameter="{Binding}">
                <MenuItem.Icon>
                    <Image Source="Images/Add.png" />
                </MenuItem.Icon>
            </MenuItem>
            <Separator />
        </ContextMenu>

        <!-- MODULE XXX -->
        <!-- ModuleParam > xxx -->
        <HierarchicalDataTemplate DataType="{x:Type xxx:ModuleParamXXXViewModel}" ItemsSource="{Binding ModuleItems}">
            <TextBlock Text="XXX" Foreground="Green"
                               Tag="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"
                               ContextMenu="{StaticResource ContextMenuProtocol}"/>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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