【问题标题】:Modify WPF Toolkit DropDownButton style修改 WPF 工具包 DropDownButton 样式
【发布时间】:2014-02-11 21:44:29
【问题描述】:

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

【问题讨论】:

    标签: c# wpf wpftoolkit


    【解决方案1】:

    似乎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,我创建了一个 attached 依赖属性 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>
    

    初始状态:

    最终状态:

    整个项目都可以在这个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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-19
      • 2014-07-02
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      相关资源
      最近更新 更多