如何为按钮定义自定义样式,但每个按钮具有不同的文本/内容显示?

时间:2017-06-20 17:16:15

标签: wpf xaml

所以我在下面有一个样式,我想要应用于我的表单中的多个按钮(WPF)。但是每个按钮需要有不同的标题,我不知道如何为每个按钮应用相同的样式而不为每个按钮复制+粘贴+重命名(并在Textblock中设置内容)。

App.xaml中的XAML

<Style x:Key="RunReportButton"
               TargetType="{x:Type Button}" 
               BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Grid Background="#EEB4B4">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetName="ButtonBorder"
                                                            Storyboard.TargetProperty="Color"
                                                            To="#d6a2a2"
                                                            Duration="0:0:00.0" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetName="ButtonBorder"
                                        Storyboard.TargetProperty="Color"
                                        To="#d6a2a2"
                                        Duration="0:0:00.0" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border>
                            <Border.Background>
                                <SolidColorBrush x:Name="ButtonBorder" 
                                Color="Transparent" />
                            </Border.Background>
                        </Border>
                        <TextBlock 
                                   FontFamily="Open Sans"
                                   FontSize="16"
                                   FontWeight="SemiBold"
                                   Foreground="#CD3333"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Margin="5,5,5,5"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

以我的形式绑定:

<Button Style="{StaticResource RunReportButton}"
                    Margin="0,20"/>

2 个答案:

答案 0 :(得分:0)

  1. 对于每个按钮,将Content属性设置为您想要的任何文本。
  2. TextBlock&#39; Text属性设置为{TemplateBinding Content}。此标记扩展名单向绑定到DependencyProperty所属项目的指定ControlTemplate

答案 1 :(得分:0)

使用TextBlock代替ControlTemplate中的ContentPresenter。默认情况下,它将显示模板化父级的Content属性 - 您的案例中的按钮。您可以通过设置ContentPresenter.ContentSource来命名模板化父级的不同属性,但在这种情况下,默认值是正确的。

TextBlock是该角色的不良选择,因为它可以显示的只是一个字符串,但Button.Content可以是任何内容 - ImageDataGrid,视图模型,任何东西。没有理由不保留这种全方位的可能性。

原始模板出错:<ControlTemplate>缺少TargetType="Button",这对于模板正常运行至关重要。

<Style 
    x:Key="RunReportButton"
    TargetType="{x:Type Button}" 
    BasedOn="{StaticResource {x:Type Button}}"
    >
    <Setter Property="TextElement.FontFamily" Value="Open Sans" />
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="Background" Value="#EEB4B4" />
    <!-- Ditto for other TextElement.FontSize etc. -->

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="{TemplateBinding Background}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="ButtonBorder"
                                                    Storyboard.TargetProperty="Color"
                                                    To="#d6a2a2"
                                                    Duration="0:0:00.0" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ColorAnimation 
                                        Storyboard.TargetName="ButtonBorder"
                                        Storyboard.TargetProperty="Color"
                                        To="#d6a2a2"
                                        Duration="0:0:00.0" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border>
                        <Border.Background>
                            <SolidColorBrush x:Name="ButtonBorder" 
                        Color="Transparent" />
                        </Border.Background>
                    </Border>
                    <!-- Ditto for other TextElement.FontSize etc. -->
                    <ContentPresenter
                        TextElement.FontFamily="{TemplateBinding TextElement.FontFamily}"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                        Margin="5,5,5,5"
                        />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

此外,如果您使用如图所示的TemplateBindings,您可以在Button样式中为这些属性设置默认值,并让消费者在XAML中选择它们。