0

I have a TreeView whose itemsource is a collection of my Model class. I have added a context menu on the treeView. Since the commands of the contextMenu should be in the visual tree, so I had to place them in my Model class. Which is wrong (Binding directory to the Model).

How can I Bind my context menu's Command to my ViewModel rather than Model?

Here is my XAML code for TreeView.

 <TreeView ItemsSource="{Binding DigSource}" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
                    <TreeView.ItemContainerStyle >
                        <Style TargetType="{x:Type TreeViewItem}">
                            <Setter Property="ContextMenu">
                                <Setter.Value>
                                    <ContextMenu >
                                        <MenuItem Header="Edit" CommandParameter="{Binding }"
                                            Command="{Binding Path=PlacementTarget.Tag.DataContext.MyCommand, 
                                            RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" />
                                    </ContextMenu>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </TreeView.ItemContainerStyle >
                    <TreeView.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding SingleDig}">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Name}"/>
                            </StackPanel>
                            <HierarchicalDataTemplate.ItemTemplate>
                                <DataTemplate DataType="{x:Type dt:MultiDig}">
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Text="{Binding Name}"/>
                                    </StackPanel>
                                </DataTemplate>
                            </HierarchicalDataTemplate.ItemTemplate>
                        </HierarchicalDataTemplate>
                    </TreeView.ItemTemplate>
                </TreeView>

and ViewModel's Icommand Property is

    private ICommand _editMenuCommand;
    /// <summary>
    /// Edit command
    /// </summary>
    public ICommand EditMenuCommand { get { return _editMenuCommand ?? (_editMenuCommand = new RelayCommand(EditMenu)); } }

    /// <summary>
    /// Edit menu
    /// </summary>
    public void EditMenu()
    {
        MessageBox.Show("Edit me");
    }

Thanks in advance.

1
  • what is the issue with this code? command not firing? Commented Sep 18, 2013 at 17:52

1 Answer 1

3

Here is your ItemContainerStyle with updated bindings.. Tested this at my end and it works well.

<TreeView ItemsSource="{Binding DigSource}">
    <TreeView.ItemContainerStyle >
          <Style TargetType="{x:Type TreeViewItem}">
               <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
               <Setter Property="ContextMenu">
                   <Setter.Value>
                       <ContextMenu >
                            <MenuItem Header="Edit" CommandParameter="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
                                                Command="{Binding Path=PlacementTarget.Tag.DataContext.MyCommand, 
                                                RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}" />
                         </ContextMenu>
                    </Setter.Value>
                  </Setter>
         </Style>
   </TreeView.ItemContainerStyle >
Sign up to request clarification or add additional context in comments.

10 Comments

The problem is I dont know whether its a Parent Item for which the command was called or a child item. I have only two hirarchies. A Parent can have multiple children, and there can b n parents items. So I need to know for which item, the context menu's command is called.
yesterday you said "send item in command parameter like Binding=PlacementTarget.DataContext", I did it but I dont know how do I receive the item in my viewModel
yes.. the answer i provided above does the same.. now we have context menu on the treeviewitem..it can be any treeviewitem (parent or child) and will be PlacementTarget for the contextmenu... so when we are saying PlacementTarget.DataContext it means the model backing the treeviewitem.. thats why you got that in commmand param
I gotcha. But At a time, its either a parent item's command executing or a child's. How do I know which one is it?
you have parent and child of different types rt? so by the type of the item you get in command parameter you can figure out if it was child or parent
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.