I'm trying to make a Canvas move up and down, which should be a simple task, but I somehow can't do it:
<Window.Resources>
<TranslateTransform x:Key="transform1" x:Name="testTransform" X="-24" Y="0" />
<Storyboard x:Key="storyboard1">
<DoubleAnimation Duration="0:0:0.4" Storyboard.TargetName="testTransform" Storyboard.TargetProperty="Y" By="6"
AutoReverse="True" RepeatBehavior="Forever" EasingFunction="{StaticResource ease1}" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource storyboard1}" />
</EventTrigger>
</Window.Triggers>
[...]
<Canvas x:Name="canvas1" RenderTransform="{StaticResource transform1}">
<Path Data="{StaticResource amazingPath}" />
</Canvas>
Instead of smoothly animating that Canvas, I get this:
An unhandled exception of type 'System.InvalidOperationException' occurred in PresentationFramework.dll
Additional information: 'testTransform' name cannot be found in the name scope of 'TestProject.MainWindow'.
What's going on here?
It works if you set Storyboard.Target="{StaticResource transform1}" and if your put the EventTrigger in a Window Style:
<Window.Resources>
<TranslateTransform x:Key="transform1" X="-24" Y="0" />
<Storyboard x:Key="storyboard1">
<DoubleAnimation
Duration="0:0:0.4"
Storyboard.Target="{StaticResource transform1}"
Storyboard.TargetProperty="Y" By="6"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</Window.Resources>
<Window.Style>
<Style TargetType="Window">
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource storyboard1}" />
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Style>
<Canvas RenderTransform="{StaticResource transform1}">
...
</Canvas>
Set the Storyboard.TargetName property to the name of the element (Canvas) to which the TranslateTransform is applied.
This works:
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<TranslateTransform x:Key="transform1" x:Name="testTransform" X="-24" Y="0" />
<Storyboard x:Key="storyboard1">
<DoubleAnimation Duration="0:0:0.4" Storyboard.TargetName="canvas1"
Storyboard.TargetProperty="RenderTransform.Y" By="6" AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard Storyboard="{StaticResource storyboard1}" />
</EventTrigger>
</Window.Triggers>
<Canvas x:Name="canvas1" RenderTransform="{StaticResource transform1}">
<TextBlock>...</TextBlock>
</Canvas>
</Window>
Related
I am working on a WPF app where I would like to be able to change the Easing function at runtime. This could be done either in code behind or via a combobox selection. I just can't figure out how to do it.
Here is my code:
<Window x:Class="WpfAnimationExample.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:WpfAnimationExample"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="800">
<Window.Resources>
<Style x:Key="EllipseEasing" TargetType="Ellipse">
<Setter Property="Width" Value="30"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Fill" Value="Blue"/>
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="760" Duration="0:0:6"
Storyboard.TargetProperty="(Canvas.Left)" FillBehavior="Stop"/>
<DoubleAnimation Name="VerticalAnimation" To="330" Duration="0:0:6"
Storyboard.TargetProperty="(Canvas.Top)" FillBehavior="Stop">
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="Easeout"></BounceEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<Canvas Name="Canvas">
<Ellipse Name="MainEllipse" Style="{StaticResource EllipseEasing}" Canvas.Top="60" MouseEnter="Ellipse_MouseEnter" />
</Canvas>
</StackPanel>
The part I wish to alter at runtime is
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="Easeout"></BounceEase>
</DoubleAnimation.EasingFunction>
Thoughts? As always TIA.
My xaml is
<Grid DockPanel.Dock="Top" >
<DockPanel Background="#bdbec0" MouseEnter="showTopMenu_MouseEnter" HorizontalAlignment="Stretch" Height="55" >
<Button HorizontalAlignment="Center" VerticalAlignment="Center">Down</Button>
</DockPanel>
<DockPanel Background="#151515" LastChildFill="True" Visibility="Collapsed" Name="TopMenuArea" Height="55">
some controls here in a horizontal strip , by default its hidden and when some one click on top button its visible and it wil be hidden when some one click outside this area
</DockPanel>
And code for button mouse over is
private void showTopMenu_MouseEnter(object sender, MouseEventArgs e)
{
TopMenuArea.Visibility = Visibility.Visible;
}
How can i apply a animation effect while changing the visibility of TopMenuArea ? Is any way to do it from xaml directly?
Eventtrigger
<DockPanel Background="#bdbec0" MouseEnter="showTopMenu_MouseEnter" HorizontalAlignment="Stretch" Height="55" >
<DockPanel.Triggers>
<EventTrigger RoutedEvent="DockPanel.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TopMenuArea"
From="0.0" To="1.0" Duration="0:0:1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="DockPanel.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TopMenuArea"
From="1.0" To="0" Duration="0:0:1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DockPanel.Triggers>
<Button HorizontalAlignment="Center" VerticalAlignment="Center">Down</Button>
</DockPanel>
<DockPanel Background="#151515" LastChildFill="True" Visibility="Collapsed" Opacity="0" Name="TopMenuArea" Height="55">
</DockPanel>
Or use a style for fade in and out (with mouse enter / exit eventhandler like you did it)
<Style TargetType="FrameworkElement" x:Key="VisibleAnimation">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0.0" To="1.0" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<DockPanel Background="#151515" LastChildFill="True" Style="{StaticResource VisibleAnimation}" Name="TopMenuArea" Height="55">
Just define the style in your App Resources, or in the local Window or UserControl. You reuse the Animation style for any control.
use this in your Stackpanel
<StackPanel Background="Red" HorizontalAlignment="Stretch" >
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.MouseLeftButtonDown" >
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TopMenuArea"
From="1.0" To="0" Duration="0:0:1"></DoubleAnimation>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TopMenuArea"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:2" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<Label HorizontalAlignment="Center">Area outside top panel . Clicking here will hide top panel again</Label>
</StackPanel>
It's an old question, but I've put together an open source library to allow fading and/or translation on Visibility changed, Loaded or binding.
You can find it at SciChart.Wpf.UI.Transitionz on Github and on NuGet.
Usage:
<Window x:Class="WpfApplication15.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:tz="http://schemas.abtsoftware.co.uk/transitionz"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="b2vc"></BooleanToVisibilityConverter>
</Window.Resources>
<Grid>
<CheckBox x:Name="CheckBox" Content="Is Visible?" IsChecked="False"></CheckBox>
<TextBlock Text="Hello World!" FontSize="44" HorizontalAlignment="Center" VerticalAlignment="Center"
Visibility="Collapsed"
tz:Transitionz.Opacity="{tz:OpacityParams From=0, To=1, Duration=200, TransitionOn=Visibility}"
tz:Transitionz.Translate="{tz:TranslateParams From='10,0', To='0,0', Duration=200, TransitionOn=Visibility}"
tz:Transitionz.Visibility="{Binding ElementName=CheckBox, Path=IsChecked, Converter={StaticResource b2vc}}"/>
</Grid>
</Window>
Which results in:
This would be a good start.
You can just add one c# file and set property like below.
common:VisibilityAnimation.AnimationType="Fade"
here is a sample example
<Grid DockPanel.Dock="Top">
<DockPanel Background="#bdbec0"
x:Name="topPanel"
HorizontalAlignment="Stretch"
Height="55">
<Button HorizontalAlignment="Center"
VerticalAlignment="Center">Down</Button>
</DockPanel>
<DockPanel Background="#151515"
LastChildFill="True"
Name="TopMenuArea"
IsHitTestVisible="False"
Height="55">
<TextBlock Foreground="White"> some controls here in a horizontal strip , by default its hidden and when some one click on top button its visible and it wil be hidden when some one click outside this area</TextBlock>
<DockPanel.Style>
<Style TargetType="DockPanel">
<Setter Property="Opacity"
Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver,ElementName=topPanel}"
Value="true">
<Setter Property="Opacity"
Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
</DockPanel>
</Grid>
in the sample above I have set IsHitTestVisible="False" on the TopMenuArea dockPanel, as i can see that it is on top of previous (source for trigger panel)
other option is to use the TopMenuArea as the source if it is on the top
sample
<Grid DockPanel.Dock="Top">
<DockPanel Background="#bdbec0"
HorizontalAlignment="Stretch"
Height="55">
<Button HorizontalAlignment="Center"
VerticalAlignment="Center">Down</Button>
</DockPanel>
<DockPanel Background="#151515"
LastChildFill="True"
Name="TopMenuArea"
Height="55">
<TextBlock Foreground="White"> some controls here in a horizontal strip , by default its hidden and when some one click on top button its visible and it wil be hidden when some one click outside this area</TextBlock>
<DockPanel.Style>
<Style TargetType="DockPanel">
<Setter Property="Opacity"
Value="0" />
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Opacity"
Value="1" />
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
</DockPanel>
</Grid>
give it a try and see if it is close to what you are looking for.
both of above just switch the opacity between 0 & 1, you may also use animation to make a fade effect if needed.
I come up with a way to gradually show Grid and hide Grid using ScaleTransform.
The ScaleTransform is set to X=0 Y=0 to hide, X=1 Y=1 to show,
and Trigger using Tag property, as the code below:
At ViewModel:
private string _helpVisiblilityTag = "hide";
public string HelpVisiblilityTag
{
get { return _helpVisiblilityTag; }
set
{
_helpVisiblilityTag = value;
NotifyOfPropertyChange(() => HelpVisiblilityTag);
}
}
public void Hide()
{
HelpVisiblilityTag = "hide";
}
public void Show()
{
HelpVisiblilityTag = "show";
}
At View:
<Button Click="Show"/>
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Tag="{Binding HelpVisiblilityTag}"
RenderTransformOrigin="0.5, 0.5" >
<Grid.Background>
<SolidColorBrush Color="#D4F1FA" Opacity="0.8"/>
</Grid.Background>
<Grid.RenderTransform>
<ScaleTransform x:Name="MyAnimatedScaleTransform"
ScaleX="0" ScaleY="0" />
</Grid.RenderTransform>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<Trigger Property="Tag" Value="show">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0.0" To="1.0" Duration="0:0:1" AutoReverse="False" />
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
From="0.0" To="1" Duration="0:0:1" AutoReverse="False"
>
<DoubleAnimation.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="1"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
From="0.0" To="1" Duration="0:0:1" AutoReverse="False"
>
<DoubleAnimation.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="1"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Duration="0:0:0.5" AutoReverse="False" />
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
From="1" To="0.0" Duration="0:0:0.5" AutoReverse="False"
/>
<DoubleAnimation
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
From="1" To="0.0" Duration="0:0:0.5" AutoReverse="False"
/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Button Click="Hide"/>
</Grid>
Sample Screenshot:
You can use ToggleButton Checked and UnChecked Routed Event with Event Trigger:
<ToggleButton Content="Toggle" Height="20" Width="60" Panel.ZIndex="2" VerticalAlignment="Top" HorizontalAlignment="Left">
<ToggleButton.Triggers>
<EventTrigger RoutedEvent="ToggleButton.Checked">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="MyDockPanel"
Storyboard.TargetProperty="Opacity"
From="0" To="1"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Unchecked">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyDockPanel"
Storyboard.TargetProperty="Opacity"
From="1" To="0"
Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToggleButton.Triggers>
</ToggleButton>
<DockPanel x:Name="MyDockPanel" Background="Yellow" Opacity="0">
<TextBlock DockPanel.Dock="Bottom" Text="DockPanel"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DockPanel>
Result:
I have this xaml:
<Window x:Class="StoryboardTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="RenderTransformOrigin" Value="0.5 0.5"/>
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform x:Name="rt" Angle="0"/>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column="1" Content="Start">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation From="0" To="100" Storyboard.TargetName="pbar" Storyboard.TargetProperty="Value" Duration="0:0:6"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Grid.Row="1" Content="1" x:Name="btn1">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard x:Name="bs1">
<Storyboard>
<DoubleAnimation From="0" To="90" Storyboard.TargetProperty="RenderTransform.Angle" Duration="0:0:1" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Grid.Row="1" Grid.Column="1" Content="2" x:Name="btn2">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard x:Name="bs2">
<Storyboard>
<DoubleAnimation From="0" To="90" Storyboard.TargetProperty="RenderTransform.Angle" Duration="0:0:1" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Grid.Row="1" Grid.Column="2" Content="3" x:Name="btn3">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard x:Name="bs3">
<Storyboard>
<DoubleAnimation From="0" To="90" Storyboard.TargetProperty="RenderTransform.Angle" Duration="0:0:1" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<ProgressBar x:Name="pbar" Maximum="100" Grid.Row="2" Grid.ColumnSpan="3"/>
</Grid>
</Window>
As you can see there are 4 buttons(Start button - the main one, buttons 1, 2 and 3) and a progress bar. When I click buttons 1,2 or 3 they rotate slightly. My question is how can I trigger that rotations(which are described by respective storyboards) in Start's button EventTrigger? Is it possible to achieve this not writing 3 other storyboards in the Start button but invoking already attached storyboards for buttons 1,2,3 in xaml only?
<Window.Resources>
<Storyboard x:Key="StoryboardName">
<DoubleAnimation From="0" To="90" Storyboard.TargetProperty="RenderTransform.Angle" Storyboard.TargetName="btn1" Duration="0:0:1" AutoReverse="True"/>
<DoubleAnimation From="0" To="90" Storyboard.TargetProperty="RenderTransform.Angle" Storyboard.TargetName="btn2" Duration="0:0:1" AutoReverse="True"/>
<DoubleAnimation From="0" To="90" Storyboard.TargetProperty="RenderTransform.Angle" Storyboard.TargetName="btn3" Duration="0:0:1" AutoReverse="True"/>
</Storyboard>
</Window.Resources>
<Button Grid.Column="1" Content="Start">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard Storyboard="{StaticResource StoryboardName}"/>
</EventTrigger>
</Button.Triggers>
</Button>
Doubleanimations declared in storyboard will run simultaneously.
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=start, Path=IsPressed}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
...
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Someone suggested this for me to use as an animation:
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="600">
<Window.Resources>
<Storyboard x:Key="ScaleImageStoryboard">
<DoubleAnimation Duration="0:0:0.2" From="1" To="1.2" AutoReverse="True"
Storyboard.TargetName="ScaleImage" Storyboard.TargetProperty="ScaleX"/>
<DoubleAnimation Duration="0:0:0.2" From="1" To="1.2" AutoReverse="True"
Storyboard.TargetName="ScaleImage" Storyboard.TargetProperty="ScaleY"/>
</Storyboard>
</Window.Resources>
<Grid>
<Image Name="Image" Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
Stretch="Fill" Width="300" Height="300"
RenderTransformOrigin="0.5, 0.5">
<Image.RenderTransform>
<ScaleTransform x:Name="ScaleImage"/>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard Storyboard="{StaticResource ScaleImageStoryboard}"/>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
Note that a single Image declaration in XAML is more than 6 lines! :D Is there a way for me to create much much cleaner XAML without breaking this functionality?
I think the easiest solution here is to create a style for the image, where you define the triggers and storyboard
<Window.Resources>
<Style x:Key="imageStyle" TargetType="{x:Type Image}">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform />
</Setter.Value>
</Setter>
<Setter Property="RenderTransformOrigin" Value="0.5, 0.5" />
<Style.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" From="1" To="1.2" AutoReverse="True"
Storyboard.TargetProperty="RenderTransform.ScaleX"/>
<DoubleAnimation Duration="0:0:0.2" From="1" To="1.2" AutoReverse="True"
Storyboard.TargetProperty="RenderTransform.ScaleY"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
You can then use this style for all your images :
<Image Name="Image"
Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
Stretch="Fill" Width="300" Height="300"
Style="{StaticResource imageStyle}" />
Note : I didn't test it, it might require a few modifications...
I believe that Thomas' answer is quite good. If that's still to much code for you, you can make some collection of strings (or more sophisticated objects representing your 60 images), make it available for your Window through some property and display it using ItemsControl and appropriate data template (and panel [ItemsControl.ItemsPanel property] if you want to do some fancy positioning). There's really no need for 'old shool way' in WPF ;).
<Window>
<ItemsControl ItemsSource={Binding ListOfPaths}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Name="Image"
Source="{Binding}"
Stretch="Fill" Width="300" Height="300"
Style="{StaticResource imageStyle}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
For situations like this is probably better to creating objects in source code ("old school way"), but if You prefer XML you can try use XSLT to generate it (but I don't recommend it).
I'm pretty new to WPF and even newer to animations in WPF. I know there are storyboards, etc. But I'm looking for a specific effect so I can work from there and tinker with it.
Can anyone just give me a simple example about on Image control MouseDown (because there is no Click event in this control in WPF) makes the image bigger through a nifty looking animation?
Thanks bros.
The following will scale the image relative to it's current size, rather than changing the absolute values. This might be more flexible.
<Page xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Image x:Name="MyImage" Source="c:\myImage.jpg" Width="250" Height="250">
<Image.RenderTransform>
<ScaleTransform x:Name="ImageScale" ScaleX="1" ScaleY="1" RenderTransformOrigin="0.5, 0.5"/>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ImageScale" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
<DoubleAnimation Storyboard.TargetName="ImageScale" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</Page>
Here is an example that does what I think you want:
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="600">
<Window.Resources>
<Storyboard x:Key="ScaleImageStoryboard">
<DoubleAnimation Duration="0:0:0.5" From="300" To="400" Storyboard.TargetName="Image" Storyboard.TargetProperty="Height"/>
<DoubleAnimation Duration="0:0:0.5" From="300" To="400" Storyboard.TargetName="Image" Storyboard.TargetProperty="Width"/>
</Storyboard>
</Window.Resources>
<Grid>
<Image Name="Image" Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" Stretch="Fill" Width="300" Height="300">
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard Storyboard="{StaticResource ScaleImageStoryboard}"/>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</Window>
Here, the image starts off at 300x300 px. When the Image.MouseDown event is fired the Trigger begins the storyboard which changes the image size to 400x400 over a half second period.
However, if you wanted an effect that just affected the size of the image temporarily and didn't influence layout, you would use:
<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="600">
<Window.Resources>
<Storyboard x:Key="ScaleImageStoryboard">
<DoubleAnimation Duration="0:0:0.2" From="1" To="1.2" AutoReverse="True"
Storyboard.TargetName="ScaleImage" Storyboard.TargetProperty="ScaleX"/>
<DoubleAnimation Duration="0:0:0.2" From="1" To="1.2" AutoReverse="True"
Storyboard.TargetName="ScaleImage" Storyboard.TargetProperty="ScaleY"/>
</Storyboard>
</Window.Resources>
<Grid>
<Image Name="Image" Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
Stretch="Fill" Width="300" Height="300"
RenderTransformOrigin="0.5, 0.5">
<Image.RenderTransform>
<ScaleTransform x:Name="ScaleImage"/>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard Storyboard="{StaticResource ScaleImageStoryboard}"/>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</Window>