c# – 如何在WPF中创建具有Microsoft Web应用程序样式的菜单

我们的任务是在 WPF中设计一个企业应用程序,它将取代具有现代外观的战舰灰色 Winforms应用程序.

我们喜欢Microsoft Web应用程序目前拥有的外观和感觉:

我们可以通常的方式在WPF中创建这些菜单

<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="_File">
            <MenuItem Header="_New" />
            <MenuItem Header="_Open" />
            <MenuItem Header="_Save" />
            <Separator />
            <MenuItem Header="_Exit" />
        </MenuItem>
    </Menu>
    <TextBox AcceptsReturn="True" />
</DockPanel>

但是我们会得到一些看起来像Winforms菜单的东西.

我已经看到了一些像this one这样令人印象深刻的造型工作,但它们似乎都具有相同熟悉的Winforms形状.我也看过像MahApps Metro这样的图书馆的菜单,但这些菜单让我们觉得太简单了.

WPF菜单控件是否足够灵活,可以如上图所示进行样式设置,还是应该从堆栈面板和列表构建自定义菜单控件等其他路径?有什么权衡?

奖金积分(即奖金)将被授予xaml /代码,正是这样做的.

这个菜单样式的一个例子:
https://www.visualstudio.com/

解决方法

WPF的设计真的可以改变每个开箱即用的机制/控件(按钮,菜单,树视图等)的外观和行为.
所以,一般来说,最好这样做而不是重写一切.例如,如果您重新设计自定义菜单,则必须考虑键盘,UI自动化等…

所以,我给你的例子做了一个镜头并尝试构建一个最小的工作样本 – 纯XAML – 模仿VS在线菜单(我还添加了悬浮背景颜色变化,认情况下不在WPF的菜单中).

结果如下,如您所见,它看起来非常相似:

这是XAML.我选择为每个MenuItem使用自定义控件模板.我认为当你需要真正定制每件商品时这是非常实用的.

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="550" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="btv" />

        <!-- style a top level menu item -->
        <ControlTemplate x:Key="VsMenutop" targettype="MenuItem">
            <StackPanel TextBlock.FontSize="15px" Height="40">
                <!-- label,icons,etc. -->
                <Label Content="{TemplateBinding Header}" Margin="5" Foreground="White" />

                <!-- sub items -->
                <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False">
                    <Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0">
                        <StackPanel IsItemsHost="True" />
                    </Border>
                </Popup>
                <StackPanel.Style>
                    <Style targettype="StackPanel">
                        <Style.Triggers>
                            <Trigger Property="IsMouSEOver"  Value="True">
                                <Setter Property="Background" Value="#106EBE" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </StackPanel.Style>
            </StackPanel>
        </ControlTemplate>

        <!-- style a non-top level menu item -->
        <ControlTemplate x:Key="VsMenuSub" targettype="MenuItem">
            <DockPanel TextBlock.FontSize="15px" x:Name="panel">
                <!-- label,etc. -->
                <Image Source="{Binding Icon,RelativeSource={RelativeSource TemplatedParent}}" Width="20" Margin="5,0" />
                <Label Content="{TemplateBinding Header}" Foreground="Black" Margin="0,5,5" />

                <!-- draw the right arrow only if this menu item has sub items -->
                <Image Source="icon_right.png" Visibility="{Binding HasItems,Converter={StaticResource btv},RelativeSource={RelativeSource TemplatedParent}}" />

                <!-- sub items -->
                <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" Placement="Right" >
                    <Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0">
                        <StackPanel IsItemsHost="True" />
                    </Border>
                </Popup>
            </DockPanel>
            <ControlTemplate.Triggers>
                <Trigger Property="IsHighlighted" Value="True">
                    <Setter Property="Background" TargetName="panel" Value="#EFF6FC" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

        <!-- style the separator -->
        <ControlTemplate x:Key="VsMenuSep" targettype="Separator">
            <Border Height="1" Background="#E0E0E0" />
        </ControlTemplate>

        <!-- style the VSOnline -->
        <ControlTemplate x:Key="VsOnline" targettype="MenuItem">
            <StackPanel TextBlock.FontSize="15px" Height="40" Orientation="Horizontal" Background="#005A9E">
                <Label Content="{TemplateBinding Header}" Margin="5" Foreground="White" />
                <Image Source="icon_down.png" Height="20" Margin="0,0" />

                <!-- sub items -->
                <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False">
                    <Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0">
                        <StackPanel IsItemsHost="True" />
                    </Border>
                </Popup>
            </StackPanel>
        </ControlTemplate>

        <!-- some base stuff -->
        <Style targettype="Menu">
            <Setter Property="Background" Value="#0078D7" />
            <Setter Property="Height" Value="40px" />
        </Style>

    </Window.Resources>

    <!-- the real app and real menu -->
    <StackPanel>
        <Menu IsMainMenu="True">
            <MenuItem Header="_VSOnline" Template="{StaticResource VsOnline}" >
                <MenuItem Header="_Whatever" Template="{StaticResource VsMenuSub}" />
            </MenuItem>
            <MenuItem Header="_Dashboards" Template="{StaticResource VsMenutop}">
                <MenuItem Header="_Overview" Template="{StaticResource VsMenuSub}" />
            </MenuItem>
            <MenuItem Header="_Code" Template="{StaticResource VsMenutop}">
                <MenuItem Header="_Files" Template="{StaticResource VsMenuSub}" />
                <MenuItem Header="_Commits" Template="{StaticResource VsMenuSub}" />
                <MenuItem Header="_Pushes" Template="{StaticResource VsMenuSub}" />
            </MenuItem>
            <MenuItem Header="_Work" Template="{StaticResource VsMenutop}">
                <MenuItem Header="_Backlogs" Template="{StaticResource VsMenuSub}" Icon="icon_backlogs.png" />
                <MenuItem Header="_Queries" Template="{StaticResource VsMenuSub}" Icon="icon_queries.png" />
                <Separator Template="{StaticResource VsMenuSep}" />
                <MenuItem Header="_New Work Item" Template="{StaticResource VsMenuSub}">
                    <MenuItem Header="_Epic" Template="{StaticResource VsMenuSub}" Icon="icon_epic.png" />
                    <MenuItem Header="_Feature" Template="{StaticResource VsMenuSub}" Icon="icon_feature.png" />
                    <MenuItem Header="_Issue" Template="{StaticResource VsMenuSub}" Icon="icon_issue.png" />
                    <MenuItem Header="_Task" Template="{StaticResource VsMenuSub}" Icon="icon_task.png" />
                    <MenuItem Header="_Test Case" Template="{StaticResource VsMenuSub}" Icon="icon_testcase.png" />
                    <MenuItem Header="_User Story" Template="{StaticResource VsMenuSub}" Icon="icon_userstory.png" />
                </MenuItem>
                <MenuItem Header="_Bug" Template="{StaticResource VsMenuSub}" Icon="icon_bug.png" />
            </MenuItem>
        </Menu>
    </StackPanel>
</Window>

该项目于here on github年开始实施.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...