如何在WPF中基于另一个构建按钮样式

时间:2015-10-31 22:25:40

标签: wpf xaml wpf-controls

我是WPF的新手,通过快速教程,我成功获得了如下个性化按钮样式:

<Style x:Key="ButtonFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Border>
                    <Rectangle Margin="2" StrokeThickness="1" Stroke="#60000000" StrokeDashArray="1 2"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<SolidColorBrush x:Key="NormalBrush" Color="#FF0C0C13"/>
<SolidColorBrush x:Key="LightBrush" Color="#FF2E2E3E"/>
<SolidColorBrush x:Key="PressedBrush" Color="#FF209FD4"/>

<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#FF494968" />
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#FF2E2E3E" />

<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />
<SolidColorBrush x:Key="HorizontalNormalBrush" Color="AntiqueWhite"/>
<SolidColorBrush x:Key="HorizontalLightBrush" Color="AntiqueWhite"/>
<SolidColorBrush x:Key="DarkBrush" Color="AntiqueWhite"/>

<SolidColorBrush x:Key="NormalBorderBrush" Color="Aqua"/>
<Style x:Key="MyButtonStyle" TargetType="Button">
    <Setter Property="SnapsToDevicePixels" Value="true"/>
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border x:Name="Border"  BorderThickness="1" Background="{StaticResource NormalBrush}" BorderBrush="#FF2E2E3E">
                    <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource LightBrush}" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
                        <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我们确实需要覆盖ControlTemplate并保留一些功能(比如悬停鼠标时的行为)我们需要定义它们。我在这里已经很奇怪的是,在ControlTemplate下,它被定义为Border标记,然后触发器引用Border。所以,作为第一个问题,为什么Border而不是其他?

但现在主要问题是:假设我想要完全相同的按钮,具有相同的颜色和功能但没有边框。我尝试使用类似于以下内容的BasedOn:

<Style x:Key="MyButtonStyleNoBorder" TargetType="{x:Type Button}"  BasedOn="{StaticResource MyButtonStyle}">
    <Setter Property="BorderThickness" Value="0"/>
</Style>

但没办法。我发现的唯一解决方案是复制MyButtonStyle的整个代码,然后只更改一个字符(!)以BorderThickness="0"。但这对我来说看起来很愚蠢。你能帮忙吗?

2 个答案:

答案 0 :(得分:1)

  

所以作为第一个问题,为什么选择Border而不是别的什么?

名为Border的元素是最外层的元素,它的子元素将继承其大部分状态,在本例中为背景。

  

但现在主要问题是:假设我想要完全相同的按钮,具有相同的颜色和功能但没有边框。

如果你喜欢没有边框的按钮,你可以直接将按钮的BorderThickness属性设置为0.或者作为样式中的setter。

  

我找到的唯一解决方案是复制MyButtonStyle的整个代码,然后只更改一个字符(!)以使BorderThickness =&#34; 0&#34;。但这对我来说看起来很愚蠢。你能帮忙吗?

样式是一种列表,用于指定要在目标上更改的属性。 basedOn功能将使用basedOn-style和&#34; add&#34;来自新风格的新二传手。

模板更像是控件的绘图(以及一些图形行为),当您指定一个新模板时,您只需丢弃旧模板。我有可能在那里做一个基础。我们如何确定使用什么以及替换什么?

不是你想要的答案,但希望你还是得到了它。

<Border x:Name="Border"  BorderThickness="{TemplateBinding BorderThickness}" Background="{StaticResource NormalBrush}" BorderBrush="#FF2E2E3E">
                <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/>
            </Border>

将获取Button对象在BorderThickness上获得的值。

答案 1 :(得分:0)

我会使用MVVM完成此操作(如果您还没有考虑MVVM)。 在绑定到Button的ViewModel中,我将添加一个属性“IsBorderLess”。

然后,在触发器上:

<ControlTemplate.Triggers>
      <DataTrigger Binding="{Binding IsBorderLess}" Value="True">
           <Setter TargetName="Border" Property="BorderThickness" Value="0"/>
      </DataTrigger>
      <DataTrigger Binding="{Binding IsBorderLess}" Value="False">
           <Setter TargetName="Border" Property="BorderThickness" Value="10"/>
      </DataTrigger>
   ..........