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

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>

Related

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>

using transformgroup in wpf gives an error

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" ... />

how to popout the image in wpf not only the height and width but also left and top?

hi guyz i saw and tried the code using scaletransform from andrej blog on how to popout the image smoothly and it's nice. here's the code
<Window.Resources>
<Storyboard x:Key="expandStoryboard">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX"
To="2" Duration="0:0:0.2" />
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY"
To="2" Duration="0:0:0.2" />
</Storyboard>
<!-- This storyboard will make the image revert to its original size -->
<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>
</Window.Resources>
and in grid area, something like this:
<Image Name="image2" Source="C:\Documents and Settings\My Documents\Visual Studio 2010\settings_256.png" Margin="23,44,372,221" HorizontalAlignment=" center" VerticalAlignment="Center" >
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource expandStoryboard}" />
</EventTrigger>
<EventTrigger RoutedEvent="Image.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource shrinkStoryboard}" />
</EventTrigger>
</Image.Triggers>
<Image.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Image.RenderTransform>
</Image>
so when im going to point my mouse in the image it will resize the height and the width of the image smoothly. but what i want to do also is if im going to do mouseover, i want my left and top of the image will change the position like decreasing the margin something like image1.margin(left-5,top-5). so it will pop the image out as width++ height++ left-- top--
anyone? thanks and God bless :)
You could use UIElement.RenderTransformOrigin Property:
<Image RenderTransformOrigin="0.5, 0.5"
Name="image2" Source="C:\Documents and Settings\My Documents\Visual Studio 2010\settings_256.png"
Margin="23,44,372,221" HorizontalAlignment="center" VerticalAlignment="Center">
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource expandStoryboard}" />
</EventTrigger>
<EventTrigger RoutedEvent="Image.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource shrinkStoryboard}" />
</EventTrigger>
</Image.Triggers>
<Image.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1"/>
</Image.RenderTransform>
</Image>

Problem animating a WPF button

I have a button, this is a unique button, and his style should çn't match the style of all the others. So when you pass your mouse over this button, it should change its image. But it is not working, Here is the code... I'm starting at WPF so if you can point me what am I doing wrong would be really appreciated
<Button Name="RemoveButton" ClickMode="Press" BorderThickness="0" Background="Transparent" Style="{StaticResource ButtonStyle1}">
<Button.Content>
<Grid>
<Image x:Name="CloseActive" x:FieldModifier="public" Height="12" VerticalAlignment="Center" Source="/HTFS.Atlas.Portfolio.PortfolioClient.WCF.Controls;component/Images/tab-close.png" Visibility="Hidden" />
<Image x:Name="CloseInactive" x:FieldModifier="public" Height="12" VerticalAlignment="Center" Source="/HTFS.Atlas.Portfolio.PortfolioClient.WCF.Controls;component/Images/tab-close-inactive.png" />
</Grid>
</Button.Content>
<Button.Resources>
<Storyboard x:Key="MouseOverAnimation">
<DoubleAnimation Storyboard.TargetName="CloseActive" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="CloseInactive" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:0.5" />
</Storyboard>
<Storyboard x:Key="MouseOutAnimation">
<DoubleAnimation Storyboard.TargetName="CloseInactive" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="CloseActive" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:0.5" />
</Storyboard>
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Control}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Resources>
</Button>
For the CloseActive image, instead of using Visibility="Hidden" try Opacity="0".
In your animation you're adjusting the opacity of the image, but it's still hidden.
In addition to removing the visibility attribute, try putting the animation triggers directly in Button.Triggers
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
</EventTrigger>
</Button.Triggers>
since you can't use Storyboard.TargetName in a storyboard called from a style. You'll also have to use event triggers instead of normal triggers.
You can also remove the CloseButtonStyle since it won't be used.

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>

Resources