Search code examples
wpfmvvmcontextmenustackpaneltreeviewitem

WPF ContextMenuOpening not fired on TreeViewItem with a StackPanel


In a TreeView, I have a HierarchicalDataTemplate, the TreeViewItem is in a horizontal StackPanel.

When I right-click on the Image or TextBlock, the ContextMenuOpening event is triggered, but when I right-click between the image and text block (that's the margin between the two), the ContextMenuOpening event is not triggered. What am I doing wrong so that the ContextMenuOpening event is triggered on the entire StackPanel?

<TreeView.Resources>
    <HierarchicalDataTemplate DataType="{x:Type treeViewVM:BaseTreeViewItemVM}" ItemsSource="{Binding SubItems}">
        <Grid ContextMenu="{Binding ContextMenu}">
            <StackPanel Orientation="Horizontal" Margin="2">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="PreviewMouseRightButtonDown">
                        <i:ChangePropertyAction PropertyName="IsSelected" Value="true" TargetObject="{Binding}" />
                    </i:EventTrigger>
                    <i:EventTrigger EventName="ContextMenuOpening">
                        <i:InvokeCommandAction Command="{Binding ContextMenuOpeningCommand}" PassEventArgsToCommand="True" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <Image Stretch="None" Source="{Binding Icon}" />
                <TextBlock Text="{Binding Label}" Margin="5,0,0,0" />
            </StackPanel>
        </Grid>
    </HierarchicalDataTemplate>
</TreeView.Resources>

I tried these 2 other versions without success :

        <Grid ContextMenu="{Binding ContextMenu}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="PreviewMouseRightButtonDown">
                    <i:ChangePropertyAction PropertyName="IsSelected" Value="true" TargetObject="{Binding}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="ContextMenuOpening">
                    <i:InvokeCommandAction Command="{Binding ContextMenuOpeningCommand}" PassEventArgsToCommand="True" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <StackPanel Orientation="Horizontal" Margin="2">
                <Image Stretch="None" Source="{Binding Icon}" />
                <TextBlock Text="{Binding Label}" Margin="5,0,0,0" />
            </StackPanel>
        </Grid>



        <StackPanel Orientation="Horizontal" Margin="2" ContextMenu="{Binding ContextMenu}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="PreviewMouseRightButtonDown">
                    <i:ChangePropertyAction PropertyName="IsSelected" Value="true" TargetObject="{Binding}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="ContextMenuOpening">
                    <i:InvokeCommandAction Command="{Binding ContextMenuOpeningCommand}" PassEventArgsToCommand="True" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <Image Stretch="None" Source="{Binding Icon}" />
            <TextBlock Text="{Binding Label}" Margin="5,0,0,0" />
        </StackPanel>

Solution

  • You need to set a background color. null - means there is no background and the click "goes through".

    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type treeViewVM:BaseTreeViewItemVM}" ItemsSource="{Binding SubItems}">
            <Grid ContextMenu="{Binding ContextMenu}">
                <StackPanel Orientation="Horizontal" Margin="2"
                            Background="Transparent">
    

    P.S. I don't understand why you need an external Grid in this layout. In my opinion, it's unnecessary.

            <HierarchicalDataTemplate DataType="{x:Type treeViewVM:BaseTreeViewItemVM}" ItemsSource="{Binding SubItems}">
                <StackPanel ContextMenu="{Binding ContextMenu}"
                            Orientation="Horizontal" Margin="2"
                            Background="Transparent">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="PreviewMouseRightButtonDown">
                            <i:ChangePropertyAction PropertyName="IsSelected" Value="true" TargetObject="{Binding}" />
                        </i:EventTrigger>
                        <i:EventTrigger EventName="ContextMenuOpening">
                            <i:InvokeCommandAction Command="{Binding ContextMenuOpeningCommand}" PassEventArgsToCommand="True" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                    <Image Stretch="None" Source="{Binding Icon}" />
                    <TextBlock Text="{Binding Label}" Margin="5,0,0,0" />
                </StackPanel>
            </HierarchicalDataTemplate>