I have a grid of images and buttons, and I want to animate motion from one position to another (actually a few spaces to the left) automatically, but it hasn't worked. I've tried using a storyboard in xaml and programatically as in the code below, but its now working. Please help!!!
public static void MoveTo(Grid target)
{
Canvas.SetLeft(target, 0);
var top = Canvas.GetTop(target);
var left = Canvas.GetLeft(target);
TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;
double newX = (double)(left - 300);
double newY = (double)top;
DoubleAnimation anim1 = new DoubleAnimation(top, -15, TimeSpan.FromSeconds(10));
//DoubleAnimation anim1 = new DoubleAnimation(top, newY - top, TimeSpan.FromSeconds(10));
DoubleAnimation anim2 = new DoubleAnimation(left, newX - left, TimeSpan.FromSeconds(10));
anim1.AutoReverse = true;
anim1.RepeatBehavior = RepeatBehavior.Forever;
trans.BeginAnimation(TranslateTransform.XProperty, anim1);
trans.BeginAnimation(TranslateTransform.YProperty, anim2);
}
totally TranslateTransform isnt good for that you want .better to use thinkness animation
i advise you dont use canavas and change it to grid but if you use canavas use this code
private void Animationsss(Grid grd)
{
//create an animation
DoubleAnimation da = new DoubleAnimation();
//set from animation to start position
//dont forget set canvas.left for grid if u dont u will get error
da.From = Canvas.GetLeft(grd);
//set second position of grid
da.To = -100;
//set duration
da.Duration = new Duration(TimeSpan.FromSeconds(2));
//run animation if u want stop ,start etc use story board
grd.BeginAnimation(Canvas.LeftProperty, da);
}
if you use grid code is this :
private void Animation(Grid grd)
{
ThicknessAnimation ta = new ThicknessAnimation();
//your first place
ta.From = grd.Margin;
//this move your grid 1000 over from left side
//you can use -1000 to move to left side
ta.To = new Thickness(1000, 0, 0, 0);
//time the animation playes
ta.Duration = new Duration(TimeSpan.FromSeconds(10));
//dont need to use story board but if you want pause,stop etc use story board
grd.BeginAnimation(Grid.MarginProperty, ta);
}
you can use opacity animation for fade your grid ... it show good if move and fade !
private void Animationsss(Grid grd)
{
DoubleAnimation da = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(2)));
grd.BeginAnimation(Grid.OpacityProperty, da);
}
if there isnt any reason u can change canavas to grid and also better use TranslateTransform for resize controls like code below this code resize control if mouse enter in it :
private void grid1_MouseEnter(object sender, MouseEventArgs e)
{
//at first its normal size
ScaleTransform st = new ScaleTransform(1, 1);
//animation size to 1.25 persent of real size
DoubleAnimation da = new DoubleAnimation(1,1.25, new Duration(TimeSpan.FromSeconds(2)));
//set transform to control
grid1.RenderTransform = st;
//animation transform now From Y And X
st.BeginAnimation(ScaleTransform.ScaleXProperty, da);
st.BeginAnimation(ScaleTransform.ScaleYProperty, da);
}
if you animation for width or height do same work like scale transform :)
hope i can help you ...:))
leave comment for me please
You can also use xaml for this:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestBed.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Storyboard x:Key="MoveGrid">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="grid">
<EasingThicknessKeyFrame KeyTime="0:0:1" Value="-300,0,0,0"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
<BeginStoryboard x:Name="MoveGrid_BeginStoryboard" Storyboard="{StaticResource MoveGrid}"/>
</EventTrigger>
</Window.Triggers>
<Canvas>
<Grid x:Name="grid" Height="300" Width="300" Background="Black">
<Button x:Name="button" Content="Move the gird!" Height="30" Margin="10,0" />
</Grid>
</Canvas>
</Window>
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
HubPage is my landing page. On Hubpage.xaml, I have a grid of 3x3, containing a Rectangle, what I'm calling a "cell". In HubPage.xaml.cs, particularly in the HubPage() constructor, I create a storyboard for each cell:
CreateStoryboardForCell("Column0Row0");
CreateStoryboardForCell("Column0Row1");
...
CreateStoryboardForCell("Column2Row2");
I want to add a storyboard to the Page.Resources, normally I would do it in XAML, but I am attempting it from C#. Now, here is the CreateStoryboardForCell implementation:
private void CreateStoryboardForCell(string cellName)
{
// Create two DoubleAnimations, one for scaleX and one for scaleY, and set their properties.
Duration duration = new Duration(TimeSpan.FromSeconds(0.2));
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);
// Set the targets of the animations
Storyboard.SetTarget(myDoubleAnimation1, Column0Row0);
Storyboard.SetTarget(myDoubleAnimation2, Column0Row0);
// Set the attached properties of ScaleX and ScaleY
// to be the target properties of the two respective DoubleAnimations
Storyboard.SetTargetProperty(myDoubleAnimation1, "(UIElement.RenderTransform).(CompositeTransform.ScaleX)");
Storyboard.SetTargetProperty(myDoubleAnimation2, "(UIElement.RenderTransform).(CompositeTransform.ScaleY)");
myDoubleAnimation1.To = 15;
myDoubleAnimation2.To = 22;
// Make the Storyboard a resource.
try
{
pageRoot.Resources.Add("story" + cellName, sb);
}
catch (Exception e)
{
Status.Text = "Error adding storyboard resource for cell" + cellName + ": " + e.Message;
}
}
pageRoot is from Hubpage.xaml: Page x:Name="pageRoot", etc. I do not get an exception when adding the resource, but I cannot see the resource when I set the breakpoint, so I assume it was added successfully, as I can see the count increasing, and no exception was thrown.
Moving on, I have a click handler for each column cell, where I infer the row and column number and try to start up the corresponding storyboard added to the page resource earlier. Here is the code:
private void Column1_Cell_Click(object sender, RoutedEventArgs e)
{
Rectangle rect = sender as Rectangle;
int x = (int)rect.GetValue(Grid.RowProperty);
int y = (int)rect.GetValue(Grid.ColumnProperty);
string storyboardName = "storyColumn" + y + "Row" + x;
Storyboard storyboard = (Storyboard)FindName(storyboardName);
storyboard.Begin();
}
but the FindName call always returns a null storyboard. What am I missing here?
I've written this code for you.I hope benefits to business
Here is code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column0Row0"/>
<ColumnDefinition x:Name="Column0Row1"/>
<ColumnDefinition x:Name="Column0Row2"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle Fill="Pink" x:Name="rectangle" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"/>
<Rectangle Grid.Column="1" Grid.Row="1" Fill="Coral" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"/>
<Rectangle Grid.Column="2" Grid.Row="2" Fill="Orange" MouseLeftButtonDown="Rectangle_MouseLeftButtonDown"/>
</Grid>
Code Behind :
private void CreateStoryboardForCell(Rectangle target)
{
ScaleTransform trans = new ScaleTransform();
target.RenderTransform = trans;
DoubleAnimation anim = new DoubleAnimation(1, 2, TimeSpan.FromMilliseconds(1000));
trans.BeginAnimation(ScaleTransform.ScaleXProperty, anim);
trans.BeginAnimation(ScaleTransform.ScaleYProperty, anim);
}
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
CreateStoryboardForCell((Rectangle)sender);
}
Please try this code.I always use this code for finding a storyboard.It works.
Here is code:
FrameworkElement element = new FrameworkElement();
Storyboard sb=new Storyboard ();
sb = element.FindResource("Please write here Storyboard Key") as Storyboard;
sb.Begin(target element name , true);
If BeginStoryboard doesn't support in WinRT.You can use the following code.I created the animation in codedehind.Maybe you can solve the problem like this;I did some research on this problem.
I tried this code.It works
Here is code:
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Storyboard storyboard = new Storyboard();
ScaleTransform scale = new ScaleTransform(1.0, 1.0);
animatedRectangle.RenderTransformOrigin = new Point(0.5, 0.5);
animatedRectangle.RenderTransform = scale;
DoubleAnimation scaleAnimation1 = new DoubleAnimation(1, 2, TimeSpan.FromMilliseconds(1000));
DoubleAnimation scaleAnimation2 = new DoubleAnimation(1, 2, TimeSpan.FromMilliseconds(1000));
storyboard.Children.Add(scaleAnimation1);
storyboard.Children.Add(scaleAnimation2);
Storyboard.SetTargetProperty(scaleAnimation1, new PropertyPath("RenderTransform.ScaleX"));
Storyboard.SetTargetProperty(scaleAnimation2, new PropertyPath("RenderTransform.ScaleY"));
Storyboard.SetTarget(scaleAnimation1, animatedRectangle);
Storyboard.SetTarget(scaleAnimation2, animatedRectangle);
storyboard.Begin();
}
I m using MouseDragElementBehavior in my WP7 application to drag an image down the canvas. I m able to get the coordinates (X,Y positions) after the image dragging. But I want to retain the same image position after tombstoning also.
private void MouseDragElementBehavior_Dragging(object sender, MouseEventArgs e)
{
Point currentPos = e.GetPosition(image1);
if (currentPos.X < 190)
{
double targetOffset = 700;
DoubleAnimation animation = new DoubleAnimation();
animation.EasingFunction = new CircleEase();
animation.Duration = new Duration(new TimeSpan(0, 0, 10));
animation.From = TextScroll.AnimatableOffset;
animation.To = targetOffset;
Storyboard.SetTarget(animation, TextScroll);
Storyboard.SetTargetProperty(animation, new PropertyPath("(AnimatableScrollViewer.AnimatableOffset)"));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(animation);
storyboard.Begin();
}
App app = (App)Application.Current;
app.current_X = currentPos.X.ToString();
app.current_Y = currentPos.Y.ToString();
TextScroll.AnimatableOffset = -700;
}
I have stored and retrived the values from isolated storage for tombstoning.
private void LoadSettings()
{
var settings = IsolatedStorageSettings.ApplicationSettings;
current_X = settings["Xpos"].ToString();
current_Y = settings["Ypos"].ToString();
}
private void SaveSettings()
{
var settings = IsolatedStorageSettings.ApplicationSettings;
settings.Add("Xpos", current_X);
settings.Add("Ypos",current_Y);
settings.Save();
}
Now I would like to use the values to position the image at the same coordinates as before tombstoning. I dont know how to position the image with the X and Y coordinates provided.
Here is the XAML code where I use the image.
<Canvas Margin="12,0,3,-834" Grid.Row="1">
<Image Height="800" Source="37.jpg" Stretch="Fill" Width="480" Canvas.Left="-11" x:Name="image1">
<i:Interaction.Behaviors>
<el:MouseDragElementBehavior ConstrainToParentBounds="True" Dragging="MouseDragElementBehavior_Dragging" />
</i:Interaction.Behaviors>
</Image>
</Canvas>
First, Point currentPos = e.GetPosition(image1); is getting the position of the mouse relative to the image. Maybe you want to get the position relative to the canvas instead?
Or, you can use this to get the position within the canvas:
canvas1.GetLeft(image1);
canvas1.GetTop(image1);
Then, you can set the position of something within a canvas like this:
canvas1.SetLeft(image1, x);
canvas1.SetTop(image1, y);
To do that, you would need to name your Canvas:
<Canvas x:Name="canvas1" Margin="12,0,3,-834" Grid.Row="1">
I'm wanting to make a component that inherits from rotate canvas using a storyboard. But when I try nothing happens.
Eventually I also want to dynamically change the speed of rotation to a stop. But first, i need rotate the componente.
This is the code for the component:
class MyToy : Canvas
{
public MyToy()
{
this.Background = System.Windows.Media.Brushes.Green;
this.Width = 300;
this.Height = 300;
Polyline poly = new Polyline();
poly.Points.Add(new Point(25, 25));
poly.Points.Add(new Point(0, 50));
poly.Points.Add(new Point(25, 75));
poly.Points.Add(new Point(50, 50));
poly.Points.Add(new Point(25, 25));
poly.Points.Add(new Point(25, 0));
poly.Stroke = System.Windows.Media.Brushes.Blue;
poly.StrokeThickness = 10;
this.Children.Add(poly);
Canvas.SetLeft(poly, 120);
Canvas.SetTop(poly, 120);
}
}
the window xaml code is:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="500" Width="500">
<Canvas x:Name="myCanvas">
<Button Canvas.Left="0" Canvas.Top="0" Content="Rotate" Height="23" Name="button1" Width="111" Click="button1_Click" />
</Canvas>
</Window>
And finaly, the code behind, where i create the storyboard is:
public partial class Window1 : Window
{
MyToy myToy;
RotateTransform transform;
public Window1()
{
InitializeComponent();
myToy = new MyToy();
transform = new RotateTransform();
// transform.Name = "MyToy1Transform";
myToy.RenderTransform = transform;
// this.RegisterName(transform.Name, transform);
myToy.Name = "MyToy1";
this.RegisterName("MyToy1", myToy);
myCanvas.Children.Add(myToy);
Canvas.SetTop(myToy, 50);
Canvas.SetLeft(myToy, 50);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation ani = new DoubleAnimation();
ani.From = 0;
ani.To = 359;
ani.AutoReverse = true;
ani.RepeatBehavior = RepeatBehavior.Forever;
ani.Duration = new Duration(TimeSpan.FromSeconds(2));
Storyboard story = new Storyboard();
story.Children.Add(ani);
// Storyboard.SetTargetName(ani, myToy.Name);
Storyboard.SetTarget(ani, transform);
Storyboard.SetTargetProperty(ani, new PropertyPath(RotateTransform.AngleProperty));
story.Begin(this);
}
}
thanks for any help.
The target of your animation is a MyToy object and your target property is Angle. MyToy doesn't have an angle property though. Solution: Set the RenderTransform (or LayoutTransform) property of MyToy to be a new RotateTransform object. Then use that object (which has the Angle property) as the target of the animation.
I have the following problem to solve: I have some ellipses in my xaml that work as buttons, and some of them may open in 2 new buttons when clicked. I put them in separate canvas, in a way that this buttons to be generated already exist with opacity 0. What I want is to have an effect to set this buttons opacity to 1 when I click their parent button, in a transition. How can I achieve that?
C#
private void ExpandHarborButtons(object sender, MouseButtonEventArgs e)
{
Ellipse thisPath = (Ellipse)sender;
String test = (String)thisPath.DataContext;
for(int i = 0; i < DoubleHarbors.Children.Count; i++)
{
Ellipse button = (Ellipse)VisualTreeHelper.GetChild(DoubleHarbors, i);
if (test.Contains((String)button.DataContext))
{
button.Opacity = 1;
}
}
}
That's the way I'm doing right now, but it doesn't work as I want. The buttons are shown, but not with the effect I told before.
Create a DoubleAnimation and start it from the click. Something like this:
<Storyboard x:Name="fadeIn">
<DoubleAnimation Storyboard.TargetName="ButtonName" From="0.0" To="0.1" Duration="0:0:0.5"
Soryboard.TargetProperty="Opacity"/>
</Storyboard>
Then in Code:
fadeIn.Begin();
--EDIT--
Here's how to do an animation in C#. It's actually easier to define in XAML, but if this is really what you want, this is a way to do it.
Storyboard sb = new Storyboard();
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = 1.0;
da.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
sb.Children.Add(da);
Storyboard.SetTarget(sb, sender as Button);
Storyboard.SetTargetProperty(Button1, new PropertyPath("Opacity"));
sb.Begin();