using transformgroup in wpf gives an error - wpf

i was searching for combining multiple transform in an object and i found out how but the problem is when i try to put transformgroup, it gives an error "Cannot resolve all property references in the property path 'RenderTransform.ScaleX'. Verify that applicable objects support the properties."
here's my transformation code which i copied from the net ("thanks to those who made this code")
<Window.Resources>
<Storyboard x:Key="expandStoryboard">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1.3" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1.3" Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="shrinkStoryboard">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX"
To="1" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY"
To="1" Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="shakeStoryBoard">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
From="-5" To="5" Duration="0:0:0.05"
AutoReverse="True"
RepeatBehavior="3x"
FillBehavior="Stop" />
</Storyboard>
and this is my object (button)
<Button RenderTransformOrigin="0.5,0.5" Background="Transparent" Focusable="False" BorderBrush="Transparent" Height="220" HorizontalAlignment="Left" Margin="591,213,0,0" Name="cmdsettings" VerticalAlignment="Top" Width="189">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center" Width="217" Height="220">
<Image HorizontalAlignment="Center" VerticalAlignment="Center" Source="Images/settings.png" Height="192" Width="204" />
<TextBlock VerticalAlignment="center" TextAlignment="center" FontSize="16" Width="123" Foreground="white" FontWeight="Bold" Height="20">Settings</TextBlock>
</StackPanel>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource expandStoryboard}" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource shrinkStoryboard}" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard Storyboard="{StaticResource shakeStoryBoard}" />
</EventTrigger>
</Button.Triggers>
<Button.RenderTransform >
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<RotateTransform />
</TransformGroup>
</Button.RenderTransform>
</Button>

Since Button.RenderTransform contains a TransformGroup, you would have to access the contained Transforms by its Children property:
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX" ... />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY" ... />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Children[1].Angle" ... />

Related

Animate an image and text in a TabHeader when selected and when mouse is over

I have a tabControl that Contain several TabHeaders,I made it so that the text size of the TabHeader will shrink a little when mouse is over and will become bigger when the TabHeader is selected. I want to add an image into the TabHeader that will act the same way and to act as one item with the text so that both the text and the image will shrink a little when mouse is over and get bigger when TabHeader is selected. Right now both do that but separately meaning that they animate when I hover or click either of them and I want them to act as one
here is the xaml of the TabHeader
<TabItem.Header>
<StackPanel>
<Grid ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="SalesImg" HorizontalAlignment="Center" VerticalAlignment="Center" Source="Images/Sales.png">
<Image.RenderTransform>
<ScaleTransform x:Name="scale" CenterX="50" CenterY="50" ScaleX="1" ScaleY="1" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseEnter">
<BeginStoryboard>
<BeginStoryboard.Storyboard>
<Storyboard Duration="0:0:0.2">
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" To="1.5" />
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" To="1.5" />
</Storyboard>
</BeginStoryboard.Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Image.MouseLeave">
<BeginStoryboard>
<BeginStoryboard.Storyboard>
<Storyboard Duration="0:0:0.2">
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" To="1" />
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" To="1" />
</Storyboard>
</BeginStoryboard.Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
<TextBlock Grid.Column="1" Text="Sales" HorizontalAlignment="Center" />
</Grid>
</StackPanel>
</TabItem.Header>
You can put the container of the image and text - in this case, a grid - into a ViewBox, and animate on the ViewBox.
ViewBox takes the all the contents inside it as a single child, so both image and text will grow and shrink in size as a whole.
<TabItem.Header>
<Grid Width="126" Height="48">
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<BeginStoryboard.Storyboard>
<Storyboard Duration="0:0:0.2">
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" To="1.5" />
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" To="1.5" />
</Storyboard>
</BeginStoryboard.Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<BeginStoryboard.Storyboard>
<Storyboard Duration="0:0:0.2">
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" To="1" />
<DoubleAnimation Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" To="1" />
</Storyboard>
</BeginStoryboard.Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Viewbox Width="84" Height="32">
<Viewbox.RenderTransform>
<ScaleTransform x:Name="scale" CenterX="42" CenterY="16" ScaleX="1" ScaleY="1" />
</Viewbox.RenderTransform>
<Grid ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="SalesImg" HorizontalAlignment="Center" VerticalAlignment="Center"
Source="Images/Sales.png"/>
<TextBlock Grid.Column="1" Text="Sales" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Viewbox>
</Grid>
</TabItem.Header>

How to add animation to margin property of TextBlock in WPF

I want to make TextBlock like this
But,
aTextBlock.BeginAnimation(Button.MarginProperty, myDoubleAnimation);
get this error
'System.Windows.Media.Animation.DoubleAnimation' cannot be used to animate the 'Margin' property of type 'System.Windows.Thickness'.
I have test in Xaml and get same error:
<Border CornerRadius="8" Background="Red" Margin="352,173,214,368">
<TextBlock x:Name="TestB"
Text="{Binding ElementName=MTxt,Path=Text,NotifyOnSourceUpdated=True}"
Margin="0,0,0,0"
HorizontalAlignment="Center"
Foreground="White"
FontWeight="Bold"
FontSize="16">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="TestB"
Storyboard.TargetProperty="(TextBlock.Margin)"
To="2"
Duration="0:0:1" AutoReverse="True"
RepeatBehavior="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Border>
What is your idea?
You need to use ThicknessAnimation for this. DoubleAnimation is for properties of Double type.
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation
Storyboard.TargetName="TestB"
Storyboard.TargetProperty="(TextBlock.Margin)"
To="2"
Duration="0:0:1" AutoReverse="True"
RepeatBehavior="2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>

Can't make an animation work WPF

I can't make this animation work:
<Ellipse Opacity="0.7" Width="150" Height="50" StrokeThickness="5">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation From="0" To="100" Duration="0:0:2" Storyboard.TargetProperty="LayoutTransform.Y" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
Basically it's an Ellipse that translates from a starting point at Y to an ending point of Y. But basically, it doesn't move, and launches a mistake... Any ideas?
Animating the LayoutTransform will not move the object. What you are looking for is an animation of the RenderTransform property:
You have to put a TranslateTransform into Ellipse.RenderTransform and change Storyboard.TargetProperty:
<Ellipse Opacity="0.7" Width="150" Height="50" StrokeThickness="5" Stroke="Black">
<Ellipse.RenderTransform>
<TranslateTransform />
</Ellipse.RenderTransform>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" AutoReverse="True">
<DoubleAnimation From="0" To="100" Duration="0:0:2"
Storyboard.TargetProperty="RenderTransform.Y" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
To keep it simple you can put ellipsis in a canvas :
<Canvas>
<Ellipse Width="30" Height="30" Fill="Purple" Canvas.Top="0" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded" >
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:5" AutoReverse="True" Storyboard.TargetProperty="(Canvas.Top)" To="100" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Canvas>

EventTrigger RoutedEvent in wpf xaml

I have a problem in wpf xaml and i'm pretty new on this so it may be something basic
i want to rotate a ellipse 360 degree
<Ellipse Name="test" Fill="Black" StrokeThickness="5" Margin="0,0,0,0" Height="66">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded" SourceName="test">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="test"
Storyboard.TargetProperty="(Ellipse.RenderTransform).(RotateTransform.Angle)"
From="0"
To="360"
Duration="0:0:0.5"
RepeatBehavior="1x" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
But nothing happens, what is wrong?
First of all. you will need the RotateTransform object in your ellipse:
<Ellipse.RenderTransform>
<RotateTransform x:Name="transform" />
</Ellipse.RenderTransform>
Change these properties in your Storyboard:
Storyboard.TargetName="transform"
Storyboard.TargetProperty="Angle"
And it should work!
You can also only change the TargetProperty, and leave the TargetName on test:
Storyboard.TargetName="test"
Storyboard.TargetProperty="RenderTransform.Angle"
That way, your RotateTransform object does not need a name!
Putting it all together:
<Ellipse Name="test" Fill="Black" StrokeThickness="5" Margin="0,0,0,0" Height="66">
<Ellipse.RenderTransform>
<RotateTransform />
</Ellipse.RenderTransform>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded" SourceName="test">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="test"
Storyboard.TargetProperty="RenderTransform.Angle"
From="0" To="360" Duration="0:0:0.5" RepeatBehavior="1x" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>

WPF - Can't get storyboard to affect another local resource

I've set up a Transformation and a Storyboard as local resources, but when I trigger the storyboard from a button I get the following error:
{"'WorldTranslation' name cannot be found in the name scope of 'System.Windows.Controls.Button'."}
Can someone point me in the right direction please?
<Window.Resources>
<Transform3DGroup x:Key="WorldTranslation">
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="myAngleRotation" Axis="0,1,0" Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
<Storyboard x:Key="MyStoryboard">
<DoubleAnimation
Storyboard.TargetName="WorldTranslation"
Storyboard.TargetProperty="(Transform3DGroup).(RotateTransform3D).(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)"
From="0"
To="360"
Duration="0:0:1"
/>
</Storyboard>
</Window.Resources>
And heres the button xaml ...
<Button Height="20" Width="100">
<Button.Content>Blah</Button.Content>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource MyStoryboard}" >
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
There are several things wrong in you XAML. I will start with the transform inline and then refactor it to resources. I changed to a 2D RotateTransform as not to complicate matters unnecessarily.
We start with:
<Button Height="20" Width="100"
RenderTransformOrigin=".5,.5"
Content="Blah">
<Button.RenderTransform>
<RotateTransform Angle="0" x:Name="MyAnimatedTransform"/>
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyAnimatedTransform"
Storyboard.TargetProperty="(RotateTransform.Angle)"
From="0.0" To="360" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
Then we take out the StoryBoard:
<Window.Resources>
<Storyboard x:Key="MyStoryBoard">
<DoubleAnimation
Storyboard.TargetName="MyAnimatedTransform"
Storyboard.TargetProperty="(RotateTransform.Angle)"
From="0.0" To="360" Duration="0:0:.3" />
</Storyboard>
</Window.Resources>
<Grid>
<Button Height="20" Width="100"
RenderTransformOrigin=".5,.5"
Content="Blah">
<Button.RenderTransform>
<RotateTransform Angle="0" x:Name="MyAnimatedTransform"/>
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource MyStoryBoard}"/>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
And finally the RotateTransform. Referencing this by the Storyboard.TargetName property does not work here. You need the Storyboard.Target property:
<Window.Resources>
<RotateTransform Angle="0" x:Key="WorldTransform"/>
<Storyboard x:Key="MyStoryBoard">
<DoubleAnimation
Storyboard.Target="{Binding TemplatedParent}"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
From="0.0" To="360" Duration="0:0:.3" />
</Storyboard>
</Window.Resources>
<Grid>
<Button Height="20" Width="100"
RenderTransformOrigin=".5,.5"
Content="Blah">
<Button.RenderTransform>
<StaticResource ResourceKey="WorldTransform" />
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource MyStoryBoard}"/>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
EDIT: due to bonus question ;-)
Suppose you want the transform to take place on the containing grid. Simply catch the Button.Click event in the Grid (events are routed remember?) and put the trigger there. The TemplatedParent will now be the grid and no longer the button.
<Grid RenderTransformOrigin=".5,.5">
<Grid.RenderTransform>
<StaticResource ResourceKey="WorldTransform"/>
</Grid.RenderTransform>
<Grid.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource MyStoryBoard}"/>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Button Height="20" Width="100"
Content="Blah">
</Button>
</Grid>

Resources