i have a custom togglebutton with some visual states.
I have to override or change the "checked" state and do this in an easy way.
But the state isn't shown but called. What i am doing wrong?
Heres my code (sample)
[TemplateVisualState(GroupName = CommonStateGroup, Name = ToggleButton.CheckedNormal)]
public partial class ToggleButton : ToggleButton
{
internal const String CommonStateGroup = "CommonStates";
internal const String CheckedNormal = "CheckedNormal";
protected virtual void ChangeVisualState(bool useTransitions)
{
if (this.IsChecked.HasValue && this.IsChecked.Value)
{
VisualStateManager.GoToState(this, CheckedNormal, useTransitions);
}
}
protected override void OnChecked(RoutedEventArgs e)
{
base.OnChecked(e);
this.ChangeVisualState(true);
}
And the Template
<ControlTemplate x:Key="myTemplate" TargetType="{x:Type vw:ToggleButton}">
<Grid Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="CheckedNormal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="CheckedRectangle">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleButtonCheckedBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BackgroundBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleButtonCheckedBorderThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ToggleButtonCheckedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundBorder" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" Margin="3" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Rectangle x:Name="CheckedRectangle" StrokeThickness="0"/>
<Rectangle x:Name="MouseOverRectangle" StrokeThickness="0"/>
<Border x:Name="BlinkBorder" Background="{TemplateBinding BlinkBrush}" CornerRadius="{TemplateBinding CornerRadius}" Opacity="0"/>
<ContentControl x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Border>
<Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1"/>
<Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" Stroke="{StaticResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1"/>
</Grid>
</ControlTemplate>
The template is created in Blend and the state is testet by clicking around in visual states.
I think the behavior is interrupted by the "checked" state.
My Solution to this:
Adding a "UncheckedNormal" State reacting on Unchecked
Editing the following states:
Normal: Visibility of CheckedBorder = Visible
Enabled: Visibility of CheckedBorder = Visible
MouseOver: Visibility of CheckedBorder = Collapsed
CheckedNormal: Visibility of CheckedBorder = Visible
Background = CheckedBackgroundBrush
UncheckedNormal: Visibility of CheckedBorder = Visible
Background = transparent
Related
I am making a custom control. When mouse over it, the opacity of content will animate from 0.5 to 0.8. When mouse pressed it, the opacity of content will set to 1 immediately.
Here is my code:
<ControlTemplate TargetType="{x:Type local:OpacityButton}">
<Border x:Name="B" Background="{TemplateBinding Background}" Opacity="0.5" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter Margin="{TemplateBinding Padding}" TextBlock.FontFamily="{TemplateBinding FontFamily}" Content="{TemplateBinding Content}" TextBlock.Foreground="{TemplateBinding Foreground}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" TextBlock.FontSize="{TemplateBinding FontSize}"></ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="B"
Storyboard.TargetProperty="Opacity"
To="0.8" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="B"
Storyboard.TargetProperty="Opacity"
To="0.5" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" Value="1" TargetName="B"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
When the button is pressed, the opacity doesn't change any.
Soon I found this solution:
Storyboard animation not completing when triggering property changes
I add the RemoveStoryboard to the EnterActions and ExitActions, now when the mouse is over, the opacity does not change any.
It seems because it removes the Storyboard immediately but not after it is complete.
How can I solve this?
This is a better job for VisualStates:
<ControlTemplate TargetType="{x:Type local:OpacityButton}">
<Border x:Name="B"
Background="{TemplateBinding Background}"
Opacity="0.5"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="B"
Storyboard.TargetProperty="Opacity"
To="0.5"
Duration="0:0:0.3" />
</Storyboard>
</VisualState>
<VisualState Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="B"
Storyboard.TargetProperty="Opacity"
To="0.8"
Duration="0:0:0.3" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="B"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.3" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Margin="{TemplateBinding Padding}"
TextBlock.FontFamily="{TemplateBinding FontFamily}"
Content="{TemplateBinding Content}"
TextBlock.Foreground="{TemplateBinding Foreground}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
TextBlock.FontSize="{TemplateBinding FontSize}"></ContentPresenter>
</Border>
</ControlTemplate>
The problem with your Triggers is that more than one of them is true at the same time - when the button is pressed, the mouse is also over it, so the triggers are competing and the IsMouseOver one is winning.
The control can only have one VisualState at a time though, so you can define exactly what happens in each state and only that state.
If you're committed to triggers you could use MultiTrigger for the mouse over state, making the conditions IsMouseOver = true and IsPressed = false. Then when IsPressed is true, that trigger will run and the other won't.
But assuming you're subclassing Button here, WPF is already giving you the VisualState's for free, so you might as well use them.
I'm creating an app where on my main page I have a list with a ToggleSwitch control on each row but the control doesn't appear on the phone emulator. The XAML for the ToggleSwitch control is as below:
<toolkit:ToggleSwitch x:Name="ToggleSwitch" IsChecked="false" Content="Content Goes here" Checked="switch_Unchecked" Unchecked="switch_Unchecked" BorderBrush="black" Background="Black" Width="200"/>
When I click on that code, it shows me that:
So I believe that the control with BorderBrush=black and Background=Black is at the right place but it doesn't appear...
May somebody helps me with that ?
What's the color of your Grid Background color? There might be some problem with that too. Try applying the following style for the Toggle Switch.
<Grid x:Name="LayoutRoot" Background="White">
<toolkit:ToggleSwitch Margin="12,0" Content="Live Update" Background="White" Foreground="Black" Style="{StaticResource FixedToggleSwitchStyle}"/>
</Grid>
And the style is,
<Style x:Key="FixedToggleSwitchButtonStyle" TargetType="toolkitPrimitives:ToggleSwitchButton">
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="{StaticResource PhoneBackgroundBrush}"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="SwitchForeground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkitPrimitives:ToggleSwitchButton">
<Border x:Name="Root" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CacheMode="BitmapCache" Opacity="{TemplateBinding Opacity}" Padding="{TemplateBinding Padding}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimation Duration="0" To="{TemplateBinding Foreground}" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" Storyboard.TargetName="SwitchBottom"/>
<ColorAnimation Duration="0" To="{TemplateBinding Foreground}" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="ThumbCenter"/>
<DoubleAnimation Duration="0" To="0.3" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.05" To="Unchecked"/>
<VisualTransition GeneratedDuration="0:0:0.05" To="Checked"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0" To="69" Storyboard.TargetProperty="(TranslateTransform.X)" Storyboard.TargetName="BackgroundTranslation">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="15"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Duration="0" To="69" Storyboard.TargetProperty="(TranslateTransform.X)" Storyboard.TargetName="ThumbTranslation">
<DoubleAnimation.EasingFunction>
<ExponentialEase EasingMode="EaseOut" Exponent="15"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="Dragging"/>
<VisualState x:Name="Unchecked">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(TranslateTransform.X)" Storyboard.TargetName="BackgroundTranslation"/>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(TranslateTransform.X)" Storyboard.TargetName="ThumbTranslation"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid x:Name="SwitchRoot" Background="Transparent" Height="95" Width="136">
<Grid x:Name="SwitchTrack" Width="89">
<Grid x:Name="SwitchBottom" Background="{TemplateBinding SwitchForeground}" Height="34">
<Rectangle x:Name="SwitchBackground" Fill="{TemplateBinding Background}" HorizontalAlignment="Center" Height="20" VerticalAlignment="Center" Width="77">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="BackgroundTranslation"/>
</Rectangle.RenderTransform>
</Rectangle>
<Border BorderBrush="{TemplateBinding Foreground}" BorderThickness="3">
<Border BorderBrush="{TemplateBinding Background}" BorderThickness="4"/>
</Border>
</Grid>
<Border x:Name="SwitchThumb" BorderBrush="{TemplateBinding Background}" BorderThickness="4,0" HorizontalAlignment="Left" Height="38" Margin="-4,0" Width="28">
<Border.RenderTransform>
<TranslateTransform x:Name="ThumbTranslation"/>
</Border.RenderTransform>
<Border x:Name="ThumbCenter" BorderBrush="{TemplateBinding Foreground}" BorderThickness="2" Background="{TemplateBinding Foreground}"/>
</Border>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="FixedToggleSwitchStyle" TargetType="toolkit:ToggleSwitch">
<Setter Property="Background" Value="{StaticResource PhoneBackgroundBrush}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyLight}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeLarge}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="SwitchForeground" Value="{StaticResource PhoneAccentBrush}"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ToggleSwitch">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CacheMode="BitmapCache" Padding="{TemplateBinding Padding}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0.3" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Header"/>
<DoubleAnimation Duration="0" To="0.3" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Content"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Margin="12,5,12,42">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ContentControl x:Name="Header" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{StaticResource PhoneSubtleBrush}" FontSize="{StaticResource PhoneFontSizeNormal}" FontFamily="{StaticResource PhoneFontFamilyNormal}" HorizontalAlignment="Left" IsTabStop="False" Margin="-1,0,0,0" Opacity="{TemplateBinding Opacity}" VerticalAlignment="Bottom"/>
<ContentControl x:Name="Content" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" Margin="-1,1,0,-7" Opacity="{TemplateBinding Opacity}" Grid.Row="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<toolkitPrimitives:ToggleSwitchButton x:Name="Switch" Background="{TemplateBinding Background}" Grid.Column="1" Margin="-22,-29,-24,-28" Opacity="{TemplateBinding Opacity}" Grid.RowSpan="2" SwitchForeground="{TemplateBinding SwitchForeground}" VerticalAlignment="Bottom" Style="{StaticResource FixedToggleSwitchButtonStyle}" Foreground="{TemplateBinding Foreground}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Change your Background color and Foreground color as per your needs in Toggle Switch.
Have either one of these property, Background or the BorderBrush.
Why don't you try it this way?
xaml:
<ToggleSwitch x:Name="toggleSwitch1" Header="ToggleSwitch"
OnContent="On" OffContent="Off"
Toggled="ToggleSwitch_Toggled"/>
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
// Add code to perform some action here.
}
Have a look at this too. Is that the one you're using from the Toolkit or what?
Hope it helps!
I added a button then changed it's background to a picture.. when it run if I hover on the button the picture is gone and when I click it will become solid white
I want to change that .. I want to display the picture on hover and click
how to do this ?? please help me
im using visual studio 2013 - windows store - c#/xaml
here is my xaml code for the btton
<Button Content="Asia" HorizontalAlignment="Left" Margin="232,366,0,0" VerticalAlignment="Top" Height="395" Width="235" BorderThickness="0">
<Button.Background>
<ImageBrush ImageSource="south amirica.png"/>
</Button.Background>
</Button>
do I change something here ??
Behaviour you're describing is part of default Template for a Button. To customize this behaviour you can define your custom Button.Template:
<Button Content="Asia" HorizontalAlignment="Left" Margin="232,366,0,0" VerticalAlignment="Top" Height="395" Width="235">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="south amirica.png"/>
</Grid.Background>
<ContentPresenter/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
Be aware that this will also remove all other effects like for example button press effect but you can add it to your Template if you want
Try this
<Button Height="35" Width="200">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Grid.Resources>
<BitmapImage x:Key="NormalButton" UriSource="Assets/NormalButton.png"></BitmapImage>
<BitmapImage x:Key="OnMouseOver" UriSource="Assets/OnMouseOver.png"></BitmapImage>
<BitmapImage x:Key="OnPresed" UriSource="Assets/OnPresed.png"></BitmapImage>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="ImageSource" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource OnMouseOver}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="ImageSource" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource OnPresed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Grid.Background>
<ImageBrush x:Name="Border" ImageSource="{StaticResource NormalButton}"></ImageBrush>
</Grid.Background>
<ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
I would like to change Border.Background when the ListBox's ListBoxItem is selected.
I made this resource in App.xaml:
<Style x:Key="HighlightStyle" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FFE20080" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedUnfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Strange, it works with Foreground, it changes the color, but it's not working with Background, and that is what I want to change.
The Background property is not set in XAML, so there is no local default value there.
Try setting the Background in your style, in a setter. The reason for the animation not running could be that the brush from the theme is frozen. See http://msdn.microsoft.com/en-us/library/ms750509(v=vs.110).aspx
--- EDIT ---
Sorry, it was late last night when I answered and I missed a couple of things :) The most important of those is that this question concerns Windows Phone.
First, you don't need to animate the color, you want to replace the brush - that would be more efficient.
Second, you might want to change the background on the list box item, instead a particular component of it.
The following lines achieve this:
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<SolidColorBrush Color="#FFE20080" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
Then, you have a hardcoded value ('White') on your container control component. Make it inherit the value from the list box item instead, like this:
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"/>
HTH
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!
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).
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);
}
}