修改 WPF Toolkit DropDownButton 样式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21713688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Modify WPF Toolkit DropDownButton style
提问by Flack
I am trying to modify WpfToolkit's DropDownButton style in order to allow me to set the Background color.
我正在尝试修改 WpfToolkit 的 DropDownButton 样式以允许我设置背景颜色。
Here is the default style of the DropDownButton:
这是 DropDownButton 的默认样式:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:chrome="clr-namespace:Xceed.Wpf.Toolkit.Chromes"
xmlns:conv="clr-namespace:Xceed.Wpf.Toolkit.Core.Converters"
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit">
<conv:InverseBoolConverter x:Key="InverseBoolConverter" />
<LinearGradientBrush x:Key="PopupDarkBorderBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0" />
<GradientStop Color="#FF8399A9" Offset="0.375" />
<GradientStop Color="#FF718597" Offset="0.375" />
<GradientStop Color="#FF617584" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="PopupBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0" Color="#FFffffff" />
<GradientStop Offset="1" Color="#FFE8EBED" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style TargetType="{x:Type local:DropDownButton}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DropDownButton}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="True">
<ToggleButton x:Name="PART_DropDownButton"
Grid.Column="1"
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter />
</ControlTemplate>
</ToggleButton.Template>
<Grid>
<chrome:ButtonChrome x:Name="ToggleButtonChrome"
CornerRadius="2.75"
RenderChecked="{TemplateBinding IsOpen}"
RenderEnabled="{TemplateBinding IsEnabled}"
RenderMouseOver="{Binding IsMouseOver, ElementName=PART_DropDownButton}"
RenderPressed="{Binding IsPressed, ElementName=PART_DropDownButton}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="true" />
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Margin="4,3,4,3" Grid.Column="1">
<Path x:Name="Arrow" Width="7" Height="4" Data="M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z" Fill="#FF000000" />
</Grid>
</Grid>
</chrome:ButtonChrome>
</Grid>
</ToggleButton>
<Popup x:Name="PART_Popup"
HorizontalOffset="1"
VerticalOffset="1"
AllowsTransparency="True"
StaysOpen="False"
Placement="Bottom"
Focusable="False"
IsOpen="{Binding IsChecked, ElementName=PART_DropDownButton}">
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource PopupDarkBorderBrush}">
<ContentPresenter x:Name="PART_ContentPresenter" Content="{TemplateBinding DropDownContent}" />
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I am creating the DropDownButton like so:
我正在像这样创建 DropDownButton:
<extToolkit:DropDownButton VerticalAlignment="Center" Background="Red">
<extToolkit:DropDownButton.Content>
<TextBlock>Click me</TextBlock>
</extToolkit:DropDownButton.Content>
<extToolkit:DropDownButton.DropDownContent>
<TextBlock>Popup</TextBlock>
</extToolkit:DropDownButton.DropDownContent>
</extToolkit:DropDownButton>
I set the Background to Red but that doesn't have any impact. So I tried to set the Background of the DropDownButton's style to bind to the Background I set:
我将背景设置为红色,但这没有任何影响。因此,我尝试将 DropDownButton 样式的背景设置为绑定到我设置的背景:
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="true" />
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Margin="4,3,4,3" Grid.Column="1">
<Path x:Name="Arrow" Width="7" Height="4" Data="M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z" Fill="#FF000000" />
</Grid>
</Grid>
But that didn't change the background color, no matter what I set in my control. If I set the Background color directly in the style (no binding), then the color takes affect but for some reason the CornerRadius defined on ButtonChrome disappears and the button reverts to a rectangle.
但这并没有改变背景颜色,无论我在控件中设置什么。如果我直接在样式中设置背景颜色(无绑定),则颜色会生效,但由于某种原因,ButtonChrome 上定义的 CornerRadius 消失,按钮恢复为矩形。
Any suggestions? I just want to be able to set the background of the drop down button and the PART_Popup when defining the control.
有什么建议?我只是希望能够在定义控件时设置下拉按钮和 PART_Popup 的背景。
回答by Anatoliy Nikolaev
It seems that ButtonChromecan not set an arbitrary Background color without losing the CornerRadius property. If you do not like it, then you need to look for an alternative, as an alternative, I have used ToggleButtonfor this:
似乎ButtonChrome无法在不丢失 CornerRadius 属性的情况下设置任意背景颜色。如果您不喜欢它,那么您需要寻找替代方案,作为替代方案,我已经用于ToggleButton此:
<ToggleButton x:Name="ToggleButtonChrome"
Background="{TemplateBinding Background}"
IsEnabled="{TemplateBinding IsEnabled}"
IsChecked="{Binding IsOpen, ElementName=PART_Popup}">
but I have a icon Button stands in the middle, for me no methods do not get rid of it, so I'm in Contentproperty compensated by its spaces:
但我有一个图标 Button 站在中间,对我来说没有方法不能摆脱它,所以我的Content财产补偿了它的空间:
Content=" Click me "
To set the Backgroundfor Popup, I created an attacheddependency property Background, which is in PropertyExtension namespace:
为了设置Backgroundfor Popup,我创建了一个附加的依赖属性 Background,它在 PropertyExtension 命名空间中:
public static class Popup
{
#region Popup Background Property
public static readonly DependencyProperty BackgroundProperty;
public static void SetBackground(DependencyObject DepObject, Brush value)
{
DepObject.SetValue(BackgroundProperty, value);
}
public static Brush GetBackground(DependencyObject DepObject)
{
return (Brush)DepObject.GetValue(BackgroundProperty);
}
#endregion
static Popup()
{
#region Popup Background Registration
PropertyMetadata BrushPropertyMetadata = new PropertyMetadata(Brushes.Transparent);
BackgroundProperty = DependencyProperty.RegisterAttached("Background",
typeof(Brush),
typeof(Popup),
BrushPropertyMetadata);
#endregion
}
}
And set in the ControlTemplateas follows:
并设置ControlTemplate如下:
<Popup x:Name="PART_Popup"
IsOpen="{Binding IsChecked, ElementName=PART_DropDownButton}"
...>
<Border BorderThickness="1"
Background="{TemplateBinding PropertyExtension:Popup.Background}"> <!-- Here -->
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding DropDownContent}" />
</Border>
</Popup>
Example of using:
使用示例:
<Grid>
<wpfx:DropDownButton PropertyExtension:Popup.Background="{StaticResource PopupBackground}"
Content=" Click me "
HorizontalContentAlignment="Left"
Background="CadetBlue"
Width="80"
Height="30" >
<wpfx:DropDownButton.DropDownContent>
<TextBlock Width="100"
Height="100"
Text="Popup" />
</wpfx:DropDownButton.DropDownContent>
</wpfx:DropDownButton>
</Grid>
The initial state:
初始状态:


The final state:
最终状态:


The whole project is available on this
link.
整个项目都可以在此获得
link。
Below a full example:
下面是一个完整的例子:
<Window.Resources>
<wpfx:InverseBoolConverter x:Key="InverseBoolConverter" />
<SolidColorBrush x:Key="PopupBackground" Color="Beige" />
<Style TargetType="{x:Type wpfx:DropDownButton}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type wpfx:DropDownButton}">
<Grid x:Name="MainGrid"
SnapsToDevicePixels="True">
<ToggleButton x:Name="PART_DropDownButton"
Grid.Column="1"
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter />
</ControlTemplate>
</ToggleButton.Template>
<Grid>
<ToggleButton x:Name="ToggleButtonChrome"
Background="{TemplateBinding Background}"
IsEnabled="{TemplateBinding IsEnabled}"
IsChecked="{Binding IsOpen, ElementName=PART_Popup}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True" />
<Grid x:Name="arrowGlyph"
IsHitTestVisible="False"
Margin="4,3,4,3"
Grid.Column="1">
<Path x:Name="Arrow"
Width="7"
Height="4"
Data="M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z"
Fill="#FF000000" />
</Grid>
</Grid>
</ToggleButton>
</Grid>
</ToggleButton>
<Popup x:Name="PART_Popup"
IsOpen="{Binding IsChecked, ElementName=PART_DropDownButton}"
HorizontalOffset="1"
VerticalOffset="1"
AllowsTransparency="True"
StaysOpen="False"
Placement="Bottom"
Focusable="False">
<Border BorderThickness="1"
Background="{TemplateBinding PropertyExtension:Popup.Background}">
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding DropDownContent}" />
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Fill" TargetName="Arrow" Value="#AFAFAF" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<wpfx:DropDownButton PropertyExtension:Popup.Background="{StaticResource PopupBackground}"
Content=" Click me "
HorizontalContentAlignment="Left"
Background="CadetBlue"
Width="80"
Height="30" >
<wpfx:DropDownButton.DropDownContent>
<TextBlock Width="100"
Height="100"
Text="Popup" />
</wpfx:DropDownButton.DropDownContent>
</wpfx:DropDownButton>
</Grid>

