Resizing datagrid does not work - wpf

I can resize datagrid in the window until I excecute this code:
// Handle the tabcontrol animation
DoubleAnimation dbTbViewsAnimation =
new DoubleAnimation(dToTabHeightParameter, new Duration(new TimeSpan(0,0,1)));
this.tbViews.BeginAnimation(TabControl.HeightProperty, dbTbViewsAnimation);
// Handle the tabcontrol animation
DoubleAnimation dbCurrentPlaylistHeightAnimation =
new DoubleAnimation(dToCurrentPlaylistParameter, new Duration(new TimeSpan(0, 0, 1)));
this.dgCurrentPlaylist.BeginAnimation(DataGrid.HeightProperty, dbCurrentPlaylistHeightAnimation);
What is the problem in this code and why it blocks the datagrid resizing?
thank you!

See Timeline.FillBehavior Property. The default value is HoldEnd. You could use a constructor overload to change this behavior.
DoubleAnimation dbTbViewsAnimation =
new DoubleAnimation(dToTabHeightParameter,
new Duration(new TimeSpan(0,0,1)),
FillBehavior.Stop);
FYI: How to: Set a Property After Animating It with a Storyboard

Related

How to set the Background color animation in Silver light and WinRT in code behind?

In WPF we can animate the back ground color for the particular control by using below code:
AssociatedObject.Background.BeginAnimation(SolidColorBrush.ColorProperty, ColorAnimation);
But I don't know how to animate the same in Silverlight and WinRT platforms.
The WPF code is (I think?) a shorthand for creating a storyboard, adding an animation and assigning its target, and running the storyboard. You can do the same in Silverlight like this:
var animation = new ColorAnimation
{
To = Colors.Black,
Duration = new Duration(TimeSpan.FromMilliseconds(500))
};
Storyboard.SetTarget(animation, AssociatedObject.Background);
Storyboard.SetTargetProperty(animation, new PropertyPath(SolidColorBrush.ColorProperty));
var sb = new Storyboard();
sb.Children.Add(animation);
sb.Begin();

WPF animations inside user control

I have a user control that acts like a progress bar and animates the width of a rectangle as a response to an event. Someone arises the event with certain % and the rectangle width animates from its actual width to the % of the actualWidth of the user control.
IF I try to set the new width I get the "The calling thread cannot access this object because a different thread owns it." So I use the Dispatcher.Invoke and it runs nicely.
The problem appears if I try to animate the width change instead of just setting it. Then I get the different thread owns it error event when using the dispatcher.
So. This piece of code works nicely:
bar.Dispatcher.Invoke((Action)delegate { bar.Width = myWidth; });
But this piece of code does not:
DoubleAnimation widthAnimation = new DoubleAnimation();
widthAnimation.From = bar.ActualWidth;
widthAnimation.To = myWidth;
widthAnimation.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500));
widthAnimation.RepeatBehavior = new RepeatBehavior(1);
bar.Dispatcher.Invoke( (Action)delegate {
bar.BeginAnimation(Rectangle.WidthProperty, widthAnimation);
});
So.. how am I suposed to run an animation on a user control like this one??
Thanks in advance !!!
The animation should also be created in the UI thread:
bar.Dispatcher.Invoke((Action)delegate
{
var widthAnimation = new DoubleAnimation
{
From = bar.ActualWidth,
To = myWidth,
Duration = TimeSpan.FromMilliseconds(500)
};
bar.BeginAnimation(Rectangle.WidthProperty, widthAnimation);
});

How to add scale animation to the loading user controls

I want to add animation to the loading user controls in a StackPanel.
So I add these lines to the existing project :
control.Loaded += UserControlLoaded;
and
public void UserControlLoaded(object sender, System.Windows.RoutedEventArgs e)
{
UserControl control = (UserControl)sender;
DoubleAnimation fadeInAnimation = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(5)));
Storyboard.SetTarget(fadeInAnimation, control);
Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard sb = new Storyboard();
sb.Children.Add(fadeInAnimation);
sb.Begin();
}
It works good but I want to change it to scale the user control in both axis from 0 to 1 within 2 seconds but I can't find the code to set target property of the story board to the LayoutTransform X and Y axis !
The transform was made in MS Blend by this way :
How can I do it programmatically.
Thanks in advance for your kind attention.
The code that would animate the control's LayoutTransform depends on the kind of Transform used. Provided that it simply is a ScaleTransform, you could write this:
FrameworkElement control = sender as FrameworkElement;
ScaleTransform transform = control.LayoutTransform as ScaleTransform;
DoubleAnimation scaleAnimation =
new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(2)));
transform.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
transform.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);
When the LayoutTransform was created with Blend, it is most certainly not simply a ScaleTransform, but a TransformGroup with a ScaleTransform as first child. You would then retrieve the ScaleTranform by something like this:
TransformGroup transformGroup = control.LayoutTransform as TransformGroup;
ScaleTransform transform = transformGroup.Children[0] as ScaleTransform;
And again i forgot the reason why animating a Transform like this won't work by means of a Storyboard. Instead of directly calling BeginAnimation on the ScaleTransform object, I've tried the code below, but without success.
DoubleAnimation xScaleAnimation =
new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(2)));
Storyboard.SetTarget(xScaleAnimation, transform);
Storyboard.SetTargetProperty(xScaleAnimation,
new PropertyPath(ScaleTransform.ScaleXProperty));
DoubleAnimation yScaleAnimation =
new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(2)));
Storyboard.SetTarget(yScaleAnimation, transform);
Storyboard.SetTargetProperty(yScaleAnimation,
new PropertyPath(ScaleTransform.ScaleYProperty));
Storyboard sb = new Storyboard();
sb.Children.Add(xScaleAnimation);
sb.Children.Add(yScaleAnimation);
sb.Begin();

WPF Margin Thickness

Background:
I'm loading images into a Stack Panel (called MainStack) displayed horizontally (for argument sake, 10 images) with only room for 4 images in view. As I load the images from the List I'm setting the width of each to 300 so they're all in the same size box.
I want to move the images from right to left using the Stack Panel's Margin (left) property. I want the appearance of scrolling left by exactly the same amount of the width of each image (looped with 4 second delay) until the last image is in view. Here's my code for the Margin animation:
Dim result As New Storyboard
Dim animation As New ThicknessAnimation
animation.From = MainStack.Margin
animation.EasingFunction = New PowerEase() With {.EasingMode = EasingMode.EaseInOut, .Power = 3}
animation.To = New Thickness(-300, 0, 0, 0)
animation.Duration = New Duration(TimeSpan.FromSeconds(1.5))
Storyboard.SetTarget(animation, MainStack)
Storyboard.SetTargetProperty(animation, New PropertyPath("Margin"))
result.Children.Add(animation)
result.Begin()
Strange thing is happening. The Stack Panel is moving to the left but only by about half the width of the image.
What is going on?!?
/* edit */
As per H.B. suggestion, I've tried to implement a TranslateTransform but not having much success.
Can anyone see any problems with this code?
Dim translatePosition = New Point(300, 0)
RenderTransform = New TranslateTransform()
Dim d As New Duration(New TimeSpan(0, 0, 0, 1, 30))
Dim x As New DoubleAnimation(translatePosition.X, d)
Storyboard.SetTarget(x, MainStack)
Storyboard.SetTargetProperty(x, New PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"))
Dim sb As New Storyboard()
sb.Children.Add(x)
sb.Begin()
Nothing seems to be happening.
Ben
I think you should try putting your entire stackpanel in a canvas and just animating the Canvas.Left property to scroll the images.
Another option for you is to use a horizontal ListBox, then you can animate the ScrollViewer. If you want to try it this way, here's a link that may help: WPF - Animate ListBox.ScrollViewer.HorizontalOffset?.

WPF animation problem when using Storyboard from code

I'm working on a 3D carousel of flat, square tiles that will contain information. I'm working on animating this carousel to rotate when a person presses Next and Previous buttons.
I've gotten it to work by using BeginAnimation on the Rotation property of the RotateTransform3D I applied to the carousel, but I can't seem to make a Storyboard version of the same animation work. The reason I need the Storyboard version is for the HandOffBehavior.Compose parameter because without it, multiple clicks of my next and previous buttons results in a misaligned carousel.
Here is the code for the Storyboard:
RotateTransform3D tempTransform = (RotateTransform3D)wheel.Transform;
AxisAngleRotation3D rotation = (AxisAngleRotation3D)tempTransform.Rotation;
Storyboard storyboard = new Storyboard();
DoubleAnimation animation = new DoubleAnimation();
animation.By = defaultAngle;
animation.Duration = TimeSpan.FromSeconds(.5);
Storyboard.SetTarget(animation, rotation);
Storyboard.SetTargetProperty(animation, new PropertyPath("Angle"));
storyboard.Children.Add(animation);
storyboard.Duration = animation.Duration;
storyboard.Begin(new FrameworkContentElement(), HandoffBehavior.Compose);
For some reason, this code results in absolutely nothing. I followed the examples I had to the letter, so I am quite frustrated. Any help is greatly appreciated. I am also completely open to using BeginAnimation if I can replicate HandOffBehavior.Compose.
My experience comes from 2D animation, but I guess the problem is the same.
For some stupid reason (probably relating to an unhealthy focus on XAML), Storyboards can only animate Freezable objects by looking them up by name. (See example in Storyboards Overview.) Thus although you provide a reference to your 'rotation' object when you call Storyboard.SetTarget(animation, rotation), the Storyboard only wants to remember and use a name, which it does not have.
The solution is:
Create a naming scope around the element that will govern the transform.
Call RegisterName() for each Freezable object being animated.
Pass the element to Storyboard.Begin()
Which would make your code look something like this (not tested):
FrameworkContentElement element = new FrameworkContentElement();
NameScope.SetNameScope(element, new NameScope());
RotateTransform3D tempTransform = (RotateTransform3D)wheel.Transform;
AxisAngleRotation3D rotation = (AxisAngleRotation3D)tempTransform.Rotation;
element.RegisterName("rotation", rotation);
Storyboard storyboard = new Storyboard();
DoubleAnimation animation = new DoubleAnimation();
animation.By = defaultAngle;
animation.Duration = TimeSpan.FromSeconds(.5);
Storyboard.SetTarget(animation, rotation);
Storyboard.SetTargetProperty(animation, new PropertyPath("Angle"));
storyboard.Children.Add(animation);
storyboard.Duration = animation.Duration;
storyboard.Begin(element, HandoffBehavior.Compose);
None of this is necessary in XAML because your objects are automatically registered.
EDIT: But then I worked out that you can simplify things by leaving out the Storyboard altogether:
var T = new TranslateTransform(40, 0);
Duration duration = new Duration(new TimeSpan(0, 0, 0, 1, 0);
DoubleAnimation anim = new DoubleAnimation(30, duration);
T.BeginAnimation(TranslateTransform.YProperty, anim);

Resources