Подтвердить что ты не робот

Параметр команды передачи из xaml

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

<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">
4b9b3361

Ответ 1

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

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

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

Ответ 2

Это не работает, потому что 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>