WPF-单选MenuItem

这几天在做一个工具栏,用到了Menu控件,我们都知道它是条目控件,可以绑定数据源。自带的样式不太好看,于是自己就想修改一下,让它默认只有一个子项处于选中状态,再次打开会记录当前选中的是那个MenuItem.思路就是嵌入一个RadioButton控件并让其不可见,控制它的IsChecked属性与MenuItem的IsChecked属性之间的关系,支持添加Icon。

  • Xaml及样式
<Window x:Class="WpfApp1Blend.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1Blend"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="800">
    <Window.Resources>
        <SolidColorBrush x:Key="Window.ToolBar.Selected.FgColor" Color="#42a4ff"></SolidColorBrush>
        <SolidColorBrush x:Key="Window.ToolBar.Selected.BgColor" Color="#0E2E58"></SolidColorBrush>
        <SolidColorBrush x:Key="Window.ToolBar.MouseOver.BgColor" Color="#0a2243"></SolidColorBrush>
        <SolidColorBrush x:Key="Window.ToolBar.BorderBrushColor" Color="#0d3256"></SolidColorBrush>
        <SolidColorBrush x:Key="Window.ToolBar.BgColor" Color="#031527"></SolidColorBrush>
        <SolidColorBrush x:Key="Control.Static.FgColor" Color="#A5C0E2"></SolidColorBrush>

        <Style x:Key="TextBlock.Static13" TargetType="TextBlock">
            <Setter Property="Foreground" Value="{StaticResource Control.Static.FgColor}" />
            <Setter Property="FontFamily" Value="Microsoft YaHei"></Setter>
            <Setter Property="TextWrapping" Value="Wrap" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="Margin" Value="5"></Setter>
            <Setter Property="FontSize" Value="13" />
        </Style>
        <Style TargetType="{x:Type Menu}">
            <Setter Property="Background" Value="{StaticResource Window.ToolBar.BgColor}"></Setter>
        </Style>
        <Style TargetType="{x:Type MenuItem}">
            <Setter Property="IsCheckable" Value="True"></Setter>
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type MenuItem}">
                        <Border x:Name="Border_Ground" Background="Transparent">
                            <StackPanel>
                                <Grid Margin="10,3">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="auto"></ColumnDefinition>
                                        <ColumnDefinition Width="auto"></ColumnDefinition>
                                        <ColumnDefinition></ColumnDefinition>
                                    </Grid.ColumnDefinitions>
                                    <RadioButton x:Name="rdo" IsChecked="{Binding IsChecked,RelativeSource={RelativeSource Mode=TemplatedParent},Mode=OneWay}" GroupName="A" IsThreeState="False" VerticalAlignment="Center" ></RadioButton>
                                    <Image Grid.Column="1" Source="{Binding Icon,RelativeSource={RelativeSource Mode=TemplatedParent}}" Stretch="None" Margin="0,0,0,0"/>
                                    <TextBlock x:Name="tb" Grid.Column="2"  Text="{TemplateBinding Header}" Style="{StaticResource TextBlock.Static13}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                                <Popup x:Name="popup" AllowsTransparency="True"   PopupAnimation="Fade" StaysOpen="False" VerticalOffset="5" IsOpen="{TemplateBinding IsChecked}" AutomationProperties.HelpText="121212">
                                    <Border Background="{StaticResource Window.ToolBar.BgColor}">
                                        <ItemsPresenter></ItemsPresenter>
                                    </Border>
                                </Popup>
                            </StackPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" SourceName="rdo" Value="true">
                                <Setter TargetName="Border_Ground" Property="Background" Value="{DynamicResource Window.ToolBar.Selected.BgColor}"/>
                                <Setter TargetName="tb" Property="Foreground" Value="{DynamicResource Window.ToolBar.Selected.FgColor}"/>
                                <Setter Property="IsChecked"  Value="True"></Setter>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter TargetName="tb" Property="Foreground" Value="{DynamicResource Window.ToolBar.Selected.FgColor}"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="Border_Ground" Property="Background" Value="{DynamicResource Window.ToolBar.MouseOver.BgColor}"/>
                                <Setter TargetName="Border_Ground" Property="BorderBrush" Value="{DynamicResource Window.ToolBar.BorderBrushColor}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>
    <Grid Width="400" Height="400">
        <StackPanel>
            <Menu>
                <MenuItem Header="A">
                    <MenuItem Header="A-1"/>
                    <MenuItem Header="A-2"/>
                </MenuItem>
                <MenuItem Header="B">
                    <MenuItem Header="B-1"></MenuItem>
                    <MenuItem Header="B-2"></MenuItem>
                    <MenuItem Header="B-3"></MenuItem>
                    <MenuItem Header="B-4"></MenuItem>
                </MenuItem>
            </Menu>
        </StackPanel>
    </Grid>
</Window>
  •  效果

WPF-单选MenuItem

不足之处就是弹出popup面板之后,需要点击外部两次才能隐藏popup,我想第一点击是radiobutton失去焦点,再次点击是为了隐藏popup控件。有兴趣的同学可以自己再优化一下。

上一篇:ToggleButton 和 Switch


下一篇:购物车的基本代码 不完善