0

I am attempting to modify the style of a CustomControl based on TextBox, I have been largely successful. The last thing I'm attempting to accomplish is to make it dim when disabled. I have successfully gotten this to work but the color is off, it doesn't match the standard TextBoxes when they are disabled.

What is the appropriate color for the native TextBox and/or how can I access the default style for the native TextBox in order to copy the appropriate syntax? The example on MSDN does not appear to be the standard Style? I've also seen suggestions to use Blend to grab the default style? That doesn't appear to work either, for some reason this approach creates a reference to PresentationFramework.Classic in my project and provides me with a TextBox that looks like Windows Forms(Sunken border, etc).

Generic.xaml

<Style x:Key="{x:Type l:CustomTextBox}" BasedOn="{StaticResource {x:Type TextBox}}" TargetType="{x:Type l:CustomTextBox}">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type l:CustomTextBox}">
                <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <ScrollViewer x:Name="PART_ContentHost" Margin="2" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <!-- The background does change, but the color does not match native disabled TextBoxes. -->
                        <Setter Property="Background" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                    </Trigger>
                    <!-- Additional triggers, none of which modify the Background. -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48

1 Answers1

1

I found this on a blog, it helped me out. It will write the template for the specified element to the console. It needs to be executed after the window is created e.g. the Loaded event.

var stringBuilder = new StringBuilder();

var xmlSettings = new XmlWriterSettings();
xmlSettings.Indent = true;

using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, xmlSettings))
    XamlWriter.Save(this.textBox.Template, xmlWriter);

Console.WriteLine(stringBuilder.ToString());

Output

<?xml version="1.0" encoding="utf-16"?>
<ControlTemplate TargetType="TextBoxBase" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:s="clr-namespace:System;assembly=mscorlib">
  <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">
      <Setter Property="UIElement.Opacity" TargetName="border">
        <Setter.Value>
          <s:Double>0.56</s:Double>
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>False</s:Boolean>
      </Trigger.Value>
    </Trigger>
    <Trigger Property="UIElement.IsMouseOver">
      <Setter Property="Border.BorderBrush" TargetName="border">
        <Setter.Value>
          <SolidColorBrush>#FFC5DAED</SolidColorBrush>
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>True</s:Boolean>
      </Trigger.Value>
    </Trigger>
    <Trigger Property="UIElement.IsKeyboardFocused">
      <Setter Property="Border.BorderBrush" TargetName="border">
        <Setter.Value>
          <SolidColorBrush>#FFB5CFE7</SolidColorBrush>
        </Setter.Value>
      </Setter>
      <Trigger.Value>
        <s:Boolean>True</s:Boolean>
      </Trigger.Value>
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

The generated template was not what I expected, no references to the SystemColor's? But adding the Opacity to my existing control did fix my original behavior, so I'm happy with the result just confused by it. If anyone can elaborate I'd love to see some additional comments.

Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48