2016-07-01 3 views
1

私はコンテキストメニューの使い方を学んでいます。私はメニューを取得し、それは良いようですが、コマンドはコンテキストメニューにバインドしません。コンテキストメニューの下の目に見えるボタンスタックパネルで機能します。私は、出力でこれを取得する:コンテキストメニューのコマンドのバインド

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=MainGrid'. BindingExpression:Path=DataContext.StartClientCommand; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Command' (type '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

Thakeこれを見ます。http:// stackoverflowの。 com/questions/3878620/binding-context-menu-item-to-parent-control – CiccioRocca

答えて

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

ContextMenuは、ビジュアルツリーの一部ではないので、あなたのグリッドに到達することはできません:あなたは以下のようにそれを行うことができます。

PlacementTargetプロパティを含むContextMenuのコントロールを含むことができます。

ViewModelを正しく設定していれば、DataContextはあなたのCMに届きます。あなたの場合、DataTemplate'sDataContextで十分でしょう。それがない場合、あなたはしたい、とあなたのコマンドは、我々はNavigationCommandクラスを持っている方法のような静的メンバとして存在している、あなたは次のようにコマンドを割り当てる必要があります:

<MenuItem Command="{x:Static local:MyCommands.CustomCommand}" ... /> 
関連する問題