C# 窗口的WPF动画。顶部在不同的值处停止
我构建了一个类似“Windows8StartMenu”的应用程序。我使用一个动画,将菜单窗口从底部滑入屏幕。动画使用Window.Top设置动画 但每次我运行应用程序时,“Top”的值在 当(仔细阅读!)我在“SizeChanged”行上设置断点时,在~5到~15点之间出现抖动。这意味着在执行“businessLogic.CalculateWindowTopLeft”之前。这意味着,我看到的“顶部”是动画顶部的结束值 他为什么要这么做???这是一个奇怪的W32/WPF/wHandle Bug吗?我不理解这种行为 额外评论: 首先,我用xaml编写了动画代码并对其进行了绑定(就像您通常所做的那样)。为了调试,我已经在代码隐藏中完成了这项工作(见下文)。我还尝试(见下文)在动画发生后设置绑定,这样绑定就不会出错。这种行为在所有情况下都是完全相同的(错误的) 告诉我,如果您仍然需要xaml代码,那么我会发布它 (很抱歉英语不好,我是德国人) }有趣的 这个非常(!)简单的代码创建了完全相同的行为。开始10次,你就明白我的意思了。我不敢相信……:)C# 窗口的WPF动画。顶部在不同的值处停止,c#,.net,wpf,C#,.net,Wpf,我构建了一个类似“Windows8StartMenu”的应用程序。我使用一个动画,将菜单窗口从底部滑入屏幕。动画使用Window.Top设置动画 但每次我运行应用程序时,“Top”的值在 当(仔细阅读!)我在“SizeChanged”行上设置断点时,在~5到~15点之间出现抖动。这意味着在执行“businessLogic.CalculateWindowTopLeft”之前。这意味着,我看到的“顶部”是动画顶部的结束值 他为什么要这么做???这是一个奇怪的W32/WPF/wHandle Bug吗?
名称空间幻灯片测试
{
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
停用+=(s,e)=>关闭();
}
}
}
我找到了解决办法。不是很好,但是唯一有效的。我永远也不会理解那种“fillbehavior=Stop”的行为。对我来说,这似乎是一个bug(即使我不能相信),或者是“wpf动画的本质”中的一些奇怪的东西 那么,我们开始吧:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Deactivated += (s, e) => Close();
myAnimation.Completed += (s, e) =>
{
this.BeginAnimation(Window.TopProperty, null);
myStoryboard.Remove();
};
}
}
<Window x:Class="SlideTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="200" Top="455" Left="700"
WindowStyle="None" AllowsTransparency="True" Background="Aqua">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard Duration="00:00:.30" Name="myStoryboard">
<DoubleAnimation Duration="00:00:.30" AccelerationRatio="0.1" Storyboard.TargetProperty="Top" From="1400" To="455" FillBehavior="HoldEnd" Name="myAnimation"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
停用+=(s,e)=>关闭();
myAnimation.Completed+=(s,e)=>
{
this.BeginAnimation(Window.TopProperty,null);
myStoryboard.Remove();
};
}
}
希望这能为其他人节省很多时间…我检测到wAnimation.FillBehavior=FillBehavior.HoldEnd有效。但我需要更改顶部值,因此我不能使用“HoldEnd”,问题也是一样的:当我使用FillBehavior“Stop”时,为什么会这样做?当然,您必须将高度等设置为适当的屏幕尺寸。在上述情况下,我使用1440x900屏幕。
public MainWindow()
{
Visibility = Visibility.Hidden;
InitializeComponent();
businessLogic = new BusinessLogic(new DataModel(), new DataPersister());
var vm = new MainWindowViewModel(businessLogic, new DialogService());
DataContext = vm;
businessLogic.Load();
Width = businessLogic.DataModel.MenuWidth;
Height = businessLogic.DataModel.MenuHeight;
Opacity = 0;
windowPosition = businessLogic.CalculateWindowTopLeft(Width, Height);
Top = SystemParameters.PrimaryScreenHeight - (Height * 0.50);
//Top = windowPosition.Y;
Left = windowPosition.X;
Background = businessLogic.GetTaskBarPreviewSolidColorBrush(1);
vm.CloseRequested += (s) => Hide();
Deactivated += (s, e) => { if (!vm.SettingsOpened) Close(); };
Loaded += (s, e) =>
{
var wAnimation = new System.Windows.Media.Animation.DoubleAnimation(windowPosition.Y, new Duration(new TimeSpan(0, 0, 0, 0, 300)));
wAnimation.FillBehavior = System.Windows.Media.Animation.FillBehavior.Stop;
wAnimation.AccelerationRatio = 0.1;
wAnimation.From = Top;
wAnimation.Completed += (s1, e1) =>
{
SizeChanged += (s2, e2) => { if (e2.HeightChanged) Top = businessLogic.CalculateWindowTopLeft(Width, Height).Y; };
};
var oAnimation = new System.Windows.Media.Animation.DoubleAnimation(businessLogic.DataModel.MenuOpacity, new Duration(new TimeSpan(0, 0, 0, 0, 600)));
oAnimation.FillBehavior = System.Windows.Media.Animation.FillBehavior.Stop;
oAnimation.AccelerationRatio = 0.1;
oAnimation.From = 0;
oAnimation.Completed += (s3, e3) =>
{
Binding myBinding = new Binding();
myBinding.Source = DataContext;
myBinding.Path = new PropertyPath("DataModel.MenuOpacity");
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(this, Window.OpacityProperty, myBinding);
};
BeginAnimation(Window.TopProperty, wAnimation);
BeginAnimation(Window.OpacityProperty, oAnimation);
};
Visibility = Visibility.Visible;
}
}
namespace SlideTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Deactivated += (s, e) => Close();
}
}
}
<Window x:Class="SlideTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="200" Top="500" Left="700"
WindowStyle="None" AllowsTransparency="True" Background="Aqua">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard Duration="00:00:.30">
<DoubleAnimation Duration="00:00:.30" AccelerationRatio="0.1" Storyboard.TargetProperty="Top" From="1400" To="455" FillBehavior="Stop"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Deactivated += (s, e) => Close();
myAnimation.Completed += (s, e) =>
{
this.BeginAnimation(Window.TopProperty, null);
myStoryboard.Remove();
};
}
}
<Window x:Class="SlideTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="200" Top="455" Left="700"
WindowStyle="None" AllowsTransparency="True" Background="Aqua">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard Duration="00:00:.30" Name="myStoryboard">
<DoubleAnimation Duration="00:00:.30" AccelerationRatio="0.1" Storyboard.TargetProperty="Top" From="1400" To="455" FillBehavior="HoldEnd" Name="myAnimation"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>