Can't attach event handler to Context Menu Item in Style

Dmitriy picture Dmitriy · Mar 24, 2011 · Viewed 9.3k times · Source

I'm trying to modify default ContextMenu for XamNumericEditor on XamDataGrid editable cell.

Here is my XAML-code:

<igDP:XamDataGrid.Resources>
  <Style TargetType="{x:Type editors:XamNumericEditor}">
    <Setter Property="ContextMenu">
      <Setter.Value>
        <ContextMenu>
          <ContextMenu.Items>
            <MenuItem Header="Select All"
                      Command="SelectAll">
              <MenuItem.Icon>
                <Image Source="..\icons\table_select_all.png"/>
              </MenuItem.Icon>
            </MenuItem>
            <MenuItem Header="Accept for column"
                      Click="MenuItem_Click">
            </MenuItem>
          </ContextMenu.Items>
        </ContextMenu>
      </Setter.Value>
    </Setter>
  </Style>
</igDP:XamDataGrid.Resources>

Code behind file contains event hadler for this MenuItem:

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
//...
}

But when I start it, I catch an exception with message: Unable to cast object of type 'System.Windows.Controls.MenuItem' to type 'System.Windows.Controls.ContextMenu'.

Can you help me with it? Thanks.

Answer

Fredrik Hedblad picture Fredrik Hedblad · Mar 24, 2011

Try to add the ContextMenu as a Resource and the reference it as a StaticResource I don't have XamDataGrid installed so I can't try it but it should be along the following lines.

<igDP:XamDataGrid.Resources>
    <ContextMenu x:Key="contextMenu">
        <ContextMenu.Items>
            <MenuItem Header="Select All"
                      Command="SelectAll">
                <MenuItem.Icon>
                    <Image Source="..\icons\table_select_all.png"/>
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Header="Accept for column"
                      Click="MenuItem_Click"></MenuItem>
        </ContextMenu.Items>
    </ContextMenu>
    <Style TargetType="{x:Type editors:XamNumericEditor}">
        <Setter Property="ContextMenu" Value="{StaticResource contextMenu}"/>
    </Style>
</igDP:XamDataGrid.Resources>

Alternatively, you could use an EventSetter

<MenuItem Header="Accept for column">
    <MenuItem.Style>
        <Style TargetType="MenuItem">
            <EventSetter Event="Click" Handler="MenuItem_Click"/>
        </Style>
    </MenuItem.Style>
</MenuItem>

Update

To get the PlacementTarget you'll need the ContextMenu. You could pass this along as CommandParameter

<MenuItem Header="Accept for column"
          CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
          Click="MenuItem_Click">
</MenuItem>

private void MenuItem_Click(object sender, RoutedEventArgs e)
{
    MenuItem menuItem = sender as MenuItem;
    ContextMenu contextMenu = menuItem.CommandParameter as ContextMenu;
    var placementTarget = contextMenu.PlacementTarget;
    //...
}