【问题标题】:WPF: Cant find correct BorderBrush after setting StyleWPF:设置样式后找不到正确的 BorderBrush
【发布时间】:2013-10-10 21:26:25
【问题描述】:

我有一个按钮,我也应用了一种样式。应用样式后,我进行了一个测试,检查按钮的 BorderBrush 以确保正确应用了样式。此测试总是失败,因为 BorderBrush 永远不会在 Buttons 属性中更新。

有没有办法让我显示实际的 BorderBrush?我能得到的只是默认的 BorderBrush,而不是应用的样式值。

我使用的样式是这样的:

    <Style  x:Key="ActiveModuleBtnStyleOn" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid>
                    <Border Margin="0" 
                                    BorderThickness="3" 
                                    BorderBrush="Green" 
                                    Background="White" 
                                    VerticalAlignment="Stretch" 
                                    CornerRadius="4" 
                                    HorizontalAlignment="Stretch">
                        <Border.Effect>
                            <DropShadowEffect BlurRadius="10" Color="Black" Direction="325" Opacity=".5" RenderingBias="Quality" ShadowDepth="5" />
                        </Border.Effect>
                    </Border>
                    <TextBlock Margin="2" Text="{TemplateBinding Content}" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="IsEnabled" Value="true"/>
</Style>

然后我应用这样的样式:

if(var1 == 1)
  TopologyNvTxBtn.Style = this.FindResource("ActiveModuleBtnStyleOn") as Style;
else
  TopologyNvTxBtn.Style = this.FindResource("ActiveModuleBtnStyleOff") as Style;

在我的测试应用程序中,我想检查应用了哪种样式。两种样式的区别在于边框画笔。我想做这样的事情:

if(TopologyNvTxBtn.BorderBrush == Brushes.Green)
  return PASS;

但是 BorderBrush 永远不会改变(例如,在监视窗口中,它与默认按钮样式 BorderBrush 保持相同),但它肯定会正确应用,因为它在 GUI 中变为绿色。

如何在我的测试中访问此属性?

在此先感谢

【问题讨论】:

  • 安迪,Border 设置在按钮的ControlTemplate 内。查看此MSDN article 了解更多信息!
  • 这是否意味着我无法在运行时访问它?
  • 您必须设置自己的Template - 请参阅下文。
  • 不要忘记为您的元素添加x:Name
  • 检查元素及其各自风格的好工具是Snoop。如果您打算在 WPF 中开发并设置自己的元素和控件样式,则必须具备此功能。

标签: c# wpf xaml button styles


【解决方案1】:

Button 的 BorderBrush 属性未绑定到模板中的任何内容。您需要在控件模板中执行此操作:

<Style  x:Key="ActiveModuleBtnStyleOn" TargetType="Button">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <Grid>
                <Border Margin="0" 
                                BorderThickness="3" 
                                BorderBrush="{TemplateBinding BorderBrush}" 
                                Background="White" 
                                VerticalAlignment="Stretch" 
                                CornerRadius="4" 
                                HorizontalAlignment="Stretch">
                    <Border.Effect>
                        <DropShadowEffect BlurRadius="10" Color="Black" Direction="325" Opacity=".5" RenderingBias="Quality" ShadowDepth="5" />
                    </Border.Effect>
                </Border>
                <TextBlock Margin="2" Text="{TemplateBinding Content}" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>
<Setter Property="IsEnabled" Value="true"/>
</Style>

注意 BorderBrush 现在是如何绑定到 Button 的 BorderBrush 属性的。然后你可以在样式中设置 BorderBrush 并且应该可以通过这种方式访问​​它:

if(TopologyNvTxBtn.BorderBrush == Brushes.Green)

让我知道这是否有效。

干杯, 埃里克

【讨论】:

    【解决方案2】:

    如上所述,BorderButton ControlTemplate 的一部分。我刚刚启动了 Blend 并获得了“工厂”模板的副本。有了这个,你几乎可以用它做任何事情(假设你知道造型。):

        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
        <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
        <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
        <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
        <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
        <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
        <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
        <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
        <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
        <Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
            <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
                            <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsDefaulted" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                                <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    MSDN 有一个很好的关于StyleTemplates 的入门教程。此外,您可以在网络上找到大量文章!

    Button 本身就是这样的:

    <Border
             x:Name="border"
             Background="{TemplateBinding Background}"
             BorderBrush="{TemplateBinding BorderBrush}"
             BorderThickness="{TemplateBinding BorderThickness}"
             SnapsToDevicePixels="true">
             <ContentPresenter
                x:Name="contentPresenter"
                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                Margin="{TemplateBinding Padding}"
                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                Focusable="False"
                RecognizesAccessKey="True"
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Border>
    

    所以,您要查找的是Triggers,您必须根据需要添加和更改这些标签:

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefaulted" Value="true">
                            <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="true">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                            <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
    

    注意事项:TargetName 和每个&lt;Trigger Property="IsDefaulted" Value="true"&gt; 一样! 祝你好运!

    【讨论】:

    • 那太好了,但这就是我已经拥有的。设置我想要的样式没有问题,这一切都很好。问题是找到设置后设置的样式。我有一个带有绿色边框的按钮样式,但我在任何地方都看不到它。如果我查看按钮对象,边框仍然是灰色的。如果我看屏幕是绿色的。
    • Trigger 标签负责处理当某些操作(如MouseOver)发生时哪个属性发生的情况。您可以将您的样式放在&lt;Button.Resources&gt; 标签之间,也可以将它们设置在其他位置并在您的文件中引用xaml
    • 我看不出这如何告诉我我正在使用什么风格,这是我需要的信息。我错过了什么吗?在应用样式后,我需要一种在运行时访问边框的方法,请参阅我对原始帖子的编辑。
    • 现在我不确定你的意思是什么......无论如何。您必须为元素提供 x:Name 才能访问和投射它们。
    猜你喜欢
    • 1970-01-01
    • 2014-09-24
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多