Binding a context menu command parameter to a datagrid property
In my XAML file I have a DataGrid with a context menu. The data source is a ViewModel which has a property EntityCollection
(an ObservableCollection) as the ItemsSource of the DataGrid and another collection ContextMenu.MenuItems
which serves as the data source to create a context menu on the DataGrid. The elements of that collection have a Command
property which I bind to the Command property of the menu items:
<DataGrid Name="EntityDataGrid" ItemsSource="{Binding EntityCollection}" Height="450">
<DataGrid.ContextMenu>
<ContextMenu ItemsSource="{Binding Path=ContextMenu.MenuItems}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="CommandParameter"
Value="{Binding ElementName=EntityDataGrid, Path=SelectedItems}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
The action for the menu item command has the following signature in the ViewModel:
private void SelectedItemsAction(object parameter)
{
// Do something with "parameter"
}
Now my problem is that I reach SelectedItemsAction
when I click on a context menu item but the parameter
is null
. I believe that my problem is in the setter for the CommandParameter
property. As you can see, I want to bind this property to the SelectedItems
property of the DataGrid by setting the value to:
<Setter Property="CommandParameter"
Value="{Binding ElementName=EntityDataGrid, Path=SelectedItems}" />
I've tried simpler values as a test:
<Setter Property="CommandParameter"
Value="{Binding ElementName=EntityDataGrid, Path=Height}" />
Here parameter
is still null
. And then just to test if any parameter reaches my action method at all:
<Setter Property="CommandParameter"
Value="10" />
This works, the parameter
in my action method is now indeed 10
.
What am I doing wrong to bind the CommandParameter
value to a property of Ent开发者_开发知识库ityDataGrid
? Is it possible at all?
Thank you for help in advance!
The ContextMenu
isn't in the same part of the Visual Tree so that's why you can't use ElementName etc. to reference the DataGrid
. You'll have to use PlacementTarget
of the ContextMenu
instead. Try it like this
<ContextMenu ItemsSource="{Binding Path=ContextMenu.MenuItems}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="CommandParameter"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}},
Path=PlacementTarget.SelectedItems}" />
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
Have you tried doing an Ancestor binding? Something like:
<Setter Property="CommandParameter"
Value="{Binding Path=SelectedItems,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<Setter Property="CommandParameter"
Value="{Binding Path=SelectedItems,
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
If you use the code in the CodeWarrior answer, you can convert it to any type you want using the code below on the ViewModel side.
System.Collections.IList items = (System.Collections.IList)obj;
var collection = items.Cast<Foo>();
after that
foreach(var item in collection)
{
.
.
but if you need a single line the following code will suffice.
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
精彩评论