[英]How to create BeginStoryboard in code behind for WPF?
我有以下XAML,我希望將其轉換為代碼,我已經能夠成功創建動畫,因此控件按預期淡入和淡出,但我無法將IsMouseOver觸發器轉換為代碼隱藏:
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Control.Loaded"
SourceName="NotificationGrid">
<BeginStoryboard x:Name="BeginNotificationStoryboard">
<Storyboard x:Name="NotificationStoryboard">
<DoubleAnimation Storyboard.TargetName="NotificationGrid"
From="0.01"
To="1"
Storyboard.TargetProperty="Opacity"
Duration="0:0:0.5" />
<DoubleAnimation Storyboard.TargetName="NotificationGrid"
From="1"
To="0"
Storyboard.TargetProperty="Opacity"
Duration="0:0:0.5"
BeginTime="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<Trigger Property="IsMouseOver"
Value="True">
<Trigger.EnterActions>
<SeekStoryboard Offset="0:0:3"
BeginStoryboardName="BeginNotificationStoryboard" />
<PauseStoryboard BeginStoryboardName="BeginNotificationStoryboard" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<SeekStoryboard Offset="0:0:3"
BeginStoryboardName="BeginNotificationStoryboard" />
<ResumeStoryboard BeginStoryboardName="BeginNotificationStoryboard" />
</Trigger.ExitActions>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
我遇到的問題是如何知道SeekStoryboard類實例的'BeginStoryboardName'值應該是什么,因為我沒有必要創建一個BeginStoryboard實例來使加載動畫按預期工作。
var loadingAnimation = new DoubleAnimation(0.01, 1, new Duration(TimeSpan.FromSeconds(0.5)));
var closingAnimation = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(3)))
{
BeginTime = TimeSpan.FromSeconds(5)
};
Storyboard.SetTarget(loadingAnimation, AssociatedObject);
Storyboard.SetTarget(closingAnimation, AssociatedObject);
Storyboard.SetTargetProperty(loadingAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard.SetTargetProperty(closingAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard.SetTarget(loadingAnimation, AssociatedObject);
Storyboard.SetTarget(closingAnimation, AssociatedObject);
var storyboard = new Storyboard();
storyboard.Children.Add(loadingAnimation);
storyboard.Children.Add(closingAnimation);
var enterSeekStoryboard = new SeekStoryboard
{
Offset = TimeSpan.FromSeconds(5),
// What value should go here?
BeginStoryboardName = ""
};
var exitSeekStoryboard = new SeekStoryboard
{
Offset = TimeSpan.FromSeconds(5),
// What value should go here?
BeginStoryboardName = ""
};
var trigger = new Trigger
{
Property = UIElement.IsMouseOverProperty,
Value = true
};
trigger.EnterActions.Add(enterSeekStoryboard);
trigger.ExitActions.Add(exitSeekStoryboard);
var style = new Style();
style.Triggers.Add(trigger);
AssociatedObject.Style = style;
storyboard.Completed += HandleOnCompleted;
storyboard.Begin();
你的完整代碼就是這樣的。 我留下了一些評論來指出我發現的一些問題:
var loadingAnimation = new DoubleAnimation(0.01, 1, new Duration(TimeSpan.FromSeconds(0.5)));
var closingAnimation = new DoubleAnimation(1, 0, new Duration(TimeSpan.FromSeconds(3)))
{
BeginTime = TimeSpan.FromSeconds(5)
};
Storyboard.SetTarget(loadingAnimation, AssociatedObject);
Storyboard.SetTarget(closingAnimation, AssociatedObject);
Storyboard.SetTargetProperty(loadingAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard.SetTargetProperty(closingAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard.SetTarget(loadingAnimation, AssociatedObject);
Storyboard.SetTarget(closingAnimation, AssociatedObject);
var storyboard = new Storyboard();
storyboard.Children.Add(loadingAnimation);
storyboard.Children.Add(closingAnimation);
// Subscription to events must be done at this point, because the Storyboard object becomes frozen later on
storyboard.Completed += HandleOnCompleted;
string storyBoardName = "BeginNotificationStoryboard";
// We define the BeginStoryBoard action for the EventTrigger
var beginStoryboard = new BeginStoryBoard();
beginStoryboard.Name = storyBoardName;
beginStoryboard.Storyboard = storyboard;
// We create the EventTrigger
var eventTrigger = new EventTrigger(Control.LoadedEvent);
eventTrigger.Actions.Add(beginStoryboard);
// Actions for the entering animation
var enterSeekStoryboard = new SeekStoryboard
{
Offset = TimeSpan.FromSeconds(5),
BeginStoryboardName = storyBoardName
};
var enterPauseStoryboard = new PauseStoryboard
{
BeginStoryboardName = storyBoardName
};
// Actions for the exiting animation
var exitSeekStoryboard = new SeekStoryboard
{
Offset = TimeSpan.FromSeconds(5),
BeginStoryboardName = storyBoardName
};
var exitResumeStoryboard = new ResumeStoryboard
{
BeginStoryboardName = storyBoardName
};
var trigger = new Trigger
{
Property = UIElement.IsMouseOverProperty,
Value = true
};
trigger.EnterActions.Add(enterSeekStoryboard);
trigger.EnterActions.Add(enterPauseStoryboard);
trigger.ExitActions.Add(exitSeekStoryboard);
trigger.ExitActions.Add(exitResumeStoryboard);
var style = new Style();
// The name of the Storyboard must be registered so the actions can find it
style.RegisterName(storyBoardName, beginStoryboard);
// Add both the EventTrigger and the regular Trigger
style.Triggers.Add(eventTrigger);
style.Triggers.Add(trigger);
AssociatedObject.Style = style;
// No need for storyboard.Begin()
您已創建Storyboard但未創建BeginStoryboard。 所以這樣做:
var storyboard = new Storyboard();
storyboard.Children.Add(loadingAnimation);
storyboard.Children.Add(closingAnimation);
var beginStoryboard = new BeginStoryboard(){ Name="BeginNotificationStoryboard", Storyboard = storyboard};
var enterSeekStoryboard = new SeekStoryboard
{
Offset = TimeSpan.FromSeconds(5),
// What value should go here?
BeginStoryboardName = "BeginNotificationStoryboard"
};
別忘了像以前一樣將beginStoryboard添加到EventTrigger。
實際上原始XAML代碼使用BeginNotificationStoryboard id只是為了刪除一些代碼重復。 如果您不再需要它,只需將其添加到TriggerActions,如下所示:
trigger.EnterActions.Add(beginStoryboard);
比你不需要指定名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.