How to set TargetProperty of Storyboard in c#? - c#

I have this xaml code and I want to convert it in c#:
<Storyboard>
<DoubleAnimationUsingKeyFrames EnableDependentAnimation="True" Storyboard.TargetProperty="(Shape.Stroke).(GradientBrush.GradientStops)[0].(GradientStop.Offset)" Storyboard.TargetName="ellipse">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="1"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
I have made different tries :
Duration duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard sb = new Storyboard();
sb.Duration = duration;
var da = new DoubleAnimationUsingKeyFrames();
da.EnableDependentAnimation = true;
da.Duration = duration;
var ed1 = new EasingDoubleKeyFrame();
ed1.KeyTime = TimeSpan.Parse("0");
ed1.Value = 1;
var ed2 = new EasingDoubleKeyFrame();
ed2.KeyTime = TimeSpan.Parse("0:0:0.7");
ed2.Value = 1;
var ed3 = new EasingDoubleKeyFrame();
ed3.KeyTime = TimeSpan.Parse("0:0:1");
ed3.Value = 0;
da.KeyFrames.Add(ed1);
da.KeyFrames.Add(ed2);
da.KeyFrames.Add(ed3);
Storyboard.SetTarget(da, lgbStroke);
Storyboard.SetTargetProperty(da, "(Shape.Stroke).(GradientBrush.GradientStops)[0].(GradientStop.Offset)");
sb.Children.Add(da);
sb.Begin();
but I get this exception :
WinRT information: Cannot resolve TargetProperty (Shape.Stroke).(GradientBrush.GradientStops)[0].(GradientStop.Offset) on specified object.
Does anybody have any idea how to resolve this?
Thanks in advance

Related

Storyboard DoubleAnimation programmatically

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.

C# WPF How to keep Application responsive while adding many UI Elements to Stackpanel

I made an Application where I add many Grids to some Stackpanels in a for loop. My problem is that, while the for loop is loading my Application doesn´t respond and my Loadinganimation is freezed. How can I add the Grids to the Stackpanel without affecting the UI Thread, so my Loading Animation won´t freeze.
Thanks in Advance
Edit:
Grid creation Method:
public void GridExample()
{
for(int i = 0; i < 120; i++)
{
Grid Grid1 = new Grid();
Grid1.FlowDirection = FlowDirection.LeftToRight;
Grid1.Width = 200;
Grid1.Background = new SolidColorBrush(Color.FromArgb(255, (byte)33, (byte)33, (byte)33));
Grid1.Margin = new Thickness(5, 20, 5, 20);
ColumnDefinition Grid1_col1 = new ColumnDefinition();
Grid1.ColumnDefinitions.Add(Grid1_col1);
RowDefinition Grid1_row1 = new RowDefinition();
RowDefinition Grid1_row2 = new RowDefinition();
RowDefinition Grid1_row3 = new RowDefinition();
RowDefinition Grid1_row4 = new RowDefinition();
Grid1.RowDefinitions.Add(Grid1_row1);
Grid1.RowDefinitions.Add(Grid1_row2);
Grid1.RowDefinitions.Add(Grid1_row3);
Grid1.RowDefinitions.Add(Grid1_row4);
Grid1_row1.Height = new GridLength(255);
Grid1_row2.Height = new GridLength(60);
Grid1_row3.Height = new GridLength(5);
Grid1_row4.Height = new GridLength(55);
//Adds Grid to HomePage
homepage1_mainstackpanel1.Children.Add(Grid1);
Image Image1 = new Image();
Image1.Stretch = Stretch.Fill;
Image1.Source = new BitmapImage(new Uri("Image.png"));
Grid.SetRow(Image1, 0);
Grid1.Children.Add(Image1);
Label Label1 = new Label();
Label1.Content = "Example Text";
Label1.FontSize = 15;
Label1.Foreground = new SolidColorBrush(Colors.White);
Label1.VerticalAlignment = VerticalAlignment.Center;
Label1.HorizontalAlignment = HorizontalAlignment.Center;
Grid.SetRow(Label1, 1);
Grid1.Children.Add(Label1);
Line Line1 = new Line();
Line1.X1 = 1;
Line1.StrokeThickness = 2;
Line1.Stroke = new SolidColorBrush(Color.FromArgb(255, (byte)51, (byte)51, (byte)51));
Line1.Stretch = Stretch.Fill;
Grid.SetRow(Line1, 2);
Grid1.Children.Add(Line1);
Button Button1 = new Button();
Button1.Content = "Play";
Button1.FontSize = 15;
Button1.Foreground = new SolidColorBrush(Colors.White);
Button1.Background = new SolidColorBrush(Color.FromArgb(255, (byte)33, (byte)33, (byte)33));
Button1.BorderThickness = new Thickness(0);
Button1.VerticalAlignment = VerticalAlignment.Center;
Button1.HorizontalAlignment = HorizontalAlignment.Center;
Button1.Click += new RoutedEventHandler((sender, e) =>
{
this.NavigationService.Navigate(new WatchPage1());
});
Grid1.Children.Add(Button1);
}
}
Loading Animation in HomePage:
public static Dispatcher mainthread_dispatcher = Dispatcher.CurrentDispatcher;
public HomePage1()
{
Loaded += Page_loaded;
InitializeComponent();
}
private void Page_loaded(object sender, RoutedEventArgs e)
{
using (LoadingAnimation loadanimation = new LoadingAnimation(GridExample))
{
loadanimation.ShowDialog();
}
}
LoadingAnimation.xaml:
<Window x:Class="Spaceflix_Desktop.LoadingAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Spaceflix_Desktop"
mc:Ignorable="d"
Height="110" Width="90" Loaded="Animation_Loaded">
<Window.Resources>
<Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse1">
<EasingColorKeyFrame KeyTime="0" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#B25B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse2">
<EasingColorKeyFrame KeyTime="0" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#FF5B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse3">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse4">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse5">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse6">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse7">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse8">
<EasingColorKeyFrame KeyTime="0" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#7F5B5B5B"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Border x:Name="Border" BorderBrush="#c62828" BorderThickness="2" Background="Black" Height="80" Width="80">
<Grid x:Name="maingrid" Background="Transparent">
<Ellipse x:Name="ellipse1" Fill="#FF5B5B5B" HorizontalAlignment="Center" Margin="0, 5, 0, 0" Height="15" VerticalAlignment="Top" Width="15"/>
<Ellipse x:Name="ellipse2" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 15, 15, 0" Height="15" VerticalAlignment="Top" Width="15"/>
<Ellipse x:Name="ellipse3" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 0, 5, 0" Height="15" VerticalAlignment="Center" Width="15"/>
<Ellipse x:Name="ellipse4" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 0, 15, 15" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse5" Fill="#FF5B5B5B" HorizontalAlignment="Center" Margin="0, 0, 0, 5" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse6" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="15, 0, 0, 15" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse7" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="5, 0, 0, 0" Height="15" VerticalAlignment="Center" Width="15"/>
<Ellipse x:Name="ellipse8" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="15, 15, 0, 0" Height="15" VerticalAlignment="Top" Width="15"/>
</Grid>
</Border>
</Window>
LoadingAnimation.cs:
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using System.Runtime.Remoting.Channels;
using System.Windows.Media.Media3D;
using System.Windows.Interop;
namespace Test_Application
{
/// <summary>
/// Interaktionslogik für LoadingAnimation.xaml
/// </summary>
public partial class LoadingAnimation : Window, IDisposable
{
public Action Worker { get; set; }
public LoadingAnimation (Action worker)
{
InitializeComponent();
Worker = worker ?? throw new ArgumentNullException();
}
public void Animation_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() => { }).ContinueWith(t => HomePage1.mainthread_dispatcher.Invoke(() => Worker()), TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith(t => Dispatcher.Invoke(() => Close()));
}
public void Dispose()
{
}
}
}
I hope this Information are enough
after I didn't have time for this project for a long time, I've now dealt with it again and found a solution. I can't add the grids to the stack panels in a new task or thread but at least I can display the loading animation smoothly. Because the grids have to be added to the main thread, I ran the loading animation in a new thread. So I had to display it as a popup. This is the best solution I found.
Here is the Code from the HomePage:
var PositionWindow = (Window)Parent;
int CenterX = 8;
int CenterY = 1;
Point CenterPoints = new Point(PositionWindow.Left + CenterX + (PositionWindow.Width / 2), PositionWindow.Top + CenterY + (PositionWindow.Height / 2));
Thread LoadThread = new Thread(new ThreadStart(() => {
using (PopUpLoadingAnimation loadanimation = new PopUpLoadingAnimation(GridExample, CenterPoints, PositionWindow))
{
loadanimation.StartTask();
Dispatcher.Run();
}
}));
LoadThread.SetApartmentState(ApartmentState.STA);
LoadThread.Start();
I had to calculate the middle of the Window by myself to make the PopUp centered.
And here is the Code of the PopUpLoadingAnimation.cs:
public partial class PopUpLoadingAnimation : Popup
{
public Action Worker { get; set; }
private Point _PlacementPoints { get; set; }
private Window MainWindow { get; set; }
public PopUpLoadingAnimation (Action worker, Point PlacementPoints, Window mainthreadwindow)
{
InitializeComponent();
Worker = worker ?? throw new ArgumentNullException();
MainWindow = mainthreadwindow;
_PlacementPoints = PlacementPoints;
}
public void StartTask()
{
Task.Factory.StartNew(() => Dispatcher.Invoke(() =>
{
Storyboard animationboard = Resources["Storyboard1"] as Storyboard;
animationboard.Begin(maingrid);
LoadingPopup.Placement = PlacementMode.Center;
LoadingPopup.HorizontalOffset = _PlacementPoints.X;
LoadingPopup.VerticalOffset = _PlacementPoints.Y;
LoadingPopup.IsOpen = true;
HomePage1.mainthread_dispatcher.Invoke(() => MainWindow.IsEnabled = false);
})).ContinueWith(t => HomePage1.mainthread_dispatcher.Invoke(() => Worker()), HomePage1.mainthread_scheduler).ContinueWith(t => Dispatcher.Invoke(async () =>
{
LoadingPopup.IsOpen = false;
HomePage1.mainthread_dispatcher.Invoke(() => MainWindow.IsEnabled = true);
Dispatcher.InvokeShutdown();
}));
}
by the way thanks for the answers, unfortunately they did not help

C#.net - Convert animation style to code behind

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;
}

WPF Translating an XAML Animation to C# Code

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>

Update a LinearDoubleKeyFrame KeyTime value from code

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);

Categories

Resources