5

I currently have a UserControl that uses the MVVM model.

In that control there is a TreeView, which displays some items. I have added a HierarchicalDataTemplate for this TreeView and in that template is a ContextMenu for the Items.

In the ViewModel, which is DataContext of the control (named RestoresTreeViewControl) is a command I want to bind one of the menu items to. However what I have done doesn't seem to be working. I am getting the usual can't find source for binding reference.

Here is the bit of code for the datatemplate that tried to bind the EditDatabaseCommand to one of the menu items.

<HierarchicalDataTemplate DataType="{x:Type model:Database}" >
                    <StackPanel>
                        <TextBlock Text="{Binding Name}" >
                            <TextBlock.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Header="Edit" Command="{Binding ElementName=RestoresTreeViewControl, Path=DataContext.EditDatabaseCommand}" />
                                    <MenuItem Header="Delete"/>
                                    <Separator/>
                                    <MenuItem Header="Test Connection"/>
                                </ContextMenu>
                            </TextBlock.ContextMenu>
                        </TextBlock>
                    </StackPanel>
                </HierarchicalDataTemplate>

Here is a section of the ViewModel where the command is.

public ICommand EditDatabaseCommand { get; private set; }
Robaticus
  • 22,857
  • 5
  • 54
  • 63
Matthew Bill
  • 203
  • 3
  • 11

3 Answers3

6

Unfortunately the ContextMenu is not in the VisualTree, so it's not going to see your DataContext. What you can do is something like this (copied from here: MVVM binding command to contextmenu item)

<Button Height="40" Margin="0,2,0,0" CommandParameter="{Binding Name}" 
Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
      AncestorType={x:Type UserControl}}}" Command = "{Binding 
      RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},
      Path=DataContext.ConnectCommand}">
        <Button.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Remove" 
               CommandParameter="{Binding Name}"
            Command="{Binding Path=PlacementTarget.Tag.DataContext.RemoveCommand,
            RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
            </ContextMenu>
</Button.ContextMenu>

So simply use PlacementTarget.Tag to find your ViewModel.

Josher
  • 23
  • 7
Andras Sebo
  • 1,120
  • 8
  • 19
0

You can try tracing the binding:

 xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
 ...
 {binding ... diag:PresentationTraceSources.TraceLevel="High"}

However requiring the users (even if it is just yourself) of your control to name each instance of "RestoresTreeViewControl" rather burdensome.

Try:

 {Binding Path=... RelativeSource={ FindAncestor, AncestorType={x:TheRestoresTreeViewControlType}} } 
jyoung
  • 5,071
  • 4
  • 30
  • 47
0

That probably has to do with the inheritance context.

See: Binding WPF ContextMenu MenuItem to UserControl Property vs ViewModel Property

Community
  • 1
  • 1
lukebuehler
  • 4,061
  • 2
  • 24
  • 28