为什么 TextBox 边框颜色在 WPF 中坚持而不改变?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21798326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:52:29  来源:igfitidea点击:

Why does TextBox Border Colour insist on and not changing in WPF?

c#wpfxamltextboxstyles

提问by dannybrown

As far as I understand I should be using Style triggers to update the TextBox's border colour when it is focused. However no matter what I do it always turns to the system default blue, not the black I have specified.

据我所知,我应该使用样式触发器在聚焦时更新 TextBox 的边框颜色。然而,无论我做什么,它总是变成系统默认的蓝色,而不是我指定的黑色。

Anyone have any ideas?

谁有想法?

Code below:

代码如下:

<UserControl.Resources>
    <Style TargetType="TextBox">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <Setter Property="BorderBrush" Value="Black" />
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

回答by Anatoliy Nikolaev

Try set for BorderThicknessvalue more than 1(by default):

尝试设置BorderThickness值大于1(默认):

<Window.Resources>
    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <Setter Property="BorderBrush" Value="Pink" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <TextBox Width="100"
             Height="30"
             Text="Test" 
             BorderThickness="4" />
</Grid>

Tested on Windows Seven.

在 Windows 7 上测试。

Edit: why is this happening?

Edit: why is this happening?

I looked in the default style for TextBoxin Blend under Windows 7, here it is ControlTemplate:

我查看了TextBoxWindows 7 下 Blend的默认样式,这里是 ControlTemplate:

<ControlTemplate x:Key="TextBoxControlTemplate1" TargetType="{x:Type TextBox}">
    <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
        <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Microsoft_Windows_Themes:ListBoxChrome>

    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Here there is two parameters:

这里有两个参数:

RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"

They are responsible for blue gradient Border when states Focusand MouseOverand probably there stands a condition on BorderThicknessand BorderBrush. If they remove / resetthe blue gradient Border will disappear and will not need to set values for BorderThicknessgreater than 1.

他们负责的蓝色渐变边界时的状态FocusMouseOver和可能出现看台上的条件BorderThicknessBorderBrush。如果它们remove / reset,蓝色渐变边框将消失,并且不需要设置BorderThickness大于 1 的值。

In ILSpyI found ChangeVisualState(bool)method in TextBoxBase class, here it is:

ILSpyChangeVisualState(bool)在 TextBoxBase 类中找到的方法中,它是:

internal override void ChangeVisualState(bool useTransitions)
{
    if (!base.IsEnabled)
    {
        VisualStateManager.GoToState(this, "Disabled", useTransitions);
    }
    else
    {
        if (this.IsReadOnly)
        {
            VisualStateManager.GoToState(this, "ReadOnly", useTransitions);
        }
        else
        {
            if (base.IsMouseOver)
            {
                VisualStateManager.GoToState(this, "MouseOver", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Normal", useTransitions);
            }
        }
    }

    if (base.IsKeyboardFocused)
    {
        VisualStateManager.GoToState(this, "Focused", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Unfocused", useTransitions);
    }

    base.ChangeVisualState(useTransitions);
}

It turns out that these visual states implemented "systematically" and in Styles not present.

事实证明,这些视觉状态是“系统地”实现的,并且在样式中不存在。

回答by Rohit Vats

Default template of TextBoxhas trigger which set the border brush of textBox. In case you want to override it, you need to override ControlTemplateof TextBox.

默认模板TextBoxhas trigger 设置 textBox 的边框画笔。如果要覆盖它,则需要覆盖ControlTemplateTextBox

This is how you do that:

这就是你这样做的方式:

<Style TargetType="TextBox">
    <Setter Property="Template">
       <Setter.Value>
          <ControlTemplate TargetType="TextBox">
              <Border BorderThickness="{TemplateBinding Border.BorderThickness}"
                      BorderBrush="{TemplateBinding Border.BorderBrush}"
                      Background="{TemplateBinding Panel.Background}"
                      Name="border"
                      SnapsToDevicePixels="True">
                 <ScrollViewer HorizontalScrollBarVisibility="Hidden"
                               VerticalScrollBarVisibility="Hidden"
                               Name="PART_ContentHost"
                               Focusable="False" />
              </Border>
           <ControlTemplate.Triggers>
              <Trigger Property="UIElement.IsEnabled" Value="False">
                <Setter Property="UIElement.Opacity" TargetName="border"
                        Value="0.56"/>
              </Trigger>
              <Trigger Property="UIElement.IsMouseOver" Value="True">
                <Setter Property="Border.BorderBrush" TargetName="border" 
                        Value="#FF7EB4EA"/>
              </Trigger>
              <Trigger Property="UIElement.IsKeyboardFocused" Value="True">
                <Setter Property="Border.BorderBrush" TargetName="border" 
                       Value="Black"/> <-- HERE
              </Trigger>
           </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
 </Style>

Also you might want to override MouseOver brush to Black in above template. You can do that by supplying color value for UIElement.IsMouseOvertrigger.

此外,您可能希望在上述模板中将 MouseOver 笔刷覆盖为黑色。您可以通过为UIElement.IsMouseOver触发器提供颜色值来做到这一点。