Gabe
Gabe

Reputation: 50523

Change Border Color for DatePicker

I would like to change the border color for the focus state on the DatePicker control. I took a look at the Default Style Template and didn't see any Focus State for the VisualStateManager.

The only thing I saw was a primitive control for the TextBox as follows:

<controlsPrimitives:DatePickerTextBox x:Name="TextBox" SelectionBackground="{TemplateBinding SelectionBackground}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Column="0" />

How can I change the color for the focus state for the border for the DatePicker... I had no problem changing this color for the TextBox, ComboBox and the CheckBox controls.

Please Help!

Upvotes: 2

Views: 12008

Answers (2)

decyclone
decyclone

Reputation: 30840

Does this work for you:

public class MyDatePicker : DatePicker
{
    public MyDatePicker()
    { }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        DatePickerTextBox textBox = (DatePickerTextBox)this.GetTemplateChild("TextBox");
        textBox.GotFocus += new RoutedEventHandler(textBox_GotFocus);
        textBox.LostFocus += new RoutedEventHandler(textBox_LostFocus);
    }

    void textBox_GotFocus(object sender, RoutedEventArgs e)
    {
        (sender as DatePickerTextBox).BorderBrush = new SolidColorBrush(Colors.Red);
    }

    void textBox_LostFocus(object sender, RoutedEventArgs e)
    {
        (sender as DatePickerTextBox).ClearValue(DatePickerTextBox.BorderBrushProperty);
    }
}

Upvotes: 0

Donut
Donut

Reputation: 112915

You're right, the DatePicker control doesn't have a Focus state for the VisualStateManager. Note that it is possible to add a state group and Focused/Unfocused states for the DatePicker, but that wouldn't be the best approach here.

The template for the DatePicker control contains a DatePickerTextBox control, which, according to MSDN, "represents the text input of a DatePicker".

Looking at the template for the DatePickerTextBox, we find that it has a FocusStates state group, and definitions for both the Unfocused and Focused states. We also find this line:

<Border x:Name="FocusVisual" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>

So as you can see, the default "focused color" is #FF6DBDD1. The Focused state for the DatePickerTextBox sets the Opacity property of this border to 1.

To change the border color for the Focused state, you can create a copy of this template, replacing #FF6DBDD1 with the color you want. Then, create a copy of the DatePicker template, which should specify that the DatePickerTextBox contained within it should use your modified template.

Alternatively, you can create a copy of the DatePickerTextBox template, make the adjustment to the border color, and place this template in a style with TargetType set to DatePickerTextBox:

<Style x:Key="MyStyle1" TargetType="DatePickerTextBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="DatePickerTextBox">
                <!-- Modified template for DatePickerTextBox goes here -->
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Hopefully this is useful to you!


EDIT: Default Template for DatePickerTextBox
Most of the default styles and templates for controls are available on MSDN. However (for whatever reason), DatePickerTextBox is not. If you have a copy of Expression Blend (which I highly recommend if you are working with the appearance of controls; it's invaluable -- download a free trial here), you can do the following:

Right-click on a DatePicker, click "Edit Template -> Edit a Copy...". You'll see the DatePickerTextBox in the "Objects and Timeline" panel. Right-click on that, click "Edit Template -> Edit a Copy..." once more. You can then right-click on the Template in the "Objects and Timeline" panel and click "View XAML."

Again, if you're doing any sort of work like this, I can't recommend Blend highly enough. It will save you so much time in the long run (and you'll learn a ton about XAML, styles, templates, how they all fit together, etc). If you don't have access to it, though, here's the default template for the DatePickerTextBox control:

<Style x:Key="DatePickerTextBoxStyle" TargetType="System_Windows_Controls_Primitives:DatePickerTextBox">
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="HorizontalContentAlignment" Value="Left"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="System_Windows_Controls_Primitives:DatePickerTextBox">
            <Grid x:Name="Root">
               <Grid.Resources>
                  <SolidColorBrush x:Key="WatermarkBrush" Color="#FFAAAAAA"/>
               </Grid.Resources>
               <VisualStateManager.VisualStateGroups>
                  <VisualStateGroup x:Name="CommonStates">
                     <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0"/>
                        <VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
                     </VisualStateGroup.Transitions>
                     <VisualState x:Name="Normal"/>
                     <VisualState x:Name="MouseOver">
                        <Storyboard>
                           <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement">
                              <SplineColorKeyFrame KeyTime="0" Value="#FF99C1E2"/>
                           </ColorAnimationUsingKeyFrames>
                           <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement2">
                              <SplineColorKeyFrame KeyTime="0" Value="#FF99C1E2"/>
                           </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                     </VisualState>
                  </VisualStateGroup>
                  <VisualStateGroup x:Name="WatermarkStates">
                     <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0"/>
                     </VisualStateGroup.Transitions>
                     <VisualState x:Name="Unwatermarked"/>
                     <VisualState x:Name="Watermarked">
                        <Storyboard>
                           <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
                           <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Watermark"/>
                        </Storyboard>
                     </VisualState>
                  </VisualStateGroup>
                  <VisualStateGroup x:Name="FocusStates">
                     <VisualStateGroup.Transitions>
                        <VisualTransition GeneratedDuration="0"/>
                     </VisualStateGroup.Transitions>
                     <VisualState x:Name="Unfocused"/>
                     <VisualState x:Name="Focused">
                        <Storyboard>
                           <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual"/>
                        </Storyboard>
                     </VisualState>
                  </VisualStateGroup>
               </VisualStateManager.VisualStateGroups>
               <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" Opacity="1">
                  <Grid x:Name="WatermarkContent" Background="{TemplateBinding Background}">
                     <Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="1" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                     <Border x:Name="ContentElement2" BorderBrush="#FFFFFFFF" BorderThickness="1">
                        <ContentControl x:Name="Watermark" Background="{TemplateBinding Background}" Content="{TemplateBinding Watermark}" Foreground="{StaticResource WatermarkBrush}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="False" IsTabStop="False" Opacity="0" Padding="2" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                     </Border>
                     <Border x:Name="FocusVisual" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
                  </Grid>
               </Border>
            </Grid>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style> 

Apologies for the length, and many thanks to this thread (which had the same issue).

Upvotes: 7

Related Questions