简体   繁体   中英

WPF: Cant find correct BorderBrush after setting Style

I have a button which I apply a style too. After the style is applied I have a test that checks the BorderBrush of the button to make sure the style was correctly applied. This test always fails, because the BorderBrush never gets updated in the Buttons properties.

Is there a way for me to get the actual BorderBrush being displayed? All i can get is the default BorderBrush, not the applied styles value.

The style I am using is this:

    <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>

Then I apply the style like this:

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

In my test app, I want to check which style has been applied. The difference between the two styles is the border brush. I would like to do something like this:

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

But the BorderBrush never changes (eg in a watch window, it stays the same as the default buttons style BorderBrush), but its definitely applied correctly as in the GUI it turns green.

How can i access this property in my test?

Many thanks in advance

The BorderBrush property of the Button is not bound to anything in your template. You need to do this in the control template:

<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>

Notice how the BorderBrush is now bound to the BorderBrush property of the Button. Then you you can set the BorderBrush in the style and should be able to access it in this way:

if(TopologyNvTxBtn.BorderBrush == Brushes.Green)

Let me know if that works.

Cheers, Eric

As I stated above, the Border is part of the Button ControlTemplate . I just launched Blend and got a copy of the "Factory" template. With this, you can do pretty much everything with it (assuming you know about Stylying.):

    <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 has a good introductory tutorial about Style and Templates . Besides, you can find tons of articles around the web!

The Button itself is pretty much this:

<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>

So, what your looking for is Triggers , you'll have to add and change as you wish these tags:

                <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>

Things to pay attention: TargetName and every <Trigger Property="IsDefaulted" Value="true"> alike! Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM