Fejs
Fejs

Reputation: 2888

Checkable MenuItem appearing like ToggleButton in C# WPF

I am trying to create menu with MenuItem that is checkable, but looks like toggle button. Currently, it looks like this:

enter image description here

You'd agree, this looks pretty ugly and it's not intuitive whether check mark belongs to Views or to Actions.

I'm aware that regular CheckBox has property Appearance which can be set to Button, making CheckBox appear like ToggleButton. However, there is no such property for MenuItem object.

I've also tried to add ToggleButton to menu, but it's appearance differs from what I'd expect. Here's the screenshot of this try:

enter image description here

I expect it to look something like this:

enter image description here

Is there a way to display toogle button control (or something appearing like it) in menu bar?

P.S. If You need my current test code, here it is:

<Menu Grid.Row="0" HorizontalAlignment="Stretch" IsHitTestVisible="True" x:Name="mnuMain">
    <MenuItem Header="File" x:Name="mnuFile">
        <MenuItem Header="Export List to Excel" x:Name="btnExportToExcel" Click="OnExportToExcel"/>
    </MenuItem>
    <MenuItem Header="Views" x:Name="mnuViews">
        <MenuItem Header="Item1" x:Name="chkItem1" IsCheckable="true" Click="OnChkItem1Click" />
        <MenuItem Header="Item2" x:Name="chkItem2" IsCheckable="true" Click="OnChkItem2Click" />
    </MenuItem>
    <MenuItem Header="Actions" x:Name="mnuActions" IsCheckable="true" >
        <!-- -->
    </MenuItem>
    <MenuItem Header="Analysis" x:Name="btnAnalysis" Click="OnAnalysisClick"/>
    <MenuItem Header="History" x:Name="btnHistory" Click="OnHistoryClick"/>
    <ToggleButton x:Name="tbTest" BorderThickness="0" Background="Transparent" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" Click="OnTbTestClick">Test</ToggleButton>
</Menu>

Upvotes: 1

Views: 2978

Answers (1)

ASh
ASh

Reputation: 35730

it is possible to change MenuItem template for checkable and checked items, using custom style with triggers. Here is an example of a template (it was exctrcted from default MenuItem style)

<SolidColorBrush x:Key="MenuItem.Highlight.Background" Color="#3D26A0DA"/>
<SolidColorBrush x:Key="MenuItem.Highlight.Border" Color="#FF26A0DA"/>
<SolidColorBrush x:Key="Menu.Disabled.Foreground" Color="#FF707070"/>

<Style x:Key="MenuItemToggleStyle" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsChecked" Value="True"/>
                <Condition Property="IsCheckable" Value="True"/>
                <Condition Property="Role" Value="TopLevelItem"/>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="MenuItem">
                            <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                                <Grid VerticalAlignment="Center">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <ContentPresenter x:Name="Icon" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>
                                    <ContentPresenter Grid.Column="1" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="Icon" Value="{x:Null}">
                                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{StaticResource Menu.Disabled.Foreground}"/>
                                    <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Border}"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="True">
                                    <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Background}"/>
                                    <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Border}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </MultiTrigger.Setters>
        </MultiTrigger>
    </Style.Triggers>
</Style>

Upvotes: 4

Related Questions