zoukankan      html  css  js  c++  java
  • WPF下的RibbonApplicationMenu控件自定义

    .Net Framework 4.5和.Net Core开始提供类似Office界面风格的控件。没事想抄个Windows自带的画图玩玩,Ribbon窗口往一套,倒也简单,只是细节方面有些不同,最明显的就是主菜单部分,画图里是扁平的形状,并且内容是用的文本。然而RibbonApplicationMenu去没有提供这样的选项,只能使用图片,而且没有地方可以设置。如果想做得跟画图一样,那就要定制这个菜单了。好在Xaml的机制下可以比较灵活地修改内容模板。以下就说说修改的过程。

    定制WPF控件有两种方法,一种是通过继承,另一种是就是新建内容模板。前一种一般是要增加控件的新功能,后一种只是为了修改显式样式。这里只是为了修改显示样式,所以选择后一种就行了。

    开始之前,先了解一下Ribbon窗口的结构。

    Ribbon

    从图中可以看出,这是一个复合控件。如果是简单控件,直接重给控件内容就行了,比如自定义一个圆形按钮,

    <ControlTemplate x:Key="roundbutton" TargetType="Button">
        <Grid>
            <Ellipse x:Name="backgroundElement" Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}" />
            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
    </ControlTemplate>
    

    但如果重绘一个复合控件,只是这么简单的绘制的话,会发现控件不可用了,比如一个ComboBox控件,它实际上包含一个Textbox、一个ToggleButton、一个弹出窗口以及菜单项的模板。这些子控件称为Parts,每个part有一个名称,在呈现控件树的时候使用。

    ComboBox 有两个part
    PART_EditableTextBox ComboBox的文本内容.
    PART_Popup Popup 下拉弹出窗口.

    同样,RibbonApplicationMenu也有5个part,分别是
    PART_PopupToggleButton 默认按扭,类型为RibbonToggleButton
    PART_Popup 下拉框,类型为Popup
    PART_SubmenuPlaceholder 子菜单容器,类型为一个容器,比如StackPanel
    PART_FooterPaneContentPresenter 底部内容,类型为ContentPresenter
    PART_AuxiliaryPaneContentPresenter 右侧内容,类型为ContentPresenter

    我们定义这个按钮:

    <RibbonToggleButton x:Name="PART_ToggleButton" ClickMode="Release" Label="文件" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Foreground="White" Background="#FF3E3EC7" Focusable="False" IsTabStop="False" FocusedBackground="#FF6161F7" CornerRadius="0,0,0,0" MouseOverBackground="#FF6161F7" MouseOverBorderBrush="#FF6161F7"/>
    

    这里需要注意的两个属性,一个是ClickMode,要设置成Release,否则因为绑定的原因不能正常触发,将CornerRadius设置成"0,0,0,0",默认是“2,2,2,2”。

    有了按钮后,还只能触发IsDropDownOpen属性的变化,接下来就要根据这个属性来触发弹框了。我们要定义一个Popup.

    <Popup x:Name="PART_Popup" IsOpen="{TemplateBinding IsDropDownOpen}" PopupAnimation="Slide" Placement="Relative">
    </Popup>
    

    有了这个Popup,点击蓝色的按钮就看一个弹出的小框框。接下来完善一下其它部分的内容:

    <Popup x:Name="PART_Popup" IsOpen="{TemplateBinding IsDropDownOpen}" PopupAnimation="Slide" Placement="Relative" Width="450">
                                        <Border Background="#FFE6E6E6" BorderBrush="#FF5EADCB" BorderThickness="1,1,1,1">
                                            <Grid MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxHeight}">
                                                <Grid.RowDefinitions>
                                                    <RowDefinition/>
                                                    <RowDefinition/>
                                                    <RowDefinition/>
                                                </Grid.RowDefinitions>
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition/>
                                                    <ColumnDefinition/>
                                                </Grid.ColumnDefinitions>
                                                <Border Grid.Row="1" Width="150">
                                                    <StackPanel  IsItemsHost="True"/>
                                                </Border>
                                                <Border Grid.Row="1" Grid.Column="1" BorderBrush="Gray" Width="150">
                                                    <ContentPresenter x:Name="PART_AuxiliaryPaneContentPresenter"  ContentTemplateSelector="{TemplateBinding AuxiliaryPaneContentTemplateSelector}" Content="{TemplateBinding AuxiliaryPaneContent}" ContentTemplate="{TemplateBinding AuxiliaryPaneContentTemplate}"/>
                                                </Border>
                                                <Border Grid.Row="2" Grid.ColumnSpan="2" Height="30">
                                                    <ContentPresenter x:Name="PART_FooterPaneContentPresenter"  Content="{TemplateBinding FooterPaneContent}" ContentTemplate="{TemplateBinding FooterPaneContentTemplate}" ContentTemplateSelector="{TemplateBinding FooterPaneContentTemplateSelector}"/>
                                                </Border>
                                                <RibbonToggleButton x:Name="PART_PopupToggleButton" ClickMode="Release" Label="文件" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Foreground="White" Background="#FF3E3EC7" Focusable="False" IsTabStop="False" IsHitTestVisible="True" HorizontalAlignment="Left" VerticalAlignment="Center" Height="{Binding ActualHeight, ElementName=PART_ToggleButton, Mode=OneWay}" Width="{Binding ActualWidth, ElementName=PART_ToggleButton, Mode=OneWay}" FocusedBackground="#FF6161F7" CornerRadius="0,0,0,0" MouseOverBackground="#FF6161F7" MouseOverBorderBrush="#FF6161F7" />
    
                                            </Grid>
                                        </Border>
                                    </Popup>
    

    这个代码中多了一个RibbonToggleButton,画图程序菜单里有这么一个按钮,这个也是RibbonApplicationMenu的一个Part,实际是继承了RibbonMenuButton的内容,画图里将这个按钮显示在了最上方,如果没这个按钮,主菜单按钮会被挡在下边,为了保持外观的一至性,在弹出框再放一个相同的按钮。同样的,Windows资源管理器也是相同的设计。

    整个模板的实现代码如下:

    <ControlTemplate TargetType="RibbonApplicationMenu">
                                <Grid>
                                    <Popup x:Name="PART_Popup" IsOpen="{TemplateBinding IsDropDownOpen}" PopupAnimation="Slide" Placement="Relative" Width="450">
                                        <Border Background="#FFE6E6E6" BorderBrush="#FF5EADCB" BorderThickness="1,1,1,1">
                                            <Grid MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxHeight}">
                                                <Grid.RowDefinitions>
                                                    <RowDefinition/>
                                                    <RowDefinition/>
                                                    <RowDefinition/>
                                                </Grid.RowDefinitions>
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition/>
                                                    <ColumnDefinition/>
                                                </Grid.ColumnDefinitions>
                                                <Border Grid.Row="1" Width="150">
                                                    <StackPanel  IsItemsHost="True"/>
                                                </Border>
                                                <Border Grid.Row="1" Grid.Column="1" BorderBrush="Gray" Width="150">
                                                    <ContentPresenter x:Name="PART_AuxiliaryPaneContentPresenter"  ContentTemplateSelector="{TemplateBinding AuxiliaryPaneContentTemplateSelector}" Content="{TemplateBinding AuxiliaryPaneContent}" ContentTemplate="{TemplateBinding AuxiliaryPaneContentTemplate}"/>
                                                </Border>
                                                <Border Grid.Row="2" Grid.ColumnSpan="2" Height="30">
                                                    <ContentPresenter x:Name="PART_FooterPaneContentPresenter"  Content="{TemplateBinding FooterPaneContent}" ContentTemplate="{TemplateBinding FooterPaneContentTemplate}" ContentTemplateSelector="{TemplateBinding FooterPaneContentTemplateSelector}"/>
                                                </Border>
                                                <RibbonToggleButton x:Name="PART_PopupToggleButton" ClickMode="Release" Label="文件" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Foreground="White" Background="#FF3E3EC7" Focusable="False" IsTabStop="False" IsHitTestVisible="True" HorizontalAlignment="Left" VerticalAlignment="Center" Height="{Binding ActualHeight, ElementName=PART_ToggleButton, Mode=OneWay}" Width="{Binding ActualWidth, ElementName=PART_ToggleButton, Mode=OneWay}" FocusedBackground="#FF6161F7" CornerRadius="0,0,0,0" MouseOverBackground="#FF6161F7" MouseOverBorderBrush="#FF6161F7" />
    
                                            </Grid>
                                        </Border>
                                    </Popup>
                                    <RibbonToggleButton x:Name="PART_ToggleButton" ClickMode="Release" Label="文件" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Foreground="White" Background="#FF3E3EC7" Focusable="False" IsTabStop="False" FocusedBackground="#FF6161F7" CornerRadius="0,0,0,0" MouseOverBackground="#FF6161F7" MouseOverBorderBrush="#FF6161F7"/>
    
    
                                </Grid>
    
                            </ControlTemplate>
    
  • 相关阅读:
    【机器学习】聚类算法:层次聚类
    【机器学习】聚类算法:层次聚类、K-means聚类
    【机器学习】聚类算法:层次聚类、K-means聚类
    【机器学习】聚类算法:ISODATA算法
    【机器学习】聚类算法:ISODATA算法
    【机器学习】【数字信号处理】矢量量化(Vector Quantization)
    【机器学习】【数字信号处理】矢量量化(Vector Quantization)
    【嵌入式开发】Raspberry Pi 树莓派性能测试
    【嵌入式开发】用 VLC 显示 树莓派摄像头 H264 裸流
    【嵌入式开发】用 VLC 显示 树莓派摄像头 H264 裸流
  • 原文地址:https://www.cnblogs.com/icoolno1/p/12824353.html
Copyright © 2011-2022 走看看