简体   繁体   中英

WPF XAML: Border Brush on Button with IsDefault=“True”

When I try to enter a border brush colour on a button with the IsDefault="True" property, the border will not change and stay with a blue border for the IsDefault Property.

If I remove IsDefault="True", then the border brush colour applies.

Is there a way to have the button as default and also give it a custom border colour?

The problem is the button ControlTemplate , which changes the button appearance on some occasions.

Have a look at the style / control template of a default button:

<Style x:Key="ButtonFocusVisual">
    <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>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
    <GradientStop Color="#F3F3F3" Offset="0"/>
    <GradientStop Color="#EBEBEB" Offset="0.5"/>
    <GradientStop Color="#DDDDDD" Offset="0.5"/>
    <GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
    <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
    <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
    <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <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}">
                <Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Themes:ButtonChrome>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsKeyboardFocused" Value="true">
                        <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
                    </Trigger>
                    <Trigger Property="ToggleButton.IsChecked" Value="true">
                        <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#ADADAD"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The relevant parts are probably the

<Themes:ButtonChrome x:Name="Chrome"
    ...
    RenderMouseOver="{TemplateBinding IsMouseOver}"
    RenderPressed="{TemplateBinding IsPressed}"
    RenderDefaulted="{TemplateBinding IsDefaulted}"
    ... >

and the control template triggers

<Trigger Property="IsKeyboardFocused" Value="true">
    <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
    <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>

So for your specific case, if you really only want a different border for IsDefault but you want all the border changing for focus, mouseover and other states, then you can modify the control template by setting RenderDefaulted="False" in the Themes:ButtonChrome (instead of RenderDefaulted="{TemplateBinding IsDefaulted}" ).

Method1: Best way to do this is just define a style in your Window.Resources which applies that style to all buttons:

<Window.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="BorderBrush" Value="Blue" />
    </Style>
</Window.Resources>

Method 2: Another way is to add x:Key="yourButtonStyle" to the Style element and assign it to any button you want in the Style property:

<Window.Resources>
    <Style x:Key="yourButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="BorderBrush" Value="Blue" />
    </Style>
</Window.Resources>
<Button Style="{StaticResource yourButtonStyle}"/>

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