Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 EntityDataGrid? Is it possible at all?

Thank you for help in advance!

like image 484
Slauma Avatar asked Jan 25 '11 23:01

Slauma


2 Answers

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>
like image 90
Fredrik Hedblad Avatar answered Nov 12 '22 13:11

Fredrik Hedblad


Have you tried doing an Ancestor binding? Something like:

<Setter Property="CommandParameter"
        Value="{Binding Path=SelectedItems, 
        RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
like image 9
CodeWarrior Avatar answered Nov 12 '22 12:11

CodeWarrior