如何自定义 WPF Ribbon 4.5(样式、模板等)
Posted
技术标签:
【中文标题】如何自定义 WPF Ribbon 4.5(样式、模板等)【英文标题】:How to customize the WPF Ribbon 4.5 (styles, templates, etc.) 【发布时间】:2013-07-03 12:13:10 【问题描述】:我尝试从 .Net Framework 4.5 中自定义 System.Windows.Controls.Ribbon,以便它可以与 Expression Dark 主题(如 Blend 的默认主题中的深色)一起使用。 我尝试了以下想法,但到目前为止没有任何进展:
更改功能区的背景:将仅更改主 颜色,但保留所有其他光泽颜色、突出颜色等。 更改样式和模板:我找不到任何默认模板 功能区 4.5。我试图通过 ShowMeTheTemplate 等工具获取它们, 但似乎他们使用了一些内部类。 使用 Blend for VS2012 自定义模板:我总是收到错误消息“复制模板失败。” 使用 RibbonControlLibrary 中的 .net 4 功能区:RibbonWindow 在 Windows 8 中看起来很难看(请参阅 WPF RibbonWindow + Windows 8 - control box looks bad),我无法解决任何帮助将不胜感激,欢迎所有建议。
【问题讨论】:
【参考方案1】:您可以通过在功能区上设置属性来更改几种颜色:
<ribbon:Ribbon x:Name="Ribbon"
Background="Khaki"
BorderBrush="Brown"
MouseOverBackground="LightCoral"
MouseOverBorderBrush="Coral"
PressedBackground="LightGreen"
PressedBorderBrush="Green"
CheckedBackground="LightBlue"
CheckedBorderBrush="Blue"
FocusedBackground="LightSlateGray"
FocusedBorderBrush="SlateBlue">
不完全是一个好看的例子,但展示了如何做到这一点。
也有兴趣如何进行完整的重新造型...
【讨论】:
比没有好;-)【参考方案2】:我能够使用Show me the templates 提取一个完全正常工作的模板。为此,我对其进行了修改以从“System.Windows.Controls.Ribbon”(而不是主框架程序集)中提取模板。
它给了我以下信息:
https://gist.github.com/drayde/75526b570a266f5f8f38(此处粘贴太长)
只需将其添加到您的资源中并像这样使用它:
<Ribbon Template="StaticResource ribbonTemplate">
...
</Ribbon>
通过修改模板,您应该可以完全控制功能区的显示方式。
【讨论】:
在功能区设置为最小化的情况下使用此模板,单击菜单项不会展开功能区...【参考方案3】:我关注this answer 从 VS 获取模板。
它以与 OP 描述的方式相似的方式失败。
然后我使用@Andreas 的要点修补了缺失的部分Binding (0)
。
为了进行测试,我将视图中的所有颜色属性设置为黑色,并在新创建的模板中设置为 50% 的洋红色。
大约这一次我准备放弃System.Controls.Windows.Ribbon
并尝试Fluent.Ribbon...
模板:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic"
xmlns:swcrp="clr-namespace:System.Windows.Controls.Ribbon.Primitives;assembly=System.Windows.Controls.Ribbon"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<!-- Template Colors -->
<SolidColorBrush x:Key="GroupsInnerBorderBrush" Color="#60FFFFFF"/>
<SolidColorBrush x:Key="QatTopHostBorderBrush1" Color="#66CCCCCC"/>
<SolidColorBrush x:Key="QatTopHostBorderBrush2" Color="#77222222"/>
<SolidColorBrush x:Key="QatTopHostBorderBrush3" Color="#81444444"/>
<SolidColorBrush x:Key="QatTopHostBorderBrush4" Color="#69EEEEEE"/>
<!-- #71000000 -->
<s:Byte x:Key="r">#00</s:Byte>
<s:Byte x:Key="g">#00</s:Byte>
<s:Byte x:Key="b">#00</s:Byte>
<s:Byte x:Key="a">#71</s:Byte>
<Color x:Key="DropShadowColor" R="StaticResource r" G="StaticResource g" B="StaticResource b" A="StaticResource a"/>
<LinearGradientBrush x:Key="GroupsBorderBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#EEFFFFFF" Offset="0"/>
<GradientStop Color="#BBFFFFFF" Offset="0.1"/>
<GradientStop Color="#05FFFFFF" Offset="0.5"/>
<GradientStop Color="#20FFFFFF" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="TitleBarBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#EEFFFFFF" Offset="0"/>
<GradientStop Color="#BBFFFFFF" Offset="0.1"/>
<GradientStop Color="#05FFFFFF" Offset="0.5"/>
<GradientStop Color="#20FFFFFF" Offset="1"/>
</LinearGradientBrush>
<!-- Template -->
<ControlTemplate x:Key="RibbonTemplate" TargetType="x:Type Ribbon">
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border x:Name="BackgroundBorder" Grid.ColumnSpan="3" Grid.Row="1" Grid.RowSpan="3"
BorderBrush="TemplateBinding BorderBrush"
Background="TemplateBinding Background"/>
<Border Grid.ColumnSpan="3" Grid.Row="1">
<Popup x:Name="PART_ITEMSPRESENTERPOPUP" AllowsTransparency="True"
IsOpen="Binding IsDropDownOpen, RelativeSource=RelativeSource TemplatedParent"
PopupAnimation="DynamicResource x:Static SystemParameters.MenuPopupAnimationKey">
<mwt:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" RenderOptions.ClearTypeHint="Enabled"
FocusVisualStyle="x:Null" Focusable="True" Margin="0,0,5,5">
<Border x:Name="CollapsedPopupBackgroundBorder" Background="TemplateBinding Background">
<ContentControl x:Name="popupItemsPresenterHost" KeyboardNavigation.DirectionalNavigation="Cycle"
Focusable="False" Margin="0,1,0,0" KeyboardNavigation.TabNavigation="Cycle"/>
</Border>
</mwt:SystemDropShadowChrome>
</Popup>
</Border>
<ContentControl x:Name="mainItemsPresenterHost" Grid.ColumnSpan="3" Focusable="False" Grid.Row="2">
<Border x:Name="groupsBorder" BorderThickness="1,0,1,1" Height="91" SnapsToDevicePixels="True"
BorderBrush="TemplateBinding BorderBrush"
Background="StaticResource GroupsBorderBackgroundBrush">
<Border BorderThickness="0,0,0,1" Margin="0,0,0,1" SnapsToDevicePixels="True"
BorderBrush="StaticResource GroupsInnerBorderBrush">
<ItemsPresenter x:Name="ItemsPresenter"/>
</Border>
</Border>
</ContentControl>
<Border x:Name="QatBottomHost" Grid.ColumnSpan="3" Grid.Row="3" BorderBrush="TemplateBinding BorderBrush">
<ContentPresenter x:Name="QatBottomHostContentPresenter" IsHitTestVisible="True"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Border>
<Border x:Name="titleBarBackground" BorderThickness="0,0,0,1" Grid.ColumnSpan="3" Visibility="Collapsed"
BorderBrush="TemplateBinding BorderBrush"
Background="StaticResource TitleBarBackgroundBrush"/>
<DockPanel Grid.ColumnSpan="3" Grid.Column="0" Height="22" LastChildFill="True">
<ContentControl x:Name="windowButtonPlaceHolder" DockPanel.Dock="Right" Focusable="False"
IsHitTestVisible="False" Margin="3,0,0,0" Width="35">
<ContentControl.Visibility>
<TemplateBinding Property="IsHostedInRibbonWindow">
<TemplateBindingExtension.Converter>
<BooleanToVisibilityConverter />
</TemplateBindingExtension.Converter>
</TemplateBinding>
</ContentControl.Visibility>
</ContentControl>
<ContentControl x:Name="windowIconPadding" DockPanel.Dock="Left" Focusable="False"
IsHitTestVisible="False" Margin="0,0,3,0" Width="16"/>
<swcrp:RibbonTitlePanel x:Name="PART_TitlePanel">
<Grid x:Name="QatTopHost">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border x:Name="QatTopHostLeftBorder" BorderBrush="StaticResource QatTopHostBorderBrush1"
BorderThickness="1,0,1,0.9" Background="StaticResource QatTopHostBorderBrush2" Grid.Column="0"
CornerRadius="0,0,2,2" Margin="8,2,0,2" Width="3"/>
<ContentPresenter x:Name="QatTopHostContentPresenter" Grid.Column="1" IsHitTestVisible="True"
Content="TemplateBinding QuickAccessToolBar"/>
<Border x:Name="QatTopHostRightBorder" BorderBrush="StaticResource QatTopHostBorderBrush1"
BorderThickness="1,0,1,0.9" Background="StaticResource QatTopHostBorderBrush2" Grid.Column="2"
CornerRadius="0,0,2,2" Margin="0,2,1,2" Width="3"/>
</Grid>
<ContentPresenter x:Name="PART_TitleHost" ContentTemplate="TemplateBinding TitleTemplate"
Content="TemplateBinding Title" ContentSource="Title"
TextElement.Foreground="DynamicResource x:Static SystemColors.ActiveCaptionTextBrushKey"
TextElement.FontWeight="DynamicResource x:Static SystemFonts.CaptionFontWeightKey"
TextElement.FontSize="DynamicResource x:Static SystemFonts.CaptionFontSizeKey"
TextElement.FontFamily="DynamicResource x:Static SystemFonts.CaptionFontFamilyKey"
HorizontalAlignment="TemplateBinding HorizontalContentAlignment"
IsHitTestVisible="False" Margin="3,0" MinWidth="75" MinHeight="22">
<ContentPresenter.Resources>
<DataTemplate x:Key="DataTemplateKey DataType=x:Type s:String" DataType="x:Type s:String">
<TextBlock x:Name="titleTextBlock" HorizontalAlignment="TemplateBinding HorizontalAlignment"
Margin="0,-2,0,0" Text="TemplateBinding Content" TextTrimming="CharacterEllipsis"/>
<DataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding Path=(SystemParameters.IsGlassEnabled)" Value="True"/>
<Condition Binding="Binding IsHostedInRibbonWindow, RelativeSource=RelativeSource FindAncestor,
AncestorLevel=1, AncestorType=x:Type Ribbon" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Effect" TargetName="titleTextBlock">
<Setter.Value>
<DropShadowEffect BlurRadius="5" Color="White" ShadowDepth="0"/>
</Setter.Value>
</Setter>
</MultiDataTrigger>
<DataTrigger Binding="Binding Path=(SystemParameters.IsGlassEnabled)" Value="False">
<Setter Property="Margin" TargetName="titleTextBlock" Value="0"/>
<Setter Property="VerticalAlignment" TargetName="titleTextBlock" Value="Center"/>
</DataTrigger>
<DataTrigger Binding="Binding Path=(SystemParameters.HighContrast)" Value="True">
<Setter Property="Margin" TargetName="titleTextBlock" Value="0,1,0,0"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding Path=(SystemParameters.UxThemeName)" Value="AeroLite"/>
<Condition Binding="Binding Path=(SystemParameters.IsGlassEnabled)" Value="False"/>
<Condition Binding="Binding IsHostedInRibbonWindow, RelativeSource=RelativeSource FindAncestor,
AncestorLevel=1, AncestorType=x:Type Ribbon" Value="True"/>
<Condition Binding="Binding WindowState, RelativeSource=RelativeSource FindAncestor,
AncestorLevel=1, AncestorType=x:Type RibbonWindow" Value="Normal"/>
</MultiDataTrigger.Conditions>
<Setter Property="Margin" TargetName="titleTextBlock" Value="0,0,0,7"/>
</MultiDataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
<RibbonContextualTabGroupItemsControl x:Name="PART_ContextualTabGroupItemsControl"
HorizontalAlignment="Center" IsHitTestVisible="True"
WindowChrome.IsHitTestVisibleInChrome="True"/>
</swcrp:RibbonTitlePanel>
</DockPanel>
<ContentPresenter x:Name="applicationMenu" Content="TemplateBinding ApplicationMenu" Grid.Row="1" VerticalAlignment="Top"/>
<RibbonTabHeaderItemsControl x:Name="TabHeaderItemsControl" Grid.Column="1"
HorizontalAlignment="Left" Margin="1,1,1,0" Grid.Row="1" VerticalAlignment="Top"/>
<ContentPresenter x:Name="PART_HelpPane" ContentTemplate="TemplateBinding HelpPaneContentTemplate"
Content="TemplateBinding HelpPaneContent" Grid.Column="2" ContentSource="HelpPaneContent"
HorizontalAlignment="Right" Grid.Row="1" VerticalAlignment="Top"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsCollapsed" Value="True">
<Setter Property="Visibility" TargetName="applicationMenu" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="QatBottomHost" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="QatTopHost" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="mainItemsPresenterHost" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="TabHeaderItemsControl" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="PART_HelpPane" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="PART_ContextualTabGroupItemsControl" Value="Collapsed"/>
<Setter Property="MinWidth" TargetName="PART_TitleHost" Value="0"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsCollapsed" Value="True"/>
<Condition Property="IsHostedInRibbonWindow" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed"/>
</MultiTrigger>
<Trigger Property="ShowQuickAccessToolBarOnTop" Value="False">
<Setter Property="Content" TargetName="QatTopHostContentPresenter" Value="x:Null"/>
<Setter Property="Visibility" TargetName="QatTopHost" Value="Collapsed"/>
<Setter Property="Content" TargetName="QatBottomHostContentPresenter"
Value="Binding QuickAccessToolBar, RelativeSource=RelativeSource TemplatedParent"/>
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0,0,0,1"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding QuickAccessToolBar.HasItems, RelativeSource=RelativeSource Self" Value="False"/>
<Condition Binding="Binding QuickAccessToolBar.CustomizeMenuButton, RelativeSource=RelativeSource Self" Value="x:Null"/>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" TargetName="QatTopHost" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="QatBottomHost" Value="Collapsed"/>
</MultiDataTrigger>
<Trigger Property="IsMinimized" Value="True">
<Setter Property="Content" TargetName="mainItemsPresenterHost" Value="x:Null"/>
<Setter Property="Visibility" TargetName="mainItemsPresenterHost" Value="Collapsed"/>
<Setter Property="Content" TargetName="popupItemsPresenterHost" Value="Binding ElementName=groupsBorder"/>
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0,0,0,1"/>
</Trigger>
<Trigger Property="WindowIconVisibility" Value="Collapsed">
<Setter Property="Visibility" TargetName="windowIconPadding" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="QatTopHostLeftBorder" Value="Collapsed"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMinimized" Value="True"/>
<Condition Property="ShowQuickAccessToolBarOnTop" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="BorderThickness" TargetName="QatBottomHost" Value="0,1,0,0"/>
</MultiTrigger>
<Trigger Property="IsHostedInRibbonWindow" Value="False">
<Setter Property="Grid.Row" TargetName="BackgroundBorder" Value="0"/>
<Setter Property="Grid.RowSpan" TargetName="BackgroundBorder" Value="4"/>
<Setter Property="Visibility" TargetName="titleBarBackground" Value="Visible"/>
<Setter Property="Visibility" TargetName="windowIconPadding" Value="Collapsed"/>
<Setter Property="Visibility" TargetName="QatTopHostLeftBorder" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="True">
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0"/>
</Trigger>
<Trigger Property="HasDropShadow" SourceName="PART_ITEMSPRESENTERPOPUP" Value="True">
<Setter Property="Color" TargetName="Shdw" Value="StaticResource DropShadowColor"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding IsActive, RelativeSource=RelativeSource FindAncestor,
AncestorLevel=1, AncestorType=x:Type RibbonWindow" Value="False"/>
<Condition Binding="Binding Path=(SystemParameters.IsGlassEnabled)" Value="False"/>
<Condition Binding="Binding IsHostedInRibbonWindow, RelativeSource=RelativeSource Self" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="TextElement.Foreground" TargetName="PART_TitleHost"
Value="DynamicResource x:Static SystemColors.InactiveCaptionTextBrushKey"/>
</MultiDataTrigger>
<DataTrigger Binding="Binding Path=(SystemParameters.UxThemeName)" Value="Aero">
<Setter Property="Margin" TargetName="QatTopHost" Value="0,-3,0,0"/>
<Setter Property="Margin" TargetName="QatTopHostLeftBorder" Value="3,3,0,5"/>
<Setter Property="Background" TargetName="QatTopHostLeftBorder" Value="StaticResource QatTopHostBorderBrush3"/>
<Setter Property="BorderBrush" TargetName="QatTopHostLeftBorder" Value="StaticResource QatTopHostBorderBrush4"/>
<Setter Property="Margin" TargetName="QatTopHostRightBorder" Value="0,3,1,5"/>
<Setter Property="Background" TargetName="QatTopHostRightBorder" Value="StaticResource QatTopHostBorderBrush3"/>
<Setter Property="BorderBrush" TargetName="QatTopHostRightBorder" Value="StaticResource QatTopHostBorderBrush4"/>
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="Binding Path=(SystemParameters.UxThemeName)" Value="Aero"/>
<Condition Binding="Binding WindowState, RelativeSource=RelativeSource FindAncestor,
AncestorLevel=1, AncestorType=x:Type RibbonWindow" Value="Maximized"/>
</MultiDataTrigger.Conditions>
<Setter Property="Margin" TargetName="QatTopHost" Value="0"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
【讨论】:
以上是关于如何自定义 WPF Ribbon 4.5(样式、模板等)的主要内容,如果未能解决你的问题,请参考以下文章
如何在不覆盖现有样式的情况下向 WPF 自定义控件添加触发器?
WPF中自定义标题栏时窗体最大化处理之WindowChrome
WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享