2
votes

I have created a context menu that I (at the moment) use for some items in my treeview. For that I have created a TreeItem class that holds all the relevant information like header, icon, children, execute target, etc. This is what it looks like:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"
             Visibility="{Binding ShowContextMenu}"
             ItemsSource="{Binding ContextMenu}">
  <ContextMenu.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Children}">
      <TextBlock Text="{Binding Header}" />
      <HierarchicalDataTemplate.ItemContainerStyle>
        <Style TargetType="MenuItem">
          <Setter Property="Command"
                  Value="{Binding Execute}" />
          <Setter Property="Icon"
                  Value="{StaticResource cmIcon}" />
          <Setter Property="ToolTip"
                  Value="{Binding ToolTip}" />
        </Style>
      </HierarchicalDataTemplate.ItemContainerStyle>
    </HierarchicalDataTemplate>
  </ContextMenu.ItemTemplate>
  <ContextMenu.ItemContainerStyle>
    <Style TargetType="MenuItem">
      <Setter Property="Command"
              Value="{Binding Execute}" />
      <Setter Property="Icon"
              Value="{StaticResource cmIcon}" />
      <Setter Property="ToolTip"
              Value="{Binding ToolTip}" />
    </Style>
  </ContextMenu.ItemContainerStyle>
</ContextMenu>

When I used the context menu only in the tree view, it was attached to the TextBlock in the ItemTemplate. But now I want to use the same context menu for a different control. As I don't want to copy the same code to a different location and maintain it multiple times, I want to reuse it as template. I tried 2 things:

  • I put the context menu in the resources of the user control (just for testing) and call it like this: <TextBlock Text="{Binding Header}" ContextMenu="{StaticResource myContextMenu}">. It will be displayed, but not be closed and not move. Also this is not really helpful anyway as I want to use the context menu on a different user control.

  • Then I put the context menu inside a control template in the App.xaml: <ControlTemplate x:Key="TreeContextMenu" TargetType="ContextMenu">. And I call it like this:

    <TextBlock.ContextMenu>
        <ContextMenu Template="{StaticResource TreeContextMenu}"/>
    </TextBlock.ContextMenu>
    

The program starts, but when I want to open the context menu, I get an exception: 'ContextMenu' cannot have a logical or visual parent.

I have tried to google for a solution, but couldn't find anything helpful.

1

1 Answers

1
votes

You are trying to create a context menu inside a context menu. Remove the ControlTemplate tag from the App.xaml and move the x:Key attribute directly to the ContextMenu tag.

Also, delete the TextBlock.ContextMenu and add ContextMenu="{StaticResource TreeContextMenu}" attribute to the TextBlocktag.