如何设置覆盖WPF全局样式特定控制元件设置?

问题描述 投票:0回答:2

我已经在通过一个应用程序范围资源词典我的应用程序定义按钮的全局样式。样式看起来像这样(追踪到来自其他SO例):

<Style TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="{DynamicResource BaseButtonBG}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <Grid Background="{TemplateBinding Background}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>
<Style.Triggers>
    <!-- Triggers here -->>
</Style.Triggers>

有用。但我需要特定的值直接分配给我的一些按钮,如margin和padding对准他们。我也想有覆盖从单个按钮的样式颜色属性的能力。

看来,我直接设置在特定的按钮的任何属性得到完全忽略,只有从全局样式的属性被使用。如何克服呢?

更新:为了澄清我想:在HTML / CSS的世界(这是比污垢以上),你可以添加一个风格类的元素,但你也可以直接分配属性对覆盖类值的元素。这就是我想在WPF完成的任务。

更新2这是可能的人认为这个问题是愚蠢的,因为该解决方案应该是显而易见的。不过,从我个人的测试,似乎有与填充不改变在所有除非您特别在控件模板绑定一个bug。这种行为似乎改变物业财产。因为我原来的尝试覆盖属性具体参与填充,并没有工作,我不得不建立这个解决方法。

wpf xaml
2个回答
0
投票

好吧,形成设计:

enter image description here

表单XAML代码:

<Window.Resources>

    <Style TargetType="Button">
        <Setter Property="Foreground" Value="Red"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid Background="{TemplateBinding Background}">
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>


<Grid>
    <Button Content="Button" x:Name="btnNo1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="120"/>
    <Button Content="Button" x:Name="btnNo2" HorizontalAlignment="Left" Margin="135,10,0,0" VerticalAlignment="Top" Width="120"/>

</Grid>

在运行时,我们会通过使用CS文件的代码改变Margin

public MainWindow()
{
    InitializeComponent();

    btnNo2.Margin = new Thickness(100, 100, 100, 100);
}

结果将是:

enter image description here



你可以创建并使用新的样式按钮,你需要定制保证金/填充?

<Style x:Key="SpecialButtonType1" BasedOn="{StaticResource ResourceKey=CommonButtonStyle}">
...
</Style>

与变化

<Style TargetType="Button">

<Style TargetType="Button" x:Key="CommonButtonStyle">

0
投票

YES:这是完全可行的,您可以直接在元素上指定压倒一切的属性,而无需做丑陋的过程中的许多正在使用创造只为有问题的特定元素的特殊一次性字典条目。

我不知道,如果它引起了WPF中的错误,但有一个初步的要求...

你的字典引用的基本风格可能需要包括你想要覆盖的任何属性。出于某种原因,不同性质似乎表现出不同的行为。但至少在填充的情况下,如果不包括在你的控件模板TemplateBinding填充,你将无法对其进行重写你的元素。

此外,在保证金的情况下,似乎有某种“倍增”效应,如果用户在使用的ControlTemplate TemplateBinding保证金出现这种情况。如果你不templateblind保证金,你仍然可以覆盖保证金,但行为的改变。

第1步

定义一个的ControlTemplate一个基本样式。确保您的控件模板,包括您可能需要自定义个人元素/清除所有属性TemplateBinding。

<Style TargetType="Button">
    <Setter Property="Foreground" Value="White"/>
    <Setter Property="Background" Value="{StaticResource BaseButtonBG}"/>
    <Setter Property="Margin" Value="0"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border 
                    Background="{TemplateBinding Background}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}"
                    Margin="{TemplateBinding Margin}"
                    >
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="{StaticResource BaseButtonBG_IsMouseOver}"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background" Value="{StaticResource BaseButtonBG_IsPressed}"/>
        </Trigger>
    </Style.Triggers>
</Style>

我定义了几个静态资源键我的财产的颜色,这样我可以把它们完全在另一个地方进行清洁剥皮。下面是这些按键:

<SolidColorBrush x:Key="BaseButtonBG"                   Color="#5f636c"/>
<SolidColorBrush x:Key="BaseButtonBG_IsMouseOver"       Color="#898C94"/>
<SolidColorBrush x:Key="BaseButtonBG_IsPressed"         Color="#484B51"/>

第2步

实现这样的实际的按钮:

<Button Content="New" />

而这样做的结果使得一个按钮,如下所示:

Initial Button Style

STEP 3

现在,让我们说,我想我所有的按钮来看待压扁这样,只有一个除外。我想添加一些垂直填充,使一个特定的按钮看起来更高。我可能会改变这样的例子按钮:

<Button Content="New" Padding="0,30"/>

而结果是:

Altered Button Style

或者,你可以实现的按钮覆盖如下,它给你覆盖触发器或其他特殊样式选项的能力。

<Button Content="New">
    <Button.Style >
        <Style TargetType="Button" BasedOn="{DynamicResource {x:Type Button}}">
            <Setter Property="Padding" Value="0,30"/>
        </Style>
    </Button.Style>
</Button>

TADA!我们已经分配了一个一次性的风格,直接调整到它所属的元素!我们没有在字典中创建一个样式,并引用它这一个情况。

要点

为了使这项工作“填充”必须与TemplateBinding代码的控件模板来定义。如果你不这样做,填充直接应用于按钮即可被完全忽略。同样,我不知道为什么它是这样,但是这似乎是神奇的修复。

延伸阅读:我能够从这个博客文章上的一些有用的信息想出解决办法:

explicit-implicit-and-default-styles-in-wpf

有趣的是,文章的最后一部分提出创建与自己的默认风格,你同样可以覆盖到,我怎么会在这里做属性的自定义控制。这似乎有点矫枉过正了我,但它可能会消除与填充和利润率表现不同的Bug多多奇怪的问题。并没有说的是,虽然。

© www.soinside.com 2019 - 2024. All rights reserved.