Передать параметр команды из xaml - PullRequest
20 голосов
/ 16 ноября 2011

Я пытаюсь сделать что-то вроде этого:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}">
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding RemoveRow}" 
              CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>

но я всегда получаю нулевое значение (я пробовал также SelectedIndex и SelectedValue)

, если я передаю следующий параметр в код выполнения,это работает:

<MenuItem Command="{Binding RemoveRow}" CommandParameter="1">

Ответы [ 2 ]

21 голосов
/ 29 ноября 2013

Попробуйте что-то подобное в вашем CommandParameter,

<DataGrid.ContextMenu>
     <ContextMenu>
           <MenuItem Header="MyHeader" 
                     Command="{Binding MyCommand}"
                     CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.SelectedItem}" />
</DataGrid.ContextMenu>

Я уже проверил это, и оно должно работать.

18 голосов
/ 16 ноября 2011

Он не работает, потому что ContextMenu не является частью визуального или логического дерева DataGrid, поэтому он не наследует DataContext.

Насколько я знаюСуществует простое решение этой проблемы с использованием только встроенной системы привязки.Однако, используя простой прокси-класс, как описано здесь , вы можете обойти эту проблему:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}">
   <DataGrid.Resources>
       <local:BindingProxy x:Key="proxy" Data="{Binding}" />
   </DataGrid.Resources>
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding Data.RemoveRow, Source={StaticResource proxy}}" 
              CommandParameter="{Binding ElementName=myGrid, Path=SelectedItem}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>

Однако у вас все еще есть проблема: ElementName=myGrid не работает (опять же, потому что ContextMenu не находится в визуальном или логическом дереве DataGrid, поэтому он не находится в той же области имен).Простое решение - привязать SelectedItem DataGrid к свойству ViewModel и использовать это свойство вместо параметра команды:

<DataGrid Name="myGrid" ItemSource="{Binding Path=MyCollection}"
          SelectedItem="{Binding SelectedItem}">
   <DataGrid.Resources>
       <local:BindingProxy x:Key="proxy" Data="{Binding}" />
   </DataGrid.Resources>
   <DataGrid.ContextMenu>
       <ContextMenu>
          <MenuItem 
              Command="{Binding Data.RemoveRow, Source={StaticResource proxy}}">
       </ContextMenu>
   </DataGridContextMenu>
</DataGrid>
...