A style intended for type 'MenuItem' canno

2019-07-15 11:53发布

问题:

I'm working on WPF Window Application which uses ContextMenu.

My ContextMenu in XAML (in Window.Resources):

<ContextMenu x:Key="menuList" Placement="Bottom" >
    <ContextMenu.ItemContainerStyle>
        <Style TargetType="{x:Type MenuItem}">
            <Setter Property="Header" Value="{Binding Name}"/>
            <EventSetter Event="Click" Handler="cm_RefreshChannelNotification"/>
            <Setter Property="IsChecked" Value="{Binding CFiltered}" />
            <Setter Property="IsCheckable" Value="True"/>
            <Setter Property="StaysOpenOnClick" Value="True"/>           
        </Style>
    </ContextMenu.ItemContainerStyle> 
</ContextMenu> 

When I try to add Separator to the ContextMenu I receive error:

System.InvalidOperationException was unhandled Message="A style intended for type 'MenuItem' cannot be applied to type 'Separator'.

In this way I must add a new separator:

ContextMenu cm = this.FindResource("menuList") as ContextMenu;
Separator separator = new Separator();
separator.SnapsToDevicePixels = true;  
cm.Items.Add(separator);

What should I change/add in ContextMenu definition to make it work?

回答1:

You can move the style to the ContextMenu.Resources, this applies it implicitly to the menu items which will not conflict with the Separators.


An alternative may be to drop the TargetType and qualify the properties, non-applying properties might be ignored. Never did this myself though:

<Style>
    <Setter Property="MenuItem.Header" Value="{Binding Name}"/>


回答2:

One Adition to H.B.'s answer. Both ways are working for me.

However, setting MenuItem.Header property will result in an binding error in output window, which you could ignore of course.

So in my opinion move the style to the ContextMenu.Resources is the better option.

Sorry I can't write this as comment yet.



回答3:

You might need to use an ItemContainerStyleSelector. You have multiple types in your ContextMenu both MenuItem and Separator. Although one would expect WPF to apply it to the TargetType only and be able to supply multiple styles one for each targettype.

I encountered a similar issue with derived container types and needed to override GetContainerForItemOverride and IsItemItsOwnContainerOverride.