为什么TextBox Border Color坚持而不是在WPF中更改?

时间:2014-02-15 13:42:26

标签: c# wpf xaml textbox styles

据我了解,我应该使用Style触发器在焦点时更新TextBox的边框颜色。但无论我做什么,它总是转向系统默认蓝色,而不是我指定的黑色。

有人有什么想法吗?

以下代码:

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

2 个答案:

答案 0 :(得分:14)

尝试设置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>

在Windows Seven上测试。

<强> Edit: why is this happening?

我在Windows 7下的Blend中查看了TextBox的默认样式,这里是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>

这里有两个参数:

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

当状态为FocusMouseOver时,他们负责蓝色渐变边框,并且可能在BorderThicknessBorderBrush上存在条件。如果他们 remove / reset ,蓝色渐变边框将消失,并且不需要为BorderThickness设置大于1的值。

ILSpy 中我在TextBoxBase类中找到了ChangeVisualState(bool)方法,这里是:

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);
}

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

答案 1 :(得分:2)

TextBox的默认模板有触发器,用于设置textBox的边框画笔。如果您想覆盖它,则需要覆盖TextBox的ControlTemplate

这就是你这样做的方式:

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

您也可以在上面的模板中将MouseOver画笔覆盖为黑色。您可以通过为UIElement.IsMouseOver触发器提供颜色值来实现此目的。