上下文菜单中的绑定命令

时间:2016-07-01 12:18:01

标签: c# wpf

我试图学习如何使用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>

2 个答案:

答案 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}" ... />