WPF scaleX and scaleY animation - c#

I am trying to animation scaleX and scaleY on ellipse.
simply I want to animation scaleX and scaleY in 2 cases:
When background is green I want to anmitaion scaleX and scaleY from 0 to 1.
When background is red I want to animtaion scaleX and scaleY from 1 to 0
For some reason scale animation from 0 to 1 succeeded and from 1 to 0 didn't worked at all.
Code example:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
<Window.Resources>
<Storyboard x:Key="CheckedEllipseON">
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="CheckedEllipseOFF">
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="CheckedEllipseScale">
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.0" />
<LinearDoubleKeyFrame Value="0" KeyTime="0:0:0.1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Style TargetType="ToggleButton" x:Key="MyToggleButtonStyle">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Width" Value="40"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid ClipToBounds="True" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Ellipse Fill="Green" x:Name="CheckedEllipse" RenderTransformOrigin="0.5, 0.5">
<Ellipse.RenderTransform>
<ScaleTransform CenterX="0.5" CenterY="0.5" ScaleX="1.0" ScaleY="1.0" x:Name="CheckedEllipseScale"/>
</Ellipse.RenderTransform>
</Ellipse>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Red">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource CheckedEllipseOFF}"/>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Green">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource CheckedEllipseON}"/>
</DataTrigger.EnterActions>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton" BasedOn="{StaticResource MyToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Test}" Value="true">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
<DataTrigger Binding="{Binding Test}" Value="false">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Button Command="{Binding TestCommand}" VerticalAlignment="Bottom" Width="100" Height="50"/>
</Grid>
Test property and TestCommand is only for changing colors green and red by boolean property.
Thank you.

There are actually two different problems in the code you posted. First, your ellipse background is set explicitly to "Green" and so would never actually change to red. This is a case of the "locally set" property taking precedence over style or trigger setters.
This can be fixed by changing the ellipse declaration:
<Ellipse Fill="{TemplateBinding Background}"
x:Name="CheckedEllipse"
RenderTransformOrigin="0.5, 0.5">
That will cause the ellipse to inherit the background value from the templated parent.
That issue affects only the color that is displayed. The triggers you are using use the ToggleButton.Background, and so are unaffected by that issue. So, why does the animation only work in one direction?
That issue is because you don't stop one animation before starting the other. The default for an animation is to hold its previous value, so once the animation runs to increase the scale, it continues to hold that scale value, causing the attempt by the other animation to reduce the scale to be overridden and ignored.
You can fix that aspect by adding <StopStoryboard/> actions to the triggers:
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Red">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="StoryON"/>
<BeginStoryboard Storyboard="{StaticResource CheckedEllipseOFF}" Name="StoryOFF"/>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding Background,RelativeSource={RelativeSource Mode=Self}}" Value="Green">
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="StoryOFF"/>
<BeginStoryboard Storyboard="{StaticResource CheckedEllipseON}" Name="StoryON"/>
</DataTrigger.EnterActions>
</DataTrigger>
</ControlTemplate.Triggers>
Note that you also have to give the started storyboard a name, so that you can use that name to stop it later.
With those changes, I'm able to click on the button to toggle the scale of the ellipse, causing it to increase in size when green, and decrease (and vanish) when red.

Related

Why is my XAML throwing me a Storyboard object reference error?

So I am trying to create a animation that will run when I click my button.
It's supposed to move "Box" to the right.
However when i try to run the application I get this error.
System.Windows.Markup.XamlParseException: ''Set property
'System.Windows.ResourceDictionary.DeferrableContent' threw an
exception.' Line number '48' and line position '6'.'
Inner Exception InvalidOperationException: Must have a Storyboard
object reference before this trigger action can execute.
I am new to animations so I am not entierly sure why it's throwing that error.
I tried Googleing but I couldnt find any real solutions.
Seems as if it's a scope issue afaik.
Would it be better to create a resource file and use that?
I've heard of people doing so but I'm not sure how to do it.
XAML
<Window x:Class="WooImporter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WooImporter"
mc:Ignorable="d"
Title="WooImporter" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Storyboard x:Key="slideRight">
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
From="0" To="100"
Duration="0:0:0.3"/>
</Storyboard>
</Grid.Resources>
<Grid Column="0"
Background="#272727">
<StackPanel>
<ToggleButton Height="30"
Content="Add Products"
FontSize="18"
Foreground="White"
Style="{DynamicResource MenuToggleButtonStyle}"
x:Name="MenuButton1"/>
</StackPanel>
</Grid>
<Grid Column="1">
<StackPanel Width="100"
Height="100"
Background="#212121"
x:Name="Box"/>
</Grid>
</Grid>
<Window.Resources>
<Style TargetType="ToggleButton"
x:Key="MenuToggleButtonStyle">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=MenuButton1}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{DynamicResource slideRight}"/>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
</Window>
As I suspected it was a scope issue.
I moved the style inside the stackpanel
<Grid Column="1">
<StackPanel Width="100"
Height="100"
Background="#212121"
x:Name="Box">
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=theMenuButton}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource slideRight}" />
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
</Grid>
Static Resource will do the trick but remember that Storyboard must be higher in resource hierarchy than StackPanel style. I mean you should move Storyboard to Window.Resources or StackPanel style to Grid.Resources. StoryBoard must be before StackPanel style. Then To StackPanel Style add RenderTransform Setter. In StoryBoard.TargetProperty you should add (TransformGroup.Children)[0] to show which element you want to transform in TransformGroup.
<Grid.Resources>
<Storyboard x:Key="slideRight">
<Storyboard>
<DoubleAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)"
From="0"
To="1000"
Duration="0:0:0.3" />
</Storyboard>
</Storyboard>
<Style TargetType="StackPanel">
<Setter Property="Background" Value="Green" />
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=MenuButton1}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource slideRight}" />
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>

WPF Style Storyboard To Another Objects Value

Here I have a button style in appliction resources
<Style x:Key="ClickableText" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="FontFamily" Value="/Tasks;component/Assets/Fonts/#Abel"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<StackPanel VerticalAlignment="Center">
<ContentPresenter x:Name="Text" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Rectangle x:Name="Rect1" Width="{Binding ActualWidth, ElementName=Text}" Height="2" Fill="{DynamicResource LightGrey}"/>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In the style I have added a underlining rectangle to the text in the button.
<Rectangle x:Name="Rect1" Width="{Binding ActualWidth, ElementName=Text}" Height="2" Fill="{DynamicResource LightGrey}"/>
I have binded the rectangles width to be the same width as the text so that it adds a underline effect.
I now want to add an effect so that when you hover the button the rectangle reveals by spliting out.
I have got this far by adding this under the trigger tag
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" From="0" To="{Binding ActualWidth, ElementName=Text}" Storyboard.TargetName="Rect1" Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" From="{Binding ActualWidth, ElementName=Text}" To="0" Storyboard.TargetName="Rect1" Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
I want to link the to and from part of the double animation to the binding I used in the rectangle but it keeps producing errors. How can I do this effect?
I also want to use this as a reusable style I can distribute and keep in Application resources. I have seen other people do this through workarounds in code but am not sure if you can do this in application resources
Any help or guidance is greatly appriciated!!
LayoutTransform animation is Better for this effect.
I would do this animation in this way:
<Style x:Key="ClickableText" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="FontFamily" Value="/Tasks;component/Assets/Fonts/#Abel"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="MainBorder" Background="{TemplateBinding Background}">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="2"/>
</Grid.RowDefinitions>
<ContentPresenter x:Name="Text" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Rectangle x:Name="Rect1" Grid.Row="1" Height="2" Width="{Binding ElementName=Text, Path=ActualWidth}" Fill="LightGray">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="0"/>
</Rectangle.LayoutTransform>
</Rectangle>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="MainBorder" Value="White"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Rect1" Storyboard.TargetProperty="(ContentPresenter.LayoutTransform).(ScaleTransform.ScaleX)" From="0" To="1" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Rect1" Storyboard.TargetProperty="(ContentPresenter.LayoutTransform).(ScaleTransform.ScaleX)" From="1" To="0" Duration="0:0:0.2" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>

How to make textblock move up (Float) with animation in WPF

I would like to know how to make a textblock move up (or better to say float up) with animation in Xaml (WPF).
Let's say I have login screen and I have two textblocks: Username and Password. When I click on the textblock (User name or Password) the textblock will move up (float up) with animation effect until the textblock will cross the border line of the box and then the textblock will stop moving. In the same animation, the font size of the text in the textblock Become smaller (for example, from 12px to 6px).
And additionally, in the same animation, when the text moving up I want to add the blur effect to the text, the blur effect start when textblock floating up and return to normal when the textblock cross the line of the box.
In the end, when i click in somewhere else on the Login screen the textblock will return to starting point position if nothing was writen in the box.
I found something similar here
this is my code (that doesn't work)
Xaml:
x:Class="tester.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:tester"
mc:Ignorable="d"
Title="Window1" Height="400" Width="600" >
<Grid>
<Border Margin="246,164,184,175" BorderThickness="1,1,1,1" BorderBrush="Black" >
<Label
Name="Two"
Margin="-1,-11,61,-1"
Width="100" Height="36" FontSize="20"
VerticalAlignment="Top" VerticalContentAlignment="Top"
Foreground="Blue" >
Name
<Label.Effect>
<BlurEffect Radius="0" x:Name="BlurEffect2"/>
</Label.Effect>
<Label.Triggers>
<EventTrigger
RoutedEvent="Label.MouseLeftButtonDown">
<BeginStoryboard>
<Storyboard x:Name="FirstLabelName" Completed="FirstLabelName_Completed" >
<DoubleAnimation
Storyboard.TargetName="Two"
Storyboard.TargetProperty="(Label.Height)"
To="20.0" Duration="0:0:0.3"
AutoReverse="False" />
<DoubleAnimation
Storyboard.TargetName="Two"
Storyboard.TargetProperty="(FontSize)"
To="16" Duration="0:0:0.3"
AutoReverse="False" />
<DoubleAnimation
Storyboard.TargetName="BlurEffect2"
Storyboard.TargetProperty="Radius"
To="10" Duration="0:0:0.3"
AutoReverse="False" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Label.Triggers>
</Label>
</Border>
<Border Margin="0,0,20,50" Height="30" Width="100" BorderThickness="1,1,1,1" BorderBrush="White" >
<Label
Name="one"
Margin="9,-1"
Width="80" Height="30" FontSize="16"
VerticalAlignment="Top" VerticalContentAlignment="Top"
Foreground="Blue" Visibility="Hidden">
Name
<Label.Effect>
<BlurEffect Radius="10" x:Name="BlurEffect"/>
</Label.Effect>
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard x:Name="StoryBoardOne">
<Storyboard x:Name="Effect1" >
<DoubleAnimation
Storyboard.TargetName="one"
Storyboard.TargetProperty="(Label.Height)"
To="30.0" Duration="0:0:0.5"
AutoReverse="False" />
<DoubleAnimation
Storyboard.TargetName="one"
Storyboard.TargetProperty="(FontSize)"
To="12" Duration="0:0:0.3"
AutoReverse="False" />
<DoubleAnimation
Storyboard.TargetName="BlurEffect"
Storyboard.TargetProperty="Radius"
To="0" Duration="0:0:0.5"
AutoReverse="False" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="StoryBoardOne"></StopStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</Border>
</Grid>
</Window>
Back:
private void FirstLabelName_Completed(object sender, EventArgs e)
{
Two.Visibility = Visibility.Hidden;
one.Visibility = Visibility.Visible;
}
So what you're looking for is loosely referred to as inline label inputs. They're not tough but if you want real slick ones it does take some effort into customizing control templates. You need to create your Storyboard animations and trigger them via enter/exit actions within your triggers. Unless you're using VisualStateManager in which case you would trigger the animations via VisualState instead.
Here's a quick PoC example of how you could do something like that to get you started. However I did purposely leave some finishing touches out to avoid just handing a full solution over. Except there should be enough for a quick completion and tuning to fit your needs. Hope this helps, cheers!
The result (in the form of a choppy .gif for visual aid);
...and here's the quick sample made from a default wpf TextBox template.
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel.Resources>
<SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/>
<SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/>
<Style x:Key="CW-Inline-TextBox" TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="35"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Margin" Value="0,25,0,0"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="CW-Inline-input-example">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="textBlock">
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-6.667">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="textBlock">
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="-25.733">
<EasingDoubleKeyFrame.EasingFunction>
<QuinticEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="textBlock">
<EasingColorKeyFrame KeyTime="0:0:0.6" Value="#FF0285BA"/>
</ColorAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontWeight)" Storyboard.TargetName="textBlock">
<DiscreteObjectKeyFrame KeyTime="0:0:0.3">
<DiscreteObjectKeyFrame.Value>
<FontWeight>Bold</FontWeight>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Border x:Name="border" Grid.Row="1"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
<TextBlock x:Name="textBlock" Text="{TemplateBinding Tag}"
VerticalAlignment="Center" Margin="8,0"
Foreground="Gray" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource CW-Inline-input-example}" />
</Trigger.EnterActions>
<!--
<Trigger.ExitActions>
// In case you wanted to do something cool on exit too..
</Trigger.ExitActions>
-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBox Tag="Your label"
Height="35" Width="150" FontSize="20"
Style="{DynamicResource CW-Inline-TextBox}"/>
<TextBox Tag="Your other label"
Style="{DynamicResource CW-Inline-TextBox}"/>
<TextBox Tag="Another Instance"
Height="75" Width="150" FontSize="15"
Style="{DynamicResource CW-Inline-TextBox}"/>
</StackPanel>
And sorry I couldn't respond sooner, been busy. Enjoy :)

RadioButtons in ListBox don't work correctly using with Theme

I want to use a RadioButtonList and want to check one of the RadioButtonList at initial display.
But the radioButtons in ListBox doesn't work correctly using with theme.
I set "Radio1" toSelectedItem1 property in the constructor of ViewModel. but Radio1 doesn't be checked at initial display. If I click Radio2 and click Radio1, Radio1 is checked correctly.
If I remove the theme from app.xaml, Radio1 is checked correctly at the initial display. I downloaded the theme file from http://wpf.codeplex.com/releases/view/14962 .
You can download the project by https://github.com/koty/RadioButtonListTest.
The xaml is:
<Window x:Class="RadioButtonListTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RadioButtonListTest"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<ListBox ItemsSource="{Binding RBItems1}" SelectedItem="{Binding SelectedItem1}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<RadioButton Content="{TemplateBinding Content}"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}" Foreground="Black"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Window>
The ViewModel is:
using System.Windows;
namespace RadioButtonListTest
{
public class MainWindowViewModel : DependencyObject
{
public MainWindowViewModel()
{
this.RBItems1 = new[] { "Radio1", "Radio2" };
this.SelectedItem1 = "Radio1";
}
public static readonly DependencyProperty RBItems1Property
= DependencyProperty.Register("RBItems1",
typeof (string[]),
typeof (MainWindowViewModel),
new PropertyMetadata(default(string[])));
public static readonly DependencyProperty SelectedItem1Property
= DependencyProperty.Register("SelectedItem1",
typeof (string),
typeof (MainWindowViewModel),
new PropertyMetadata(default(string)));
public string[] RBItems1
{
get { return (string[]) GetValue(RBItems1Property); }
set { SetValue(RBItems1Property, value); }
}
public string SelectedItem1
{
get { return (string)GetValue(SelectedItem1Property); }
set { SetValue(SelectedItem1Property, value); }
}
}
}
And the app.xaml is:
<Application x:Class="RadioButtonListTest.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="Themes\ShinyBlue\Theme.xaml"/>
</Application.Resources>
</Application>
You must change a little code in ShinyBlue.xaml.
In the original code there was not one trigger.
Find RadioButtonTemplate and change it with this:
<ControlTemplate x:Key="RadioButtonTemplate" TargetType="{x:Type RadioButton}">
<ControlTemplate.Resources>
<Storyboard x:Key="CheckedFalse">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CheckIcon" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="CheckedTrue">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CheckIcon" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HoverOn">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundOverlay" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HoverOff">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="BackgroundOverlay" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PressedOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Background" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="0.6"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="PressedOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Background" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="16" Height="16">
<Ellipse Height="14"
Margin="1"
x:Name="Background"
Width="14"
Fill="{StaticResource NormalBrush}"
Stroke="{TemplateBinding BorderBrush}"
StrokeThickness="2"/>
<Ellipse Height="12"
x:Name="BackgroundOverlay"
Width="12"
Opacity="0"
Fill="{StaticResource HoverBrush}"
Stroke="#00000000"
Margin="2,2,2,2"
StrokeThickness="0"/>
<Border HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="6"
Height="6"
CornerRadius="1,1,1,1"
BorderThickness="1,1,1,1"
Background="#FFFFFFFF"
x:Name="CheckIcon"
BorderBrush="{StaticResource CheckIconBrush}"
Opacity="0"/>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</BulletDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource CheckedFalse}" x:Name="CheckedFalse_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource CheckedTrue}"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource CheckedTrue}" x:Name="CheckedTrue_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource CheckedFalse}"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HoverOn}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HoverOff}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource PressedOn}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource PressedOff}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="Background" Value="{DynamicResource DisabledBackgroundBrush}"/>
<Setter Property="Stroke" TargetName="Background" Value="{DynamicResource DisabledBorderBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

How to hide datagrid container using DataTrigger if it has no items

I have a datagrid that binds its data from SelectedItem of a TreeView.
The problem is how to auto hide the grid container using DataTrigger if the datagrid has no items ?
<Grid Name="grid1" Visibility="Visible">
<DataGrid Name="datagrid1" ItemsSource="{Binding ElementName=treeview1, Path=SelectedItem}"/>
</Grid>
I think this link may be helpful.
This data trigger worked for me:
<Style TargetType="{x:Type DataGrid}">
<Style.Triggers>
<DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
You could bind to the HasItems property of the datagrid. But since that property is a boolean type and the Grid.Visibility is a Visibility enum, you'd need to convert the boolean to enum. Luckily, there already is an out-of-the-box converter called BooleanToVisibilityConverter.
<Grid Name="grid1" Visibility="{Binding HasItems, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=datagrid1, Mode=OneWay}">
Not sure why you want to use a DataTrigger, but if you want to apply transitions when changing visibility, you could do so by styling the grid and adding a trigger for when Visibility=Visible, like so:
<Style x:Key="GridStyle1" TargetType="{x:Type Grid}">
<Style.Resources>
<Storyboard x:Key="StoryboardShow">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="{x:Null}">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="StoryboardHide">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="{x:Null}">
<SplineDoubleKeyFrame KeyTime="0" Value="1"/>
<SplineDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHide}"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
Then apply this style to the grid:
<Grid Name="grid1" Style="{DynamicResource GridStyle1}" Visibility="{Binding HasItems, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=datagrid1, Mode=OneWay}">
Check the data source in the code behind, during a page load event. If the data source is empty (according to your criteria), then set datagrid1.visible = false. For completeness sake, set it to true if you do find some data worth displaying.
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="2"
CornerRadius="1"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<Grid>
<ItemsPresenter x:Name="ScroItemsPresenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<TextBlock x:Name="Block" Text="asd"></TextBlock>
</Grid>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}"
Value="True">
<Setter TargetName="Block" Property="Visibility" Value="Hidden"></Setter>
<Setter TargetName="ScroItemsPresenter" Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
HasItems:
noItems:

Categories

Resources