我试图学习如何使用contextmenu。我得到菜单,它看起来不错,但命令不在上下文菜单中绑定。它们在上下文菜单下方的可见按钮堆栈面板中工作。我在输出中得到了这个:
System.Windows.Data错误:4:无法找到带引用的绑定源' ElementName = MainGrid'。 BindingExpression:路径= DataContext.StartClientCommand;的DataItem = NULL;目标元素是' MenuItem' (名称='&#39);目标财产是' Command' (键入' ICommand')
<ListBox x:Name="lbSlaves" Grid.Row="1"
ItemsSource="{Binding Slaves}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Width="150" >
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected ,Mode=TwoWay}"/>
<TextBlock Text="{Binding FriendlyName, Mode=OneWay}" >
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Start"
Command="{Binding ElementName=MainGrid, Path=DataContext.StartClientCommand}"
CommandParameter="{Binding}" />
<MenuItem Header="Stop"
Command="{Binding ElementName=MainGrid, Path=DataContext.StopClientCommand}"
CommandParameter="{Binding}" />
<MenuItem Header="Calibrate"
Command="{Binding ElementName=MainGrid, Path=DataContext.CalibrateClientCommand}"
CommandParameter="{Binding}" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
<Button
Content="Start"
Command="{Binding ElementName=MainGrid, Path=DataContext.StartClientCommand}"
CommandParameter="{Binding}" />
<Button
Content="Stop"
Command="{Binding ElementName=MainGrid, Path=DataContext.StopClientCommand}"
CommandParameter="{Binding}" />
<Button
Content="Calibrate"
Command="{Binding ElementName=MainGrid, Path=DataContext.CalibrateClientCommand}"
CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
答案 0 :(得分:3)
这有点棘手。由于ContextMenu不是可视树的一部分,因此您需要以不同的方式传递数据上下文。你可以这样做:
<TextBlock Text="{Binding FriendlyName, Mode=OneWay}" Tag="{Binding Path=DataContext, ElementName=MainGrid}" >
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Start"
Command="{Binding Path=PlacementTarget.Tag.StartClientCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
<MenuItem Header="Stop"
Command="{Binding Path=PlacementTarget.Tag.StopClientCommand , RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
<MenuItem Header="Calibrate"
Command="{Binding Path=PlacementTarget.Tag.CalibrateClientCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
答案 1 :(得分:1)
ContextMenu
不属于Visual Tree,因此您无法访问自己的网格。
您可以使用ContextMenu
属性获取PlacementTarget
的包含控件。
如果您已正确设置了ViewModel
,则DataContext
会到达您的CM。在您的情况下,DataTemplate's
DataContext
就足够了。如果那不是您想要的,并且您的命令作为静态成员出现,就像我们在NavigationCommand类中的方式一样,那么您需要分配如下命令:
<MenuItem Command="{x:Static local:MyCommands.CustomCommand}" ... />