Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BorderThickness of TextBox in WPF (a bug?)

Tags:

c#

wpf

textbox

I have noticed a strange behaviour of TextBox while BorderThickness property is set to 1 - the focus causes the border to change the color (to something like white). However, if I set the border thickness to something different than 1, say .99 or 1.01 the problem disappears.

Is it the bug in WPF? Or is it intended?

like image 444
Jamie Avatar asked Nov 14 '22 06:11

Jamie


1 Answers

This is the default behavior of the Aero style for TextBoxes. To disable it you would need to restyle the TextBox. You can take the default styles from here (see Download Sample).

In the default Style for TextBoxBase (which TextBox is based on), you will see it uses a ListBoxChrome. This element is defined in the Presentation.Aero assembly and is responsible for rendering the "focused" look. You can simply remove the RenderFocus setting and possibly the RenderMouseOver, or replace it with a Border.

Then you'd want to include that in your application resources.

<LinearGradientBrush x:Key="TextBoxBorder"
      StartPoint="0,0" EndPoint="0,20" MappingMode="Absolute">
  <LinearGradientBrush.GradientStops>
      <GradientStop Color="#ABADB3" Offset="0.05" />
      <GradientStop Color="#E2E3EA" Offset="0.07" />
      <GradientStop Color="#E3E9EF" Offset="1" />
  </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

<Style x:Key="{x:Type TextBoxBase}" TargetType="{x:Type TextBoxBase}" BasedOn="{x:Null}">
  <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
  <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
  <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}" />
  <Setter Property="BorderThickness" Value="1" />
  <Setter Property="Padding" Value="1" />
  <Setter Property="AllowDrop" Value="true" />
  <Setter Property="FocusVisualStyle" Value="{x:Null}" />
  <Setter Property="Template">
      <Setter.Value>
          <ControlTemplate TargetType="{x:Type TextBoxBase}">
              <Border x:Name="Bd" BorderThickness="{TemplateBinding BorderThickness}"
                      BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}"
                      SnapsToDevicePixels="true">
                  <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
              </Border >
              <ControlTemplate.Triggers>
                  <Trigger Property="IsEnabled" Value="false">
                      <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                      <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                  </Trigger>
              </ControlTemplate.Triggers>
          </ControlTemplate>
      </Setter.Value>
  </Setter>
</Style>
<Style x:Key="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBoxBase}}" TargetType="{x:Type TextBox}"/>

If you look at the ListBoxChrome class in Reflector (specifically the OnRender method), you can see it will only render the focused look if it's BorderThickness is "1,1,1,1".

like image 124
CodeNaked Avatar answered Dec 18 '22 18:12

CodeNaked