Just a doubt.I have three images in my WPF application.Im going to give blink effect for that three images.So i gave this code.
<Storyboard x:Key ="AlarmBlink">
<DoubleAnimation
Storyboard.TargetName="Img1"
Storyboard.TargetProperty="Opacity"
From="1" To="0" Duration="0:0:0.1"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
This one is for FirstImage(Img1).So i have to give for other two images.Can i give multiple taget name in previus coding.
Otherwise i have to copy and paste the samecoding and changing targetname.
Is there any way to give in single coding?
You cannot put multiple Storyboard.TargetNames in a DoubleAnimation, but there is a better way: Use data binding to bind the three Opacity values together, then animate just one of them and the others will change as well.
Note: To avoid asymmetry in creating your bindings you may want to use this additional tecnhique:
- Create a fourth control with Visibility="Collapsed" so you never see it
- Animate this control's opacity
- Bind the Opacity of all three visible controls to the opacity of the invisible one.
Another option is to use a single DoubleAnimation and use code behind to apply it to all three images instead of using WPF's StoryBoard mechanism. This gives you much more control but requires you to write the code-behind.
Generally I stick with the binding solution because it is simplest. In any case the cut-and-paste solution is usually the worst of all.
1.Define a StaticResource
for your DoubleAnimation
. (because you cant use a storyboard for multiple element):
<Window.Resources>
<DoubleAnimation x:Key="DA"
Storyboard.TargetName="Img1"
Storyboard.TargetProperty="Opacity"
From="1" To="0" Duration="0:0:0.1"
AutoReverse="True" RepeatBehavior="Forever" />
</Window.Resources>
2.Use this resource for your elements and define Storyboard.TargetName
using RelativeSource Binding
. for example:
<Image Name="img1">
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard >
<Storyboard Storyboard.TargetName="{Binding Name,RelativeSource={RelativeSource AncestorType=Image,Mode=FindAncestor}}">
<StaticResourceExtension ResourceKey="DA" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
You can create a reusable attached property that can be attached to any control that derives from UIElement
(Since that's where the property Opacity
is defined at the lowest level) like so:
public class OpacityAnimation
{
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached(
"IsEnabled", typeof(bool), typeof(OpacityAnimation), new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.AffectsRender, IsEnabledChanged));
public static void SetIsEnabled(DependencyObject element, bool value)
{
element.SetValue(IsEnabledProperty, value);
}
public static bool GetIsEnabled(DependencyObject element)
{
return (bool)element.GetValue(IsEnabledProperty);
}
private static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is UIElement uiElement))
throw new Exception("DependencyObject has to be of type UIElement");
if (e.NewValue is bool isEnabled && isEnabled)
{
var doubleAnimation = CreateAnimation(500);
uiElement.BeginAnimation(UIElement.OpacityProperty, doubleAnimation);
}
else
{
uiElement.BeginAnimation(UIElement.OpacityProperty, null);
}
}
private static AnimationTimeline CreateAnimation(int durationMs)
{
return new DoubleAnimation
{
FillBehavior = FillBehavior.Stop,
RepeatBehavior = RepeatBehavior.Forever,
AutoReverse = true,
Duration = new Duration(TimeSpan.FromMilliseconds(durationMs)),
From = 0,
To = 1
};
}
}
Create this class anywhere in your project.
Then to use it: (Remember to reference your namespace in the XAML)
<Path attachedProperties:OpacityAnimation.IsEnabled="{Binding IsBlinking}"
Data="M 0,0 L 0,50 L 50,50 L 50,0" Fill="Red"/>
This way you can attach this to any property you like, and bind IsEnabled
to your ViewModel property to control the animation. You don't even need a Storyboard for simple animations like this.
Attached properties are a fantastic feature of WPF!