修改WPF Toolkit DropDownButton样式

时间:2014-02-11 21:44:29

标签: c# wpf wpftoolkit

我正在尝试修改WpfToolkit的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>

我正在创建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>

我将背景设置为红色,但这并没有任何影响。所以我尝试将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>

但无论我在控制中设置什么,这都没有改变背景颜色。如果我直接在样式中设置背景颜色(无绑定),则颜色会生效,但由于某种原因,ButtonChrome上定义的CornerRadius会消失,按钮会恢复为矩形。

有什么建议吗?我只是希望能够在定义控件时设置下拉按钮和PART_Popup的背景。

1 个答案:

答案 0 :(得分:2)

ButtonChrome似乎无法在不丢失CornerRadius属性的情况下设置任意背景色。如果您不喜欢它,那么您需要寻找替代方案,作为替代方案,我使用了ToggleButton

<ToggleButton x:Name="ToggleButtonChrome"
              Background="{TemplateBinding Background}"
              IsEnabled="{TemplateBinding IsEnabled}"
              IsChecked="{Binding IsOpen, ElementName=PART_Popup}">

但我有一个图标Button位于中间,对我来说没有方法可以摆脱它,所以我在Content属性补偿它的空格:

Content=" Click me         " 

要为Popup设置Background,我创建了一个附加依赖项属性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
    }
}

并在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>

使用示例:

<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>

初始状态:

enter image description here

最终状态:

enter image description here

  

整个项目可在此link上找到。

下面是一个完整的例子:

<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>