开发者

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}}}"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜