Making a custom stretchable button template from images - c#

I was trying to make a WPF button template from 4 images: "btnNormal, btnHover, btnPressed and btnDisabled".
The thing is I don't know how to make my button look like this exactly with WPF styles. So now I am trying to make it using these images. The thing is I want my button to be stretchable and to look same on any size. To do this I need to make 3 slices for each button state image: "Top, Bottom, Left, Right, Center"
I have this XAML for now :
<Application.Resources>
<ControlTemplate x:Key="StylishBlueButton" TargetType="{x:Type Button}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
</VisualStateGroup>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="InvalidFocused"/>
<VisualState x:Name="InvalidUnfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Application.Resources>
</Application>
Can anyone help me out, how can I make this button template?

You want to specify something inside the VisualState, e.g.
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<!--Take one half second to transition to the MouseOver state.-->
<VisualTransition To="MouseOver" GeneratedDuration="0:0:0.5" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="borderColor" Storyboard.TargetProperty="Color" To="Cyan"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="borderColor" Storyboard.TargetProperty="Color" To="Red"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Ellipse>
<Ellipse.Fill>
<SolidColorBrush x:Name="borderColor" Color="Black"/>
</Ellipse.Fill>
</Ellipse>
<Ellipse x:Name="ButtonShape" Margin="5" Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>

<Border Background="DodgerBlue">
<Rectangle Fill="Transparent" Stroke="White" Margin="3" />
</Border>
Place a path as per your style that you needed instead of Rectangle.

Related

C# WPF change BorderBrush inside the DatePicker

I use a DatePicker for my application. I can change all the values I need. The last value that I need is the BorderBrush. I can't adjust the blue color shown here which is out of the standard. I have already created and edited a copy as CustomStyle. The theme of DatePicker seems relatively complex in WPF.
How can I set this color?
Maybe someone here can help me, thank you for your support. And yes, I have already read some topics about this theme here. But as it seems no suitable answer.
The Popup of a DatePicker is a Calendar and each day inside a Calendar is a CalendarDayButton.
For what you want to achieve you have to override the Style (more precisely the ControlTemplate) of the CalendarDayButton.
The interesting part is the Rectangle "DayButtonFocusVisual"
<DatePicker>
<DatePicker.CalendarStyle>
<Style TargetType="{x:Type Calendar}">
<Setter Property="CalendarDayButtonStyle">
<Setter.Value>
<Style TargetType="{x:Type CalendarDayButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CalendarDayButton}">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="HighlightBackground"/>
<DoubleAnimation Duration="0" To=".35" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="NormalText"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation Duration="0" To=".75" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SelectedBackground"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CalendarButtonFocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="CalendarButtonFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DayButtonFocusVisual">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="CalendarButtonUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DayButtonFocusVisual">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ActiveStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Active"/>
<VisualState x:Name="Inactive">
<Storyboard>
<ColorAnimation Duration="0" To="#FF777777" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="NormalText"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DayStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="RegularDay"/>
<VisualState x:Name="Today">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TodayBackground"/>
<ColorAnimation Duration="0" To="#FFFFFFFF" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="NormalText"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="BlackoutDayStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="NormalDay"/>
<VisualState x:Name="BlackoutDay">
<Storyboard>
<DoubleAnimation Duration="0" To=".2" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Blackout"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="TodayBackground" Fill="#FFAAAAAA" Opacity="0" RadiusY="1" RadiusX="1"/>
<Rectangle x:Name="SelectedBackground" Fill="#FFBADDE9" Opacity="0" RadiusY="1" RadiusX="1"/>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"/>
<Rectangle x:Name="HighlightBackground" Fill="#FFBADDE9" Opacity="0" RadiusY="1" RadiusX="1"/>
<ContentPresenter x:Name="NormalText" TextElement.Foreground="#FF333333" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="5,1,5,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Path x:Name="Blackout" Data="M8.1772461,11.029181 L10.433105,11.029181 L11.700684,12.801641 L12.973633,11.029181 L15.191895,11.029181 L12.844727,13.999395 L15.21875,17.060919 L12.962891,17.060919 L11.673828,15.256231 L10.352539,17.060919 L8.1396484,17.060919 L10.519043,14.042364 z" Fill="#FF000000" HorizontalAlignment="Stretch" Margin="3" Opacity="0" RenderTransformOrigin="0.5,0.5" Stretch="Fill" VerticalAlignment="Stretch"/>
<Rectangle x:Name="DayButtonFocusVisual" IsHitTestVisible="false" RadiusY="1" RadiusX="1" Stroke="Red" Visibility="Collapsed"/><!--Stroke="#FF45D6FA"-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</DatePicker.CalendarStyle>
</DatePicker>

Silverlight button Mouse Over like hover effect

I created button with style but after creating button style it looses default effect of the button and when I directly put attribute in button than I will get those default effects like when I click I can see blue background.I also try to put Visual Manager but it is not working. Kindly somebody can help me to know what I am doing wrong
My Button Style:
<Style TargetType="Button" x:Key="MenuButtonStyle">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontFamily" Value="Sitka Heading"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="ButtonTextElement"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
To="Blue"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="normalImage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="mouseOverImage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" Storyboard.TargetName="ButtonTextElement"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
To="Blue"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="normalImage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="mouseOverImage">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush="Black" BorderThickness="0,0,0,0.5" Margin="30,0,0,0"
Grid.ColumnSpan="2"/>
<TextBlock x:Name="ButtonTextElement"
Text="{TemplateBinding Content}" Margin="30,0"
Foreground="{TemplateBinding Foreground}" Grid.Column="0"
VerticalAlignment="{TemplateBinding VerticalAlignment}" />
<Image x:Name="normalImage" Source="/Assets/menu-arrow-left.png"
Grid.Column="1" Stretch="None" HorizontalAlignment="Right"
Margin="0,0,30,0" />
<Image x:Name="mouseOverImage" Source="/Assets/menu-arrow-left-hover.png"
Grid.Column="1" Stretch="None" HorizontalAlignment="Right"
Visibility="Collapsed" Margin="0,0,30,0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also change in VisualStateManager like this
<ColorAnimation Storyboard.TargetName="MouseOverVisualElement"
Storyboard.TargetProperty="TextBlock.Foreground" To="Red" />
My Button Tag
<Button Style="{StaticResource MenuButtonStyle}" Content="Home"/>
There are several issues with your template. First: You have to make sure that the element identified by Storyboard.TargetName and its property (you want to change) identified by Storyboard.TargetProperty actually make sense. You can change the color of a SolidColorBrush, and you can use a SolidColorBrush for a Textblock.Foreground property, but you cannot directly set the foreground property color, because foreground actually is a Brush (not a Color). Second: if you override the template of a control you have to provide all the VisualStates that are in the original template, that means you have to define the FocusStates as well.
Here is a template that does what you are trying to do:
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation
Duration="0"
Storyboard.TargetName="ButtonTextElement"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation
Duration="0"
Storyboard.TargetName="Background"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#FF6DBDD1"/>
<ColorAnimation
Duration="0"
Storyboard.TargetName="ButtonTextElement"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
To="Red"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation
Duration="0"
Storyboard.TargetName="DisabledVisualElement"
Storyboard.TargetProperty="Opacity"
To=".55"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Duration="0"
Storyboard.TargetName="FocusVisualElement"
Storyboard.TargetProperty="Opacity"
To="1"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
x:Name="Background"
Background="White"/>
<TextBlock
x:Name="ButtonTextElement"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Text="{TemplateBinding Content}"
FontSize="20" FontFamily="Sitka Heading"
Foreground="Black"/>
<Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
<Rectangle x:Name="FocusVisualElement" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
</Grid>
</ControlTemplate>
The default button style can be found on msdn.
Please see this page:
https://msdn.microsoft.com/en-us/library/cc278069(VS.95).aspx
and see this page:
http://samples.msdn.microsoft.com/Silverlight/SampleBrowser/index.htm#/?sref=CustomTemplateSamples&id=4
there are a sample for mouse over with templete
Make sure VisualStateManager.VisualStateGroups is the direct child of the root element of your ControlTemplate. In your example, your root element is a Border, so put the VisualStateManager stuff directly under the Border tag.

Datepicker inheriting style from Textblock

I have a resource dictionary that contains the following code:
<Style TargetType="{x:Type TextBlock}" >
<Setter Property="FontSize" Value="20"/>
</Style>
In my app.xaml, I merge it globally:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Theme/Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The problem is that the text "Select a Date" in my DatePickers is influenced by the style of the TextBlock, increasing the total height of the Datepicker (only at runtime; in design it looks ok).
When you start typing a date (or select one using the calendar) it does not inherit from TextBlock style. The problem is only the text "Select a Date".
I don't want to set a Key for every textblock in my app.
What do I do to fix this?
EDIT
Looking closer at the MSDN documentation, we can see that the text of a TextBox control is displayed inside a FrameworkElement, and not a TextBlock.
http://msdn.microsoft.com/en-us/library/ms752068%28v=vs.110%29.aspx
And the DatePicker has it's value displayed as a TextBox. But the text "Select a Date" seems to be a TextBlock over the TextBox.
EDIT 2
I can access the TextBox template inside the DatePicker:
http://msdn.microsoft.com/en-us/library/ff468215%28v=vs.110%29.aspx
But nothing about the textblock...
You are correct by viewing the style of datepicker control you will not able to find your textblock for Select a date. as this is a watermark value on the textbox within the datepicker control. you will require to edit the style of this textbox within this datepicker.
The textbox used within datepicker control is DatepickerTextbox. You will require to modify the style of this textbox. This is quite easy by using expression blend.
<Style x:Key="DatePickerTextBoxStyle1" TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<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>
<ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement"/>
<ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="watermark_decorator"/>
</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="PART_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}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="1" Padding="{TemplateBinding Padding}">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="1"/>
<Border x:Name="watermark_decorator" BorderBrush="#FFFFFFFF" BorderThickness="1">
<ContentControl x:Name="PART_Watermark" Focusable="False" IsHitTestVisible="False" Opacity="0" Padding="2"/>
</Border>
<ScrollViewer x:Name="PART_ContentHost" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="#FF45D6FA" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You will need to modify the style PART_Watermark control that is Content control in above style. by modifying this style it will resolve your problem.

Changing Style of objects inside controltemplate

I made a new control which contains a rectangle in it with and some visual states.
<Style TargetType="Button" x:Key="banda">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="#FF47B215" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation Duration="0" To="{Binding Background, ElementName=Border}" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FF86B072" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" Background="purple" StrokeThickness="5" Stroke="{Binding Background, ElementName=Border}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This control is used many times in my application page and I'd like the rectangle to have different colour value every time it's used, for example when I press a button, the rectangle changes colour.
I don't have idea how to change the property of the rectangle inside the c# code though. Can someone help me with the formatting?
No sweat, just build that functionality into the template by binding the Background of it like so;
<Style TargetType="Button" x:Key="banda">
<Setter Property="Background" Value="Purple"/>
<Setter Property="BorderThickness" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="#FF47B215" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation Duration="0" To="{Binding Background, ElementName=Border}" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FF86B072" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{Binding Background, ElementName=Border}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So this way, the default color will be Purple (as seen in the Setter declaration) and you can change it on the fly like;
<Button Style="{StaticResource banda}" Content="Blah" Background="Orange"/>
However; it is normally recommended you don't attach to many state changes to a single object. For example if you load your template into Expression blend you'll and you look at your States Panel while editing your template, you'll see a triangle exclamation mark icon warning you that its not advised to base too many states around a single object in your template. Most of the time its fine though and will work as is. Also you had Stroke & StrokeThickness applied to a Border which doesn't have those Dependency Properties, so in the example I fixed that as well to BorderThickness and BorderBrush. Oh and you're probably also going to find how you have your properties so inter-relationship bound its going to cause you troubles. Ditch the things like;
<VisualState x:Name="Normal">
<Storyboard>
<ColorAnimation Duration="0" To="{Binding Background, ElementName=Border}" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="Border" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
and instead just bind it to the Background property via {TemplateBinding Background} instead. I would suggest looking at some of the default control templates for Buttons and comparing to learn more of how they're used.
Hope this helps.

Animation object cannot be used to animate RenderTransform

I have a ToggleButton to which I'm applying the following style
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="MouseOverBorder">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)" Storyboard.TargetName="normal" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" To="180" Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)" Storyboard.TargetName="normal"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate"/>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused"/>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border Background="#FF181615" Grid.Row="2" Grid.ColumnSpan="3" CornerRadius="4" Width="100" Height="20"/>
<Border x:Name="MouseOverBorder" Background="{StaticResource ButtonHoverFill}" Grid.Row="2" Grid.ColumnSpan="3" CornerRadius="4" Width="100" Height="20" Visibility="Collapsed"/>
<StackPanel Orientation="Horizontal" Margin="5,0,5,0">
<Path x:Name="normal"
HorizontalAlignment="Center"
Width="10"
Stretch="Fill"
Opacity="1"
Data="M1,6 C1,6 1,11 1,11 C1,11 7.5,6.3583374 7.5,6.3583374 C7.5,6.3583374 14,11 14,11 C14,11 14,6 14,6 C14,6 7.5,1.3583374 7.5,1.3583374 C7.5,1.3583374 1,6 1,6 z"
Fill="White" UseLayoutRounding="False" VerticalAlignment="Center" Height="9" Stroke="White" RenderTransformOrigin="0.5,0.5" >
<Path.RenderTransform>
<RotateTransform Angle="180"/>
</Path.RenderTransform>
</Path>
<TextBlock Text="Input" FontFamily="Calibri" Margin="5,2,0,0" FontSize="12" Foreground="White"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The xaml editor however throws the error,
Error 1 'System.Windows.Media.Animation.DoubleAnimation' animation object cannot be used to animate property 'RenderTransform' because it is of incompatible type 'System.Windows.Media.Transform'.
but this seems to work fine if i run the executable. Can someone tell me why rendertransform is refusing to be animated in the xamleditor?
Could you try revising the definition of the RenderTransform to use a TransformGroup like this:
<Path x:Name="normal" ... >
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
And then change the path to the property in the DoubleAnimation to look like this:
<DoubleAnimation
Duration="0:0:0.3"
To="0"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"
Storyboard.TargetName="normal"
/>
This structure seems to be the what the tooling prefers.

Categories