I have a Style code define in ResourceDirectory to animate my popup. this is WPF code:
<Style x:Key="Hardwarepopups" TargetType="Popup">
<Style.Triggers>
<Trigger Property="IsOpen" Value="True">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation Duration="0:0:.3" Storyboard.TargetProperty="Width" From="0" To="100" AccelerationRatio=".1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
This is Popup:
<Popup Height="Auto" Width="Auto" Name="HardwareToolTip" StaysOpen="True" AllowsTransparency="True" Style="{StaticResource Hardwarepopups}">
It works well by handle all in XAML. I have decided to convert it to C# code like this:
void SetHarwareStyle(Popup B) {
var RightToLeft = new DoubleAnimation()
{
From = 0,
To = 100,
Duration = TimeSpan.FromMilliseconds(300),
AccelerationRatio = 0.1
};
Storyboard.SetTargetProperty(RightToLeft, new PropertyPath(WidthProperty));
Storyboard C = new Storyboard();
C.Children.Add(RightToLeft);
var action = new BeginStoryboard();
action.Storyboard = C;
Trigger A = new Trigger { Property = Popup.IsOpenProperty, Value = true };
A.EnterActions.Add(action);
B.Triggers.Add(A);
}
But this line B.Triggers.Add(A); gives the error System.InvalidOperationException: 'Triggers collection members must be of type EventTrigger.'
How can I solve this problem?
The propose of this conversion is to change To property of DoubleAnimation in runtime.
The code in the question does not reflect the XAML completely: the style is missing.
I renamed some of the variables to make it easier to read (and prevent mistakes like these)
BTW: the rightToLeftAnimation should be named leftToRightAnimation.
void SetHarwareStyle(Popup popup)
{
var rightToLeftAnimation = new DoubleAnimation()
{
From = 0,
To = 100,
Duration = TimeSpan.FromMilliseconds(300),
AccelerationRatio = 0.1
};
Storyboard.SetTargetProperty(rightToLeftAnimation, new PropertyPath(WidthProperty));
var storyboard = new Storyboard();
storyboard.Children.Add(rightToLeftAnimation);
var beginStoryboard = new BeginStoryboard();
beginStoryboard.Storyboard = storyboard;
var trigger = new Trigger { Property = Popup.IsOpenProperty, Value = true };
trigger.EnterActions.Add(beginStoryboard);
var style= new Style();
style.TargetType = typeof(Popup);
style.Triggers.Add(trigger);
popup.Style = style;
}
Related
Initially I did it directly on nInput and everything worked.
Then I tried to move it to a cloned object (cloneInputForAnimation) but I get this error:
System.InvalidOperationException: The name 'TextBoxAnim' could not be
found in the namespace of 'System.Windows.Controls.TextBox'
XAML:
<TextBox x:Name="nInput" MaxLength="17" PreviewTextInput="numberValidationTextBox" Grid.Column="0"
Height="80" Width="240"
Foreground="White" Background="#202020"
HorizontalAlignment="Left" BorderThickness="0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="25">
<TextBox.RenderTransform>
<TranslateTransform x:Name="TextBoxAnim" />
</TextBox.RenderTransform>
<TextBox.Resources>
<Storyboard x:Key="myStoryboardY" x:Name="myStoryboardY">
<DoubleAnimation
Storyboard.TargetName="TextBoxAnim"
x:Name="myDoubleAnimationY"
Storyboard.TargetProperty="Y"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardX" x:Name="myStoryboardX">
<DoubleAnimation
Storyboard.TargetName="TextBoxAnim"
x:Name="myDoubleAnimationX"
Storyboard.TargetProperty="X"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardWidth" x:Name="myStoryboardWidth">
<DoubleAnimation
Storyboard.TargetName="nInput"
x:Name="myDoubleAnimationWidth"
Storyboard.TargetProperty="(TextBox.Width)"
Duration="0:0:0.8"
/>
</Storyboard>
<Storyboard x:Key="myStoryboardHeight" x:Name="myStoryboardHeight">
<DoubleAnimation
Storyboard.TargetName="nInput"
x:Name="myDoubleAnimationHeight"
Storyboard.TargetProperty="(TextBox.Height)"
Duration="0:0:0.8"
/>
</Storyboard>
</TextBox.Resources>
</TextBox>
C#:
//I clone the input box to perform the animation
TextBox cloneInputForAnimation = CloneXaml(nInput);
UserInteraction.Children.Add(cloneInputForAnimation);
//Removing text from the realInput
nInput.Text = "";
//nInput.IsEnabled = false;
//Creating a new object which is the one that will remain after the animation
TextBox targetInput = CloneXaml(cloneInputForAnimation);
targetInput.Visibility = Visibility.Hidden;
targetInput.Width = Double.NaN;
targetInput.Height = 50;
nList.Children.Add(targetInput);
//Obtaining the destination point
Point targetPosition = targetInput.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Obtaining the current point
Point currentPos = cloneInputForAnimation.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Calculating the translation to do to reach targetPosition
Vector translateToDo = targetPosition - currentPos;
//Obtaining storyboard and anim for x, y, width, height of cloneInputForAnimation (I can't use x:Name because is an element created programmatically)
Storyboard myStoryY = cloneInputForAnimation.Resources["myStoryboardY"] as Storyboard;
Storyboard myStoryX = cloneInputForAnimation.Resources["myStoryboardX"] as Storyboard;
Storyboard myStoryHeight = cloneInputForAnimation.Resources["myStoryboardHeight"] as Storyboard;
Storyboard myStoryWidth = cloneInputForAnimation.Resources["myStoryboardWidth"] as Storyboard;
DoubleAnimation myAnimY = myStoryY.Children[0] as DoubleAnimation;
DoubleAnimation myAnimX = myStoryX.Children[0] as DoubleAnimation;
DoubleAnimation myAnimHeight = myStoryHeight.Children[0] as DoubleAnimation;
DoubleAnimation myAnimWidth = myStoryWidth.Children[0] as DoubleAnimation;
myAnimY.To = translateToDo.Y;
myAnimX.To = translateToDo.X;
myAnimHeight.To = targetInput.ActualHeight;
myAnimWidth.To = targetInput.ActualWidth;
cloneInputForAnimation.BeginStoryboard(myStoryY);
cloneInputForAnimation.BeginStoryboard(myStoryX);
cloneInputForAnimation.BeginStoryboard(myStoryHeight);
cloneInputForAnimation.BeginStoryboard(myStoryWidth);
C# CloneXaml:
public static T CloneXaml<T>(T source)
{
string xaml = XamlWriter.Save(source);
StringReader sr = new StringReader(xaml);
XmlReader xr = XmlReader.Create(sr);
return (T)XamlReader.Load(xr);
}
Sorry but these are my first steps with WPF so the code will probably have a lot of problems.
Okay, as I imagined I was using a completely wrong approach.
This is the working version I have arrived at.
XAML:
<TextBox x:Name="nInput" MaxLength="17" PreviewTextInput="numberValidationTextBox" Grid.Column="0"
Height="80" Width="240"
Foreground="White" Background="#202020"
HorizontalAlignment="Left" BorderThickness="0"
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
FontSize="25">
<TextBox.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="CornerRadius" Value="12" />
</Style>
</TextBox.Resources>
</TextBox>
C#:
Duration animDuration = new Duration(new TimeSpan(0, 0 ,0, 0,800));
//I clone the input box to perform the animation
TextBox cloneInputForAnimation = CloneXaml(nInput);
UserInteraction.Children.Add(cloneInputForAnimation);
//Removing text from the realInput
nInput.Text = "";
//nInput.IsEnabled = false;
//Creating a new object wich is the one that will remain after the animation
TextBox targetInput = CloneXaml(cloneInputForAnimation);
targetInput.Visibility = Visibility.Hidden;
targetInput.Width = double.NaN;
targetInput.Height = 50;
nList.Children.Add(targetInput);
//Obtaining the destination point
Point targetPosition = targetInput.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Obtaining the current point
Point currentPos = cloneInputForAnimation.TransformToAncestor(rootView).Transform(new Point(0, 0));
//Calculating the translation to do to reach targetPosition
Vector translateToDo = targetPosition - currentPos;
TranslateTransform myTranslateTransform = new TranslateTransform();
cloneInputForAnimation.RenderTransform = myTranslateTransform;
DoubleAnimation myAnimX = new DoubleAnimation {
Duration = animDuration,
To = translateToDo.X
};
DoubleAnimation myAnimY = new DoubleAnimation {
Duration = animDuration,
To = translateToDo.Y
};
DoubleAnimation myAnimHeight = new DoubleAnimation {
Duration = animDuration,
To = 50,
};
DoubleAnimation myAnimWidth = new DoubleAnimation {
Duration = animDuration,
To = 50,
};
myTranslateTransform.BeginAnimation(TranslateTransform.YProperty, myAnimY);
myTranslateTransform.BeginAnimation(TranslateTransform.XProperty, myAnimX);
cloneInputForAnimation.BeginAnimation(TextBox.WidthProperty, myAnimWidth);
cloneInputForAnimation.BeginAnimation(TextBox.HeightProperty, myAnimHeight);
C# CloneXaml has not been modified
i try to do this xaml code programmatically
<Grid.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="tranny" Storyboard.TargetProperty="ScaleX" To="1.2" Duration="0:0:1">
<DoubleAnimation.EasingFunction>
<ElasticEase Oscillations="1" Springiness="8"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="tranny" Storyboard.TargetProperty="ScaleY" To="1.2" Duration="0:0:1">
<DoubleAnimation.EasingFunction>
<ElasticEase Oscillations="1" Springiness="8" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
it do it but it didn't work with i don't know why but there is no errors if there is any onwe can write this xaml in C# programmatically answer me
please if you have answer can help me add it if no please don't give -1 that is programmatically code that i wrote
var secondryGrid = new Grid();
var elasticEase = new ElasticEase();
elasticEase.Oscillations = 1;
elasticEase.Springiness = 8;
var timeSpan = new TimeSpan(0, 0, 0, 100);
var duration = new Duration(timeSpan);
var doubleAnimation = new DoubleAnimation();
doubleAnimation.To = 1.2;
doubleAnimation.Duration = duration;
doubleAnimation.EasingFunction = elasticEase;
var path = new PropertyPath("ScaleX");
var storyBoard = new Storyboard();
Storyboard.SetTargetProperty(doubleAnimation, path);
storyBoard.Children.Add(doubleAnimation);
var beginStoryBoard = new BeginStoryboard();
beginStoryBoard.Storyboard = storyBoard;
elasticEase = new ElasticEase();
elasticEase.Oscillations = 1;
elasticEase.Springiness = 8;
timeSpan = new TimeSpan(0, 0, 0, 100);
duration = new Duration(timeSpan);
doubleAnimation = new DoubleAnimation();
doubleAnimation.To = 1.2;
doubleAnimation.Duration = duration;
doubleAnimation.EasingFunction = elasticEase;
path = new PropertyPath("ScaleY");
Storyboard.SetTargetProperty(doubleAnimation, path);
storyBoard.Children.Add(doubleAnimation);
var gridEventTrigger = new EventTrigger();
gridEventTrigger.RoutedEvent = MouseEnterEvent;
gridEventTrigger.Actions.Add(beginStoryBoard);
secondryGrid.Triggers.Add(gridEventTrigger);
sorry for my bad language
In code, this is done somewhat easier.
You don't need to instantiate BeginStoryboard and Storyboard; these classes are designed to make it easier to use animations in XAML.
In code, you can set the animation directly to the desired property.
This requires significantly less code.
Example:
{
Grid grid = new Grid();
grid.MouseEnter += OnGridMouseEnter;
}
// An animation instance is created once and can then be reused.
private static readonly DoubleAnimation xyAnimation = new DoubleAnimation(1.2, TimeSpan.FromSeconds(1))
{
EasingFunction = new ElasticEase()
{
Oscillations = 1,
Springiness = 8
}
};
private void OnGridMouseEnter(object sender, MouseEventArgs e)
{
tranny.BeginAnimation(ScaleTransform.ScaleXProperty, xyAnimation);
tranny.BeginAnimation(ScaleTransform.ScaleYProperty, xyAnimation);
}
P.S. It is not clear from your code how you create the tranny transformation.
My example is created on the assumption that there is a tranny field that contains the transformation that needs to be animated.
In order to change a color of a rectangle in code behind I can use:
InitializeComponent();
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(20);
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "MyRectangle";
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
myRectangle.Fill = mySolidColorBrush;
SolidColorBrush blackBrush = new SolidColorBrush();
blackBrush.Color = Colors.Black;
myRectangle.StrokeThickness = 4;
myRectangle.Stroke = blackBrush;
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.Red;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myColorAnimation);
myRectangle.MouseEnter += delegate(object sender, MouseEventArgs e)
{
myStoryboard.Begin(this);
};
myStackPanel.Children.Add(myRectangle);
this.Content = myStackPanel;
How can I do the same for the border of the rectangle (actually I'm looking more for a blinking-border effect than the fading one, maybe by changing Stroke property)?
Modify your Stroke:
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
myRectangle.Fill = mySolidColorBrush;
SolidColorBrush blackBrush = new SolidColorBrush(Colors.Black);
this.RegisterName("MySolidColorBorderBrush", blackBrush);
myRectangle.StrokeThickness = 4;
myRectangle.Stroke = blackBrush;
And storyboard setup
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Black;
myColorAnimation.To = Colors.Blue;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBorderBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myColorAnimation);
Just for the archive (xaml)
<StackPanel Margin="20">
<Rectangle x:Name="MyRectangle" Width="100" Height="100" StrokeThickness="4">
<Rectangle.Fill>
<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
</Rectangle.Fill>
<Rectangle.Stroke>
<SolidColorBrush x:Name="MySolidColorBorderBrush" Color="Black" />
</Rectangle.Stroke>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard Duration="0:0:1">
<ColorAnimation Storyboard.TargetName="MySolidColorBrush" Storyboard.TargetProperty="Color" From="Blue" To="Red" />
<ColorAnimation Storyboard.TargetName="MySolidColorBorderBrush" Storyboard.TargetProperty="Color" From="Black" To="Blue" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
I found a great WIPE animation here : http://www.wearerighteous.com/programming/slidewipe-transition-for-your-windows-in-wpf/
EDIT: the link above is dead so you have to see this one
http://learnwpf.com/post/2006/10/03/How-can-I-create-a-e2809cwipee2809d-effect-to-transition-between-two-images-in-WPF.aspx
It has the same source code.
Basically, the code there is like this:
<Window.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="Black" x:Name="BlackStop"/>
<GradientStop Offset="0" Color="Transparent" x:Name="TransparentStop"/>
</LinearGradientBrush>
<Window.OpacityMask>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TransparentStop"
Storyboard.TargetProperty="Offset" By="1" Duration="0:0:1"/>
<DoubleAnimation Storyboard.TargetName="BlackStop"
Storyboard.TargetProperty="Offset" By="1" Duration="0:0:1"
BeginTime="0:0:0.05" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
I tried to "translate" the animation in c# code and I can't seem to do it. I tried several versions, like :
public void WipeAnimation(FrameworkElement ObjectToAnimate)
{
LinearGradientBrush OpacityBrush = new LinearGradientBrush();
OpacityBrush.StartPoint = new Point(1,0);
OpacityBrush.EndPoint = new Point(0,0);
GradientStop BlackStop = new GradientStop(Colors.Black, 0);
GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
OpacityBrush.GradientStops.Add(t);
OpacityBrush.GradientStops.Add(t2);
ObjectToAnimate.OpacityMask = OpacityBrush;
Duration d = TimeSpan.FromSeconds(4);
Storyboard sb = new Storyboard() { Duration = d };
DoubleAnimation DA = new DoubleAnimation() { By=1 , Duration = d };
DoubleAnimation DA2 = new DoubleAnimation() { By=1 , Duration = d };
sb.Children.Add(DA); sb.Children.Add(DA2);
Storyboard.SetTarget(DA,TransparentStop);
Storyboard.SetTarget(DA2,BlackStop);
Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
sb.Begin();
}
Or replacing in the SetTarget Rows like :
Storyboard.SetTarget(DA, (ObjectToAnimate.OpacityMask as LinearGradientBrush).GradientStops[1]);
But nothing happens to my FrameworkElement. I called it for a Window (just like in the example from the site), and the only think that happens is that it sets the OpacityMask. The animation starts and ends (I added a Completed Event to the Storyboard with a MessageBox just to see if it works). I don't know what other things to do.
Please help! :(
Any ideas?
EDIT:
Maybe I explained the question bad. I'm trying to create the animation that I have in XAML, in C# code.... I've been trying for two days now, searching for a solution. I don't know why the C# version doesn't work ...
I'm not sure why the above is not working, but here's something that does work - instead of creating a Storyboard, simply use the BeginAnimation() method for each GradientStop:
BlackStop.BeginAnimation(GradientStop.OffsetProperty, DA2);
TransparentStop.BeginAnimation(GradientStop.OffsetProperty, DA);
public void WipeAnimation(FrameworkElement ObjectToAnimate)
{
LinearGradientBrush OpacityBrush = new LinearGradientBrush();
OpacityBrush.StartPoint = new Point(1,0);
OpacityBrush.EndPoint = new Point(0,0);
GradientStop BlackStop = new GradientStop(Colors.Black, 0);
GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
OpacityBrush.GradientStops.Add(t);
OpacityBrush.GradientStops.Add(t2);
ObjectToAnimate.OpacityMask = OpacityBrush;
this.RegisterName("TransparentStop", TransparentStop);
this.RegisterName("BlackStop", BlackStop);
Duration d = TimeSpan.FromSeconds(4);
Storyboard sb = new Storyboard() { Duration = d };
DoubleAnimation DA = new DoubleAnimation() { By=1 , Duration = d };
DoubleAnimation DA2 = new DoubleAnimation() { By=1 , Duration = d };
sb.Children.Add(DA); sb.Children.Add(DA2);
Storyboard.SetTargetName(DA,"TransparentStop");
Storyboard.SetTargetName(DA2,"BlackStop");
Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
sb.Begin();
}
EDIT:
This code is great! But it has 3 errors so i found it. The correct version is here:
public void WipeAnimation(FrameworkElement ObjectToAnimate)
{
LinearGradientBrush OpacityBrush = new LinearGradientBrush();
OpacityBrush.StartPoint = new Point(1, 0);
OpacityBrush.EndPoint = new Point(0, 0);
GradientStop BlackStop = new GradientStop(Colors.Black, 0);
GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
OpacityBrush.GradientStops.Add(BlackStop);
OpacityBrush.GradientStops.Add(TransparentStop);
ObjectToAnimate.OpacityMask = OpacityBrush;
this.RegisterName("TransparentStop", TransparentStop);
this.RegisterName("BlackStop", BlackStop);
Duration d = TimeSpan.FromSeconds(4);
Storyboard sb = new Storyboard() { Duration = d };
DoubleAnimation DA = new DoubleAnimation() { By = 1, Duration = d };
DoubleAnimation DA2 = new DoubleAnimation() { By = 1, Duration = d };
sb.Children.Add(DA); sb.Children.Add(DA2);
Storyboard.SetTargetName(DA, "TransparentStop");
Storyboard.SetTargetName(DA2, "BlackStop");
Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
sb.Begin(this);
}
Errors line are:
OpacityBrush.GradientStops.Add(t); -> OpacityBrush.GradientStops.Add(BlackStop);
OpacityBrush.GradientStops.Add(t2); -> OpacityBrush.GradientStops.Add(TransparentStop);
sb.Begin(); -> sb.Begin(this);
Seems to work great in my case.....
<Window x:Class="WpfHierarchicalDataGrid.Window4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window4"
MinHeight="100"
MinWidth="100"
AllowsTransparency="True"
Opacity="0.7"
WindowState="Normal"
WindowStyle="None">
<Window.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="Black"
x:Name="BlackStop"/>
<GradientStop Offset="0" Color="Transparent"
x:Name="TransparentStop"/>
</LinearGradientBrush>
</Window.OpacityMask>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="TransparentStop"
Storyboard.TargetProperty="Offset"
By="1" Duration="0:0:1"/>
<DoubleAnimation
Storyboard.TargetName="BlackStop"
Storyboard.TargetProperty="Offset" By="1"
Duration="0:0:1"
BeginTime="0:0:0.05" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Grid>
<Image Source="Water_lilies.jpg" Stretch="UniformToFill" />
</Grid>
</Window>
I have some xaml like this:
<UserControl.Resources>
<Storyboard x:Name="sbLogo" x:Key="onLoadeducLogo" Completed="sbLogo_Completed">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="image">
<LinearDoubleKeyFrame x:Name="pauseKeyFrame" KeyTime="0:0:2" Value="0"/>
<LinearDoubleKeyFrame x:Name="fadeInKeyFram" KeyTime="0:0:6" Value="1"/>
<LinearDoubleKeyFrame x:Name="fadeOutKeyFrame" KeyTime="0:0:12" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
What I'd like to do is update the KeyTime values of the LinearDoubleKeyFrame elements from the UserControl code behind in C#.
I thought maybe I could do this by referencing those elements by their x:Name but I'm not having much success. I also thought maybe I could bind the values to a field in the code behind, but no success there either.
Has anyone got any clues to push me in the right direction.
Thanks
Phil
How have you tried to reference the LinearDoubleKeyFrame objects in code?
I think you need to do something like:
var storyboard = (Storyboard)FindResource("onLoadeducLogo");
var animation = (DoubleAnimationUsingKeyFrames)storyboard.Children[0];
var keyframe1 = animation.KeyFrames[0];
keyframe1.KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0,0,0,1)); // 1 second
Image creatureImage = new Image();
Storyboard fadeInFadeOut = new Storyboard();
DoubleAnimationUsingKeyFrames dbAnimation = new DoubleAnimationUsingKeyFrames();
dbAnimation.Duration = TimeSpan.FromSeconds(2);
LinearDoubleKeyFrame lDKF1 = new LinearDoubleKeyFrame();
lDKF1.Value = 1;
lDKF1.KeyTime = TimeSpan.FromSeconds(0);
dbAnimation.KeyFrames.Add(lDKF1);
//
LinearDoubleKeyFrame lDKF2 = new LinearDoubleKeyFrame();
lDKF2.Value = 0.6;
lDKF2.KeyTime = TimeSpan.FromSeconds(0.5);
dbAnimation.KeyFrames.Add(lDKF2);
//
LinearDoubleKeyFrame lDKF3 = new LinearDoubleKeyFrame();
lDKF3.Value = 1;
lDKF3.KeyTime = TimeSpan.FromSeconds(0.5);
dbAnimation.KeyFrames.Add(lDKF3);
//
LinearDoubleKeyFrame lDKF4 = new LinearDoubleKeyFrame();
lDKF4.Value = 0;
lDKF4.KeyTime = TimeSpan.FromSeconds(1);
dbAnimation.KeyFrames.Add(lDKF4);
Storyboard.SetTarget(dbAnimation, creatureImage);
Storyboard.SetTargetProperty(dbAnimation, new PropertyPath(Image.OpacityProperty));
fadeInFadeOut.Children.Add(dbAnimation);