I used this code to animation my window:
winLogin login = new winLogin();
login.Owner = this;
login.Show();
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = this.Left + ((this.Width - login.Width) / 2);
da.AutoReverse = false;
da.Duration = new Duration(TimeSpan.FromSeconds(0.1));
login.BeginAnimation(Window.LeftProperty, da);
Problem is that whenever i set the Left property of this window(after the animation), it goes crazy.
I used this code to align the child windows to be always on the center but the Left property of the windows on which i used an animation cannot be properly changed.
private void Window_LocationChanged(object sender, EventArgs e)
{
foreach (Window win in this.OwnedWindows)
{
win.Top = this.Top + ((this.Height - win.Height) / 2);
win.Left = this.Left + ((this.Width - win.Width) / 2);
}
}
First of all, when you set an animation you should always remove the potential previous animation of that property:
login.BeginAnimation(Window.LeftProperty, null);
login.BeginAnimation(Window.LeftProperty, da);
If you don't so this you will get a memory leak and probably some other undesired behavior.
Also due to the DependencyProperty precedence you can not set a value on a DependecyProperty that has an active animation, wich is the case in your animation because its FillBehavior is set to HoldEnd (the default). Again you would have to remove the animation first.
Related
I want to move a window with a storyboard. But after the storyboard completed, if you move the window with mouse, the property "Window.Left" doesn't change when you move the window. I can set "FillBehavior=FillBehavior.Stop" to solve this problem, but I don't know why.
public void MoveWindow()
{
Storyboard storyboard = new Storyboard();
DoubleAnimation xAnimation = new DoubleAnimation();
Storyboard.SetTarget(xAnimation, this);
Storyboard.SetTargetProperty(xAnimation, new PropertyPath("(Window.Left)"));
xAnimation.From = this.Left;
xAnimation.To = this.Left + 100;
xAnimation.Duration = TimeSpan.FromSeconds(0.2);
storyboard.Children.Add(xAnimation);
storyboard.Begin();
}
private void btn_Move_Click(object sender, RoutedEventArgs e)
{
MoveWindow();
}
Set FillBehavior.Stop to ensure that the animation does not hold the property value.
From the Remarks in the online documentation:
Set an animations FillBehavior property to HoldEnd when you want the animation to hold its value after it reaches the end of its active period. An animation that has reached the end of its active period that has a FillBehavior setting of HoldEnd is said to be in its fill period. When you don't want an animation to hold its value after it reaches the end of its active period, set its FillBehavior property to Stop.
Add a Completed event handler to set the current property after the animation has run.
public void MoveWindow()
{
var xAnimation = new DoubleAnimation
{
To = Left + 100,
Duration = TimeSpan.FromSeconds(0.2),
FillBehavior = FillBehavior.Stop
};
xAnimation.Completed += (s, e) => Left += 100;
BeginAnimation(LeftProperty, xAnimation);
}
I have two canvases and a textblock with name tbmarquee, on window load it animates from top to bottom, but i want to stop when i over the mose on it, and when i click it goes to the link, how to do it ?
void Window1_Loaded(object sender, RoutedEventArgs e)
{
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = -tbmarquee.ActualHeight;
doubleAnimation.To = canMain.ActualHeight;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.Parse("0:0:10"));
tbmarquee.BeginAnimation(Canvas.TopProperty, doubleAnimation);
}
On mouse over event handler of tbmarquee, call BeginAnimation() again with second argument set to null to stop the animation :
tbmarquee.BeginAnimation(Canvas.TopProperty, null);
Related question : How to stop an animation in C# / WPF?
friends,thank you for your time!
There's a problem in the codes below in WPF.I use a ProgressBar and a Animation which show the progress of value changes.When the Animation finished,I try to reset the value to 0 ,so that the ProgressBar can begin a new Animation from 0 to 100 again.But the result is that I can't set the value to 0,it seems that it would be 100 forever no matter how I tried!!!!!
Could you please give me some ideas,thank you!
pbStatus.Value = 0;//Promblem!! pbStatus is a ProgressBar
Duration dr = new Duration(TimeSpan.FromSeconds(2));
DoubleAnimation da = new DoubleAnimation(100, dr);
pbStatus.IsIndeterminate = false;
pbStatus.Visibility = Visibility.Visible;
pbStatus.BeginAnimation(ProgressBar.ValueProperty, da);
Please see this article.
Summary: There are three ways to set a value after an animation.
Set the animation's FillBehavior property to Stop
Remove the entire Storyboard. (Not applicable since you have no storyboard)
Remove the animation from the individual property.
(1) Set the fill behaviour of the animation to stop:
da.FillBehavior = FillBehavior.Stop;
(3) Remove the animation by calling this before setting the new value:
pbStatus.BeginAnimation(ProgressBar.ValueProperty, null);
From this article:
private void CreateDynamicProgressBarControl()
{
ProgressBar PBar2 = new ProgressBar();
PBar2.IsIndeterminate = false;
PBar2.Orientation = Orientation.Horizontal;
PBar2.Width = 100;
PBar2.Height = 10;
Duration duration = new Duration(TimeSpan.FromSeconds(10));
DoubleAnimation doubleanimation = new DoubleAnimation(100.0, duration);
PBar2.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);
SBar.Items.Add(PBar2);
}
I have a wpf window that hosts a control.
The window's height and width are set to SizeToControl.
Now I need to position this Window relative to the position of its parent window.(basically the Top right position).
(So my windows Top = ParentWindow.Top, and Left = ParentWindow.Left + ParentWindow.ActualWidth - control.ActualWidth so that my window is positioned inside the parent window but to its right corner)
So i will need to set the Top and Left of the window. To do this I need the Actual Width of the control that is being hosted inside it....but I can only get this once I actually do,
Window.Show(control,parent)
Is there a way to get around this problem? How do I get the actual rendered width of the control before it is actually shown?
Thanks!
Have you tried this approach?
public partial class ShellWindow : Window
{
public ShellWindow(IShellPresentationModel model)
{
InitializeComponent();
this.Loaded += ShellWindow_Loaded;
}
void ShellWindow_Loaded(object sender, RoutedEventArgs e)
{
var innerWindow = new InnerWindow();
innerWindow.Owner = this;
innerWindow.Loaded += InnerWindow_Loaded;
innerWindow.Show();
}
void InnerWindow_Loaded(object sender, RoutedEventArgs e)
{
var w = (InnerWindow)sender;
w.Owner = this;
w.Top = this.Top;
w.Left = this.Left + this.ActualWidth - w.ActualWidth;
}
}
I'm just creating my own AboutBox and I'm calling it using Window.ShowDialog()
How do I get it to position relative to the main window, i.e. 20px from the top and centered?
You can simply use the Window.Left and Window.Top properties. Read them from your main window and assign the values (plus 20 px or whatever) to the AboutBox before calling the ShowDialog() method.
AboutBox dialog = new AboutBox();
dialog.Top = mainWindow.Top + 20;
To have it centered, you can also simply use the WindowStartupLocation property. Set this to WindowStartupLocation.CenterOwner
AboutBox dialog = new AboutBox();
dialog.Owner = Application.Current.MainWindow; // We must also set the owner for this to work.
dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
If you want it to be centered horizontally, but not vertically (i.e. fixed vertical location), you will have to do that in an EventHandler after the AboutBox has been loaded because you will need to calculate the horizontal position depending on the Width of the AboutBox, and this is only known after it has been loaded.
protected override void OnInitialized(...)
{
this.Left = this.Owner.Left + (this.Owner.Width - this.ActualWidth) / 2;
this.Top = this.Owner.Top + 20;
}
gehho.
I would go the manual way, instead of count on WPF to make the calculation for me..
System.Windows.Point positionFromScreen = this.ABC.PointToScreen(new System.Windows.Point(0, 0));
PresentationSource source = PresentationSource.FromVisual(this);
System.Windows.Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(positionFromScreen);
AboutBox.Top = targetPoints.Y - this.ABC.ActualHeight + 15;
AboutBox.Left = targetPoints.X - 55;
Where ABC is some UIElement within the parent window (could be Owner if you like..) , And could also be the window itself (top left point)..
Good luck