SBa
SBa

Reputation: 43

Command Binding of Submenu item in Context Menu

I have a TreeView with an hierarchical Data Template (2 levels). I have a context menu created on the first level of the tree view with 3 levels. I want to bind a command of my view model to the second level of the context menu. Unfortunately I can only get it to work when using a command in my Model, which is not what I want to do... If possible, I would like to do it all in XAML.

I have tested the pure xaml solutions given here and here. In the designer, the "Tag" is underlined blue saying

"Cannot resolve Property Tag in data context of type System.Windows.UIElement"
or, if I use "Parent.PlacementTarget....", the designer tells me that
PlacementTarget cannot be resolved in the data context of type System.Windows.DependencyObject.
The code is compileable, but my command is never reached.

This is what I have:

In a ResourceDictionary:

<DataTemplate DataType="{x:Type viewModel:UpdateToolViewModel}">
    <view:UpdateToolView/>
</DataTemplate>

<DataTemplate x:Key="ToolNameDataTemplate" DataType="{x:Type src:Element}">
    <Grid>
        <TextBlock Text="{Binding Path=NameProperty.Value}" FontSize="12" />
    </Grid>
</DataTemplate>
<HierarchicalDataTemplate x:Key="ToolGroupsDataTemplate" ItemsSource="{Binding Elements}" DataType="{x:Type src:ElementGroup}" ItemTemplate="{StaticResource ToolNameDataTemplate}">
    <TextBlock Text="{Binding Path=TextProperty.Value}" FontSize="14" FontWeight="Bold" Tag="{Binding ElementName=UpdateToolControl}">
        <TextBlock.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Add Tool" ItemContainerStyle="{StaticResource ToolGroupContextMenuToolsItemStyle}" >
                    <MenuItem.ItemsSource>
                        <CompositeCollection>
                            <MenuItem Header="Add New ..." Command="{Binding PlacementTarget.Tag.DataContext.AddToolCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}}" />
                            <CollectionContainer Collection="{Binding Source={StaticResource AddToolContextMenuSource}}"/>
                        </CompositeCollection>
                    </MenuItem.ItemsSource>
                </MenuItem>
            </ContextMenu>
        </TextBlock.ContextMenu>            
    </TextBlock>
</HierarchicalDataTemplate>

In the UserControl:

<UserControl x:Class="...UpdateToolView" ... Name="UpdateToolControl">
    <TreeView Name="ToolTreeView" ItemsSource="{Binding AllElementsInGroups}"
              ItemTemplate="{StaticResource ToolGroupsDataTemplate}"
              ItemContainerStyle="{StaticResource ToolTreeViewItemStyle}"/>
</UserControl>

I am already on the verge of using the command in my model, calling a method in my view model. Not nice, but I just don't seem to get it to work differently.

Upvotes: 2

Views: 989

Answers (1)

SBa
SBa

Reputation: 43

I was just going on, trying to figure out how to add a command to the CollectionContainer Items, when I found this: CollectionContainer Binding (sorry, its german, but the xaml code is the relevant thing here)

Now I have added the command in the ItemContainerStyle of the MenuItem and suddenly the whole thing works (although "Tag" is still underlined blue in the designer):

<converter:ElementToToolTipConverter x:Key="ElementToToolTipConverter"/>
<Style x:Key="ToolGroupContextMenuToolsItemStyle" TargetType="{x:Type MenuItem}">
    <Setter Property="Header" Value="{Binding Name}"/>
    <Setter Property="ItemsSource" Value="{Binding Children}"/>
    <Setter Property="ToolTip" Value="{Binding Element, Converter={StaticResource ElementToToolTipConverter}}"/>
    <Setter Property="Command" Value="{Binding PlacementTarget.Tag.DataContext.AddToolCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
    <Setter Property="CommandParameter" Value="{Binding}"/>
</Style>

Sometimes, it already helps thinking about something else... :)

Upvotes: 1

Related Questions