TreeView ContextMenu MVVM Binding
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:Da开发者_如何学JAVAtabase}" >
<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; }
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.
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}} }
That probably has to do with the inheritance context.
See: Binding WPF ContextMenu MenuItem to UserControl Property vs ViewModel Property
精彩评论