Animation target not specified issue - Silverlight storyboards - silverlight

Having some real head scratching going on here as I can't seem to think why I am getting the Animation target not specified error. I create a static class for dishing out storyboards of lots of little fires "burning". I then create as many of those fires as the user wants and assign a new storyboard to it, all in Csharp. I then begin then storyboard, but as I say, I keep getting this error and I can't seem why. Here is the storyboard creating class, and when I try to call it.
public static class FireStoryboard
{
public static Storyboard fireStoryboard(UIElement target)
{
Storyboard s = new Storyboard();
s.RepeatBehavior = RepeatBehavior.Forever;
DoubleAnimationUsingKeyFrames scaleY = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(scaleY, target);
scaleY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.ScaleY)"));
EasingDoubleKeyFrame e1 = new EasingDoubleKeyFrame();
e1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
e1.Value = 1.8;
e1.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
EasingDoubleKeyFrame e2 = new EasingDoubleKeyFrame();
e2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
e1.Value = 1;
e2.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
scaleY.KeyFrames.Add(e1);
scaleY.KeyFrames.Add(e2);
DoubleAnimationUsingKeyFrames translateY = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(translateY, target);
translateY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateY)"));
EasingDoubleKeyFrame e3 = new EasingDoubleKeyFrame();
e3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
e3.Value = -4;
e3.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
EasingDoubleKeyFrame e4 = new EasingDoubleKeyFrame();
e4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
e4.Value = 0;
e4.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
translateY.KeyFrames.Add(e3);
translateY.KeyFrames.Add(e4);
DoubleAnimationUsingKeyFrames opacity = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(opacity, target);
opacity.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("UIElement.Opacity"));
EasingDoubleKeyFrame e5 = new EasingDoubleKeyFrame();
e5.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
e5.Value = 0.7;
EasingDoubleKeyFrame e6 = new EasingDoubleKeyFrame();
e6.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
e6.Value = 1;
EasingDoubleKeyFrame e7 = new EasingDoubleKeyFrame();
e7.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
e7.Value = 0.7;
opacity.KeyFrames.Add(e5);
opacity.KeyFrames.Add(e6);
opacity.KeyFrames.Add(e7);
DoubleAnimationUsingKeyFrames shadowDirection = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(shadowDirection, target);
shadowDirection.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.Direction)"));
EasingDoubleKeyFrame eShad1 = new EasingDoubleKeyFrame();
eShad1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
eShad1.Value = 449;
EasingDoubleKeyFrame eShad2 = new EasingDoubleKeyFrame();
eShad2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
eShad2.Value = 449;
shadowDirection.KeyFrames.Add(eShad1);
shadowDirection.KeyFrames.Add(eShad2);
DoubleAnimationUsingKeyFrames shadowDepth = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(shadowDepth, target);
shadowDirection.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.ShadowDepth)"));
EasingDoubleKeyFrame eShad3 = new EasingDoubleKeyFrame();
eShad3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
eShad3.Value = 0;
EasingDoubleKeyFrame eShad4 = new EasingDoubleKeyFrame();
eShad4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
eShad4.Value = 5;
EasingDoubleKeyFrame eShad5 = new EasingDoubleKeyFrame();
eShad5.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
eShad5.Value = 20;
shadowDirection.KeyFrames.Add(eShad3);
shadowDirection.KeyFrames.Add(eShad4);
shadowDirection.KeyFrames.Add(eShad5);
DoubleAnimationUsingKeyFrames shadowOpacity = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(shadowOpacity, target);
shadowDirection.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.Opacity)"));
EasingDoubleKeyFrame eShad6 = new EasingDoubleKeyFrame();
eShad6.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
eShad6.Value = 1;
EasingDoubleKeyFrame eShad7 = new EasingDoubleKeyFrame();
eShad7.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
eShad7.Value = 0;
shadowDirection.KeyFrames.Add(eShad6);
shadowDirection.KeyFrames.Add(eShad7);
DoubleAnimationUsingKeyFrames skewX = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(skewX, target);
skewX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.SkewX)"));
EasingDoubleKeyFrame eSkew1 = new EasingDoubleKeyFrame();
eSkew1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
eSkew1.Value = 0;
eSkew1.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
EasingDoubleKeyFrame eSkew2 = new EasingDoubleKeyFrame();
eSkew2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
eSkew2.Value = -5;
eSkew2.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
EasingDoubleKeyFrame eSkew3 = new EasingDoubleKeyFrame();
eSkew3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
eSkew3.Value = 5;
eSkew3.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
EasingDoubleKeyFrame eSkew4 = new EasingDoubleKeyFrame();
eSkew4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1.5));
eSkew4.Value = -5;
eSkew4.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
EasingDoubleKeyFrame eSkew5 = new EasingDoubleKeyFrame();
eSkew5.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
eSkew5.Value = 0;
eSkew5.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
skewX.KeyFrames.Add(eSkew1);
skewX.KeyFrames.Add(eSkew2);
skewX.KeyFrames.Add(eSkew3);
skewX.KeyFrames.Add(eSkew4);
skewX.KeyFrames.Add(eSkew5);
ColorAnimationUsingKeyFrames shadowColor = new ColorAnimationUsingKeyFrames();
Storyboard.SetTarget(shadowColor, target);
shadowColor.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.Color)"));
EasingColorKeyFrame eColor1 = new EasingColorKeyFrame();
eColor1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
eColor1.Value = Colors.Red;
EasingColorKeyFrame eColor2 = new EasingColorKeyFrame();
eColor2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
eColor2.Value = Color.FromArgb(255, 254, 31, 0);
EasingColorKeyFrame eColor3 = new EasingColorKeyFrame();
eColor3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.7));
eColor3.Value = Color.FromArgb(255, 254, 255, 0);
EasingColorKeyFrame eColor4 = new EasingColorKeyFrame();
eColor4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.8));
eColor4.Value = Colors.Black;
shadowColor.KeyFrames.Add(eColor1);
shadowColor.KeyFrames.Add(eColor2);
shadowColor.KeyFrames.Add(eColor3);
shadowColor.KeyFrames.Add(eColor4);
s.Children.Add(scaleY);
s.Children.Add(translateY);
s.Children.Add(opacity);
s.Children.Add(shadowDirection);
s.Children.Add(shadowDepth);
s.Children.Add(shadowOpacity);
s.Children.Add(skewX);
s.Children.Add(shadowColor);
Storyboard.SetTarget(s, target);
return s;
}
}
And here is where I assign it to each fire image:
Storyboard fireStoryboard = FireStoryboard.fireStoryboard(fire);
fireStoryboard.Begin();
Any help would be greatly appreciated. Am I missing setting a target somewhere? I really cannot see where :(.

The following works fine for me when the elementName x:Name can be found in the element which has the Storyboard in it's resources. When implementing MVVM you can also set the name on the fly because then you don't need the x:Name most of the time any way. See the following;
private void GoShowUpElement(FrameworkElement element, double opacity)
{
if (element != null)
{
string guidString = Guid.NewGuid().ToString();
element.SetValue(NameProperty, guidString);// When you don't use x:Name in Xaml (with MVVM normally not nessasary)
if (!this.LayoutRoot.Resources.Contains(guidString))
{
this.LayoutRoot.Resources.Add(guidString, ShowUpElement(opacity, 1000, guidString)); // when you do use x:Name replace guidString with the x:Name you used.
Storyboard simultaniousStoryboard = this.LayoutRoot.Resources[guidString] as Storyboard;
simultaniousStoryboard.Completed += new EventHandler(simultaniousStoryboard_Completed);
simultaniousStoryboard.Begin();
}
}
}
When the storyboard completes, I clean up the resources, which significantly increases performance when using more and more storyboards ;)
private void simultaniousStoryboard_Completed(object sender, EventArgs e)
{
Storyboard storyboard = sender as Storyboard;
foreach (DictionaryEntry dictionaryEntry in this.LayoutRoot.Resources)
{
Storyboard resourceStoryboard = dictionaryEntry.Value as Storyboard;
if (resourceStoryboard != null)
{
if (resourceStoryboard.GetValue(NameProperty) == storyboard.GetValue(NameProperty))
this.LayoutRoot.Resources.Remove(dictionaryEntry.Key);
}
}
}
Here is the static Method that creates a reusable storyboard for me.
public static Storyboard ShowUpElement(double opacity, int milliseconds, string elementName)
{
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(StoryboardBasic.KeyFramedAnimation(opacity, 0.9, 0, milliseconds, elementName, "Opacity"));
//storyboard.Children.Add(StoryboardBasic.KeyFramedAnimation.... Add more if you want
return storyboard;
}
And the DoubleAnimationUsingKeyFrames which could also be other types of animations as you like.
public static DoubleAnimationUsingKeyFrames KeyFramedAnimation(double fromValue, double toValue, int startMilliSeconds, int endMilliseconds, string targetElementName, PropertyPath propertyPath)
{
List<SplineDoubleKeyFrame> splineDoubleKeyFrames = new List<SplineDoubleKeyFrame>()
{
new SplineDoubleKeyFrame() { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(startMilliSeconds)), Value = fromValue, KeySpline = new KeySpline() { ControlPoint1 = new Point(0,0), ControlPoint2= new Point(1,0)} },
new SplineDoubleKeyFrame() { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(endMilliseconds)), Value = toValue, KeySpline = new KeySpline() { ControlPoint1 = new Point(0,0), ControlPoint2= new Point(0,1)} },
};
DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
foreach (SplineDoubleKeyFrame linearDoubleKeyFrame in splineDoubleKeyFrames)
animation.KeyFrames.Add(linearDoubleKeyFrame);
Storyboard.SetTargetName(animation, targetElementName);
Storyboard.SetTargetProperty(animation, propertyPath);
return animation;
}
Let me know if this was helpfull, Thanks in advance.

Related

How to setup and connect to database in .net 6 winform project?

I'm new to Winform (.net 6), can anyone please show me a sample code on how to set up and connect to a database (SqlServer or MySQL) in Winform? Thanks!
Here is the link to a begginers guide to accessing SQL Server through C#.
The example usage to
set up and connect to a database (SqlServer or MySQL) in Winform
I give you here:
Form1.Designer
public partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.textBox_dbAddress = new System.Windows.Forms.TextBox();
this.textBox_dbName = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.textBox_login = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.textBox_password = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(180, 88);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(132, 15);
this.label1.TabIndex = 0;
this.label1.Text = "Database server address";
this.textBox_dbAddress.Location = new System.Drawing.Point(180, 106);
this.textBox_dbAddress.Name = "textBox_dbAddress";
this.textBox_dbAddress.Size = new System.Drawing.Size(188, 23);
this.textBox_dbAddress.TabIndex = 1;
this.textBox_dbName.Location = new System.Drawing.Point(180, 153);
this.textBox_dbName.Name = "textBox_dbName";
this.textBox_dbName.Size = new System.Drawing.Size(188, 23);
this.textBox_dbName.TabIndex = 3;
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(180, 135);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(88, 15);
this.label2.TabIndex = 2;
this.label2.Text = "Database name";
this.textBox_login.Location = new System.Drawing.Point(180, 198);
this.textBox_login.Name = "textBox_login";
this.textBox_login.Size = new System.Drawing.Size(188, 23);
this.textBox_login.TabIndex = 5;
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(180, 180);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(37, 15);
this.label3.TabIndex = 4;
this.label3.Text = "Login";
this.textBox_password.Location = new System.Drawing.Point(180, 245);
this.textBox_password.Name = "textBox_password";
this.textBox_password.PasswordChar = '*';
this.textBox_password.Size = new System.Drawing.Size(188, 23);
this.textBox_password.TabIndex = 7;
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(180, 227);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(57, 15);
this.label4.TabIndex = 6;
this.label4.Text = "Password";
this.button1.Location = new System.Drawing.Point(180, 286);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 8;
this.button1.Text = "Connect";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox_password);
this.Controls.Add(this.label4);
this.Controls.Add(this.textBox_login);
this.Controls.Add(this.label3);
this.Controls.Add(this.textBox_dbName);
this.Controls.Add(this.label2);
this.Controls.Add(this.textBox_dbAddress);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label label1;
private TextBox textBox_dbAddress;
private TextBox textBox_dbName;
private Label label2;
private TextBox textBox_login;
private Label label3;
private TextBox textBox_password;
private Label label4;
private Button button1;
}
Form1
public partial class Form1 : Form
{
public Form1()
{
this.InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SqlConnection myConnection = new SqlConnection(
$"server={this.textBox_dbAddress.Text};" +
$"database={this.textBox_dbName.Text}; " +
$"user id={this.textBox_login.Text};" +
$"password={this.textBox_password.Text};" +
$"Trusted_Connection=yes;" +
$"connection timeout=30");
try
{
myConnection.Open();
MessageBox.Show("Connection oppened");
}
catch
{
MessageBox.Show("Connection failed");
}
finally
{
myConnection.Close();
}
}
}

Adding a dynamically created panel to a Flowlayoutpanel on a user control

I'm working on a todo list application and I'm dynamically building a panel from another form based on user input, this said panel is suppose to be added to the flowlayoutpanel on a user control, but nothing is showing up.
Any ideas what might cause the problem.
Update: my code does work if it is executed directly from the user control itself.
My Code
private void btnCreateTask_Click_1(object sender, EventArgs e)
{
Panel pnlParentTask = new Panel();
pnlParentTask.Size = new Size(234, 89);
pnlParentTask.BorderStyle = BorderStyle.FixedSingle;
pnlParentTask.Location = new Point(217, 186);
PictureBox pbFinish = new PictureBox();
pbFinish.Size = new Size(22, 21);
pbFinish.Location = new Point(13, 13);
pbFinish.BorderStyle = BorderStyle.FixedSingle;
Label lblTitle = new Label();
lblTitle.Text = txtTaskName.Text;
lblTitle.ForeColor = Color.Black;
lblTitle.AutoSize = true;
lblTitle.Location = new Point(41, 12);
lblTitle.Font = new Font("Arial", 12f);
lblTitle.BackColor = Color.Transparent;
lblTitle.Tag = lblTitle.Text;
enc.setpanelTag(lblTitle.Text);
pnlParentTask.Tag = lblTitle.Text;
Label lblDescription = new Label();
lblDescription.Text = txtDescription.Text;
lblDescription.AutoSize = true;
lblDescription.Location = new Point(4, 38);
lblDescription.BackColor = Color.Transparent;
lblDescription.Font = new Font("Microsoft Yahei", 8.25f);
lblDescription.Tag = lblTitle.Text;
PictureBox pbPriority = new PictureBox();
pbPriority.Location = new Point(207, 3);
pbPriority.Tag = lblTitle.Text;
pbPriority.Size = new Size(22, 21);
pbPriority.BorderStyle = BorderStyle.FixedSingle;
Label lblDateCreated = new Label();
lblDateCreated.Location = new Point(3, 69);
lblDateCreated.Text = txtStartDate.Text;
lblDateCreated.BackColor = Color.Transparent;
lblDateCreated.Font = new Font("Microsoft Yahei", 8.25f);
lblDateCreated.Tag = lblTitle.Text;
Label lblDeleteTask = new Label();
lblDeleteTask.Text = "-";
lblDeleteTask.Font = new Font("Microsoft Yahei", 24f);
lblDeleteTask.Location = new Point(206, 53);
lblDeleteTask.Click += new EventHandler(lblRemoveTask_click);
pnlParentTask.Controls.Add(pbFinish);
pnlParentTask.Controls.Add(lblTitle);
pnlParentTask.Controls.Add(lblDescription);
pnlParentTask.Controls.Add(pbPriority);
pnlParentTask.Controls.Add(lblDateCreated);
pnlParentTask.Controls.Add(lblDeleteTask);
priority.flpParent.Controls.Add(pnlParentTask);
this.Close();
}

How to create multiple parallel animations to the same element?

I'm trying to set multiple parallel animations for the same element in code-behind. Well, when im trying to pull "Moving" (RenderTransorm.X + Y) and Opacity together, it runs perfect. But when im trying to add scale animation or Width-Height animation, only the latest animation is running.
What im i doing wrong? - or, is there any elegant way to do this programmatically?
private void StartAnimation(TimeSpan startOffsetTime, TimeSpan duration)
{
if (TweetIsAnimated)
{
Globals.IsAnimating = true;
}
if (_hasAnimated)
{
return;
}
_hasAnimated = true;
StopAnimation();
EnsureTransform();
var storyboard = new Storyboard();
//--------------------------HORIZONTAL ANIMATION-------------------------
if (MoveStory)
{
var horizontalAnimation = new DoubleAnimation(FromHorizontalOffset, 0, duration)
{
EasingFunction = GetFuncByName(EasingFuncType)
//new CubicEase { EasingMode = EasingMode.EaseOut }
};
storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
storyboard.Children.Add(horizontalAnimation);
Storyboard.SetTarget(horizontalAnimation, AssociatedObject);
Storyboard.SetTargetProperty(horizontalAnimation, new PropertyPath("RenderTransform.X"));
storyboard.BeginTime = startOffsetTime;
storyboard.Begin();
}
//------------------------------------------------------------------------
//--------------------------VERTICAL ANIMATION----------------------------
if (MoveStory)
{
var veritcalAnimation = new DoubleAnimation(FromVerticalOffset, 0, duration)
{
EasingFunction = GetFuncByName(EasingFuncType)
};
storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
storyboard.Children.Add(veritcalAnimation);
Storyboard.SetTarget(veritcalAnimation, AssociatedObject);
Storyboard.SetTargetProperty(veritcalAnimation, new PropertyPath("RenderTransform.Y"));
storyboard.BeginTime = startOffsetTime;
storyboard.Begin();
}
//------------------------------------------------------------------------
//--------------------------OPACITY ANIMATION-----------------------------
if (OpacityStory)
{
var opacityAnimation = new DoubleAnimationUsingKeyFrames();
opacityAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(OpacityStart, TimeSpan.Zero));
opacityAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(OpacityStart, startOffsetTime,
GetFuncByName(EasingFuncType)));
opacityAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(1,
duration + startOffsetTime +
TimeSpan.FromMilliseconds(
Duration.TotalMilliseconds/2),
GetFuncByName(EasingFuncType)));
storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
storyboard.Children.Add(opacityAnimation);
Storyboard.SetTarget(opacityAnimation, AssociatedObject);
Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(UIElement.OpacityProperty));
storyboard.Begin();
}
//------------------------------------------------------------------------
//--------------------------SCALE ANIMATION------------------------------
if (ScaleStory)
{
ScaleTransform scaleTransform1 = new ScaleTransform(1, 1, AssociatedObject.ActualWidth, AssociatedObject.ActualHeight);
AssociatedObject.RenderTransformOrigin = new Point(1, ScaleStart);
AssociatedObject.RenderTransform = scaleTransform1;
var EasingFunction1 = new BackEase() { EasingMode = EasingMode.EaseOut, Amplitude = AmplitudeNow };
var scaleAnimation = new DoubleAnimationUsingKeyFrames();
TimeSpan time = duration + startOffsetTime + TimeSpan.FromMilliseconds(Duration.TotalMilliseconds / 2);
scaleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(ScaleStart, TimeSpan.Zero));
scaleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(ScaleStart, startOffsetTime, EasingFunction1));
scaleAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(1, time, EasingFunction1));
storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
storyboard.Children.Add(scaleAnimation);
Storyboard.SetTarget(scaleAnimation, AssociatedObject);
Storyboard.SetTargetProperty(scaleAnimation, new PropertyPath("RenderTransform.ScaleY"));
storyboard.Begin();
}
//------------------------------------------------------------------------
//--------------------------RESIZE ANIMATION------------------------------
if (ResizeStory)
{
DoubleAnimation widthAnimation = new DoubleAnimation
{
From = WidthStart,
To = AssociatedObject.ActualWidth,
Duration = Duration
};
DoubleAnimation heightAnimation = new DoubleAnimation
{
From = HeightStart,
To = AssociatedObject.ActualHeight,
Duration = Duration
};
storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
storyboard.Children.Add(widthAnimation);
Storyboard.SetTarget(widthAnimation, AssociatedObject);
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(FrameworkElement.WidthProperty));
storyboard.BeginTime = startOffsetTime;
storyboard.Begin();
storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
storyboard.Children.Add(heightAnimation);
Storyboard.SetTarget(heightAnimation, AssociatedObject);
Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(FrameworkElement.HeightProperty));
storyboard.BeginTime = startOffsetTime;
storyboard.Begin();
}
//------------------------------------------------------------------------
}
Do not create new storyboard!
Refactor your code like this:
var storyboard = new Storyboard();
storyboard.Completed += AnimationOnCompleted;
_storyboards.Add(storyboard, true);
if (MoveStory)
{
var horizontalAnimation = new DoubleAnimation(FromHorizontalOffset, 0, duration)
{
EasingFunction = GetFuncByName(EasingFuncType)
//new CubicEase { EasingMode = EasingMode.EaseOut }
};
storyboard.Children.Add(horizontalAnimation);
Storyboard.SetTarget(horizontalAnimation, AssociatedObject);
Storyboard.SetTargetProperty(horizontalAnimation, new PropertyPath("RenderTransform.X"));
}
// ... if else etc...
if (ResizeStory)
{
DoubleAnimation widthAnimation = new DoubleAnimation
{
From = WidthStart,
To = AssociatedObject.ActualWidth,
Duration = Duration
};
DoubleAnimation heightAnimation = new DoubleAnimation
{
From = HeightStart,
To = AssociatedObject.ActualHeight,
Duration = Duration
};
storyboard.Children.Add(widthAnimation);
Storyboard.SetTarget(widthAnimation, AssociatedObject);
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(FrameworkElement.WidthProperty));
storyboard.Children.Add(heightAnimation);
Storyboard.SetTarget(heightAnimation, AssociatedObject);
Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(FrameworkElement.HeightProperty));
}
storyboard.BeginTime = startOffsetTime;
storyboard.Begin();

Animation in codebehind for loop, using RenderTransform

Is it possible to animate the "old school" way, in codebehind, instead of xaml?
I just want an arrow that points to something with a 'bounce effect' which I could easily do in my own for loop. But I do not know how to refresh or do a timer delay, inside the loop. I already placed the image into position in codebehind. All I want to do is this simple animation...
public void validationArrow()
{
var validationArrow = new Image();
validationArrow.Source = new BitmapImage(new Uri("/SlProject;component/arrow.png", UriKind.RelativeOrAbsolute));
LayoutRoot.Children.Add(validationArrow);
validationArrow.Stretch = Stretch.None;
validationArrow.VerticalAlignment = System.Windows.VerticalAlignment.Top;
validationArrow.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
var arrowPosition = new TranslateTransform { X = 0, Y = 0 };
validationArrow.RenderTransform = arrowPosition;
validationArrow.Name = "validationArrow";
for (int i = 150; i >= 0; i--)
{
arrowPosition.X = i;
validationArrow.RenderTransform = arrowPosition;
// how can I refresh screen and do some timing here?
}
}
There's no school like the old school ;)
Here, this should help you on your way. You can play with the millisecond and Y translation values being passed to the BuildEasing method to change the 'bounce' effect's speed and distance.
private void RunStoryboard()
{
var arrowImage = new Image();
arrowImage.RenderTransform = new CompositeTransform();
arrowImage.Source = new BitmapImage(new Uri("/SlProject;component/arrow.png", UriKind.RelativeOrAbsolute));
LayoutRoot.Children.Add(arrowImage);
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(BuildKeyFrame(arrowImage));
storyboard.Begin();
}
private DoubleAnimationUsingKeyFrames BuildKeyFrame(Image target)
{
DoubleAnimationUsingKeyFrames kf = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(kf, target);
Storyboard.SetTargetProperty(kf, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateY)"));
kf.KeyFrames.Add(BuildEasing(100, 10));
kf.KeyFrames.Add(BuildEasing(200, 0));
kf.KeyFrames.Add(BuildEasing(300, 10));
kf.KeyFrames.Add(BuildEasing(400, 0));
kf.KeyFrames.Add(BuildEasing(500, 10));
kf.KeyFrames.Add(BuildEasing(600, 0));
return kf;
}
private EasingDoubleKeyFrame BuildEasing(int ms, int value)
{
return new EasingDoubleKeyFrame()
{
KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, ms)),
Value = value
};
}

Using a Storyboard animation on a programmatically-added control

I'm trying to fade in a new control to my application's "app" area which is programmatically added after the existing controls are removed. My code looks like this:
void settingsButton_Clicked(object sender, EventArgs e)
{
ContentCanvas.Children.Clear();
// Fade in settings panel
NameScope.SetNameScope(this, new NameScope());
SettingsPane s = new SettingsPane();
s.Name = "settingsPane";
this.RegisterName(s.Name, s);
this.Resources.Add(s.Name, s);
Storyboard sb = new Storyboard();
DoubleAnimation settingsFade = new DoubleAnimation();
settingsFade.From = 0;
settingsFade.To = 1;
settingsFade.Duration = new Duration(TimeSpan.FromSeconds(0.33));
settingsFade.RepeatBehavior = new RepeatBehavior(1);
Storyboard.SetTargetName(settingsFade, s.Name);
Storyboard.SetTargetProperty(settingsFade, new PropertyPath(UserControl.OpacityProperty));
ContentCanvas.Children.Add(s);
sb.Children.Add(settingsFade);
sb.Begin();
}
However, when I run this code, I get the error "No applicable name scope exists to resolve the name 'settingsPane'."
What am I possibly doing wrong? I'm pretty sure I've registered everything properly :(
I wouldn't hassle with the NameScopes etc. and would rather use Storyboard.SetTarget instead.
var b = new Button() { Content = "abcd" };
stack.Children.Add(b);
var fade = new DoubleAnimation()
{
From = 0,
To = 1,
Duration = TimeSpan.FromSeconds(5),
};
Storyboard.SetTarget(fade, b);
Storyboard.SetTargetProperty(fade, new PropertyPath(Button.OpacityProperty));
var sb = new Storyboard();
sb.Children.Add(fade);
sb.Begin();
I solved the problem using this as parameter in the begin method, try:
sb.Begin(this);
Because the name is registered in the window.
I agree, the namescopes are probably the wrong thing to use for this scenario. Much simpler and easier to use SetTarget rather than SetTargetName.
In case it helps anyone else, here's what I used to highlight a particular cell in a table with a highlight that decays to nothing. It's a little like the StackOverflow highlight when you add a new answer.
TableCell cell = table.RowGroups[0].Rows[row].Cells[col];
// The cell contains just one paragraph; it is the first block
Paragraph p = (Paragraph)cell.Blocks.FirstBlock;
// Animate the paragraph: fade the background from Yellow to White,
// once, through a span of 6 seconds.
SolidColorBrush brush = new SolidColorBrush(Colors.Yellow);
p.Background = brush;
ColorAnimation ca1 = new ColorAnimation()
{
From = Colors.Yellow,
To = Colors.White,
Duration = new Duration(TimeSpan.FromSeconds(6.0)),
RepeatBehavior = new RepeatBehavior(1),
AutoReverse = false,
};
brush.BeginAnimation(SolidColorBrush.ColorProperty, ca1);
It is possible odd thing but my solution is to use both methods:
Storyboard.SetTargetName(DA, myObjectName);
Storyboard.SetTarget(DA, myRect);
sb.Begin(this);
In this case there is no error.
Have a look at the code where I have used it.
int n = 0;
bool isWorking;
Storyboard sb;
string myObjectName;
UIElement myElement;
int idx = 0;
void timer_Tick(object sender, EventArgs e)
{
if (isWorking == false)
{
isWorking = true;
try
{
myElement = stackObj.Children[idx];
var possibleIDX = idx + 1;
if (possibleIDX == stackObj.Children.Count)
idx = 0;
else
idx++;
var myRect = (Rectangle)myElement;
// Debug.WriteLine("TICK: " + myRect.Name);
var dur = TimeSpan.FromMilliseconds(2000);
var f = CreateVisibility(dur, myElement, false);
sb.Children.Add(f);
Duration d = TimeSpan.FromSeconds(2);
DoubleAnimation DA = new DoubleAnimation() { From = 1, To = 0, Duration = d };
sb.Children.Add(DA);
myObjectName = myRect.Name;
Storyboard.SetTargetName(DA, myObjectName);
Storyboard.SetTarget(DA, myRect);
Storyboard.SetTargetProperty(DA, new PropertyPath("Opacity"));
sb.Begin(this);
n++;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + " " + DateTime.Now.TimeOfDay);
}
isWorking = false;
}
}

Resources