Я подумал, что добавлю еще одно решение: использовать поведения из Expression SDK и объединить его с решением от @Thomas. Используя это, мы можем определить «CloseBehavior», который обрабатывает код запуска раскадровки и закрытия окна, когда это будет сделано.
using System.ComponentModel;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Media.Animation;
namespace Presentation.Behaviours {
public class CloseBehavior : Behavior<Window> {
public static readonly DependencyProperty StoryboardProperty =
DependencyProperty.Register("Storyboard", typeof(Storyboard), typeof(CloseBehavior), new PropertyMetadata(default(Storyboard)));
public Storyboard Storyboard {
get { return (Storyboard)GetValue(StoryboardProperty); }
set { SetValue(StoryboardProperty, value); }
}
protected override void OnAttached() {
base.OnAttached();
AssociatedObject.Closing += onWindowClosing;
}
private void onWindowClosing(object sender, CancelEventArgs e) {
if (Storyboard == null) {
return;
}
e.Cancel = true;
AssociatedObject.Closing -= onWindowClosing;
Storyboard.Completed += (o, a) => AssociatedObject.Close();
Storyboard.Begin(AssociatedObject);
}
}
}
Поведение определяет раскадровку как свойство зависимости, поэтому мы можем установить его в xaml, и когда AssociatedObject
(окно, в котором мы определяем поведение) закрывается, эта раскадровка запускается с использованием Storyboard.Begin()
. Теперь в xaml мы просто добавляем поведение в окно, используя следующий xaml
<Window x:Class="Presentation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:behave="clr-namespace:Presentation.Behaviours"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
x:Name="window">
<Window.Resources>
<Storyboard x:Key="ExitAnimation">
<DoubleAnimation Storyboard.Target="{Binding ElementName='window'}"
Storyboard.TargetProperty="(Window.Opacity)"
Duration="0:0:1" From="1" To="0"/>
</Storyboard>
</Window.Resources>
<i:Interaction.Behaviors>
<behave:CloseBehavior Storyboard="{StaticResource ExitAnimation}"/>
</i:Interaction.Behaviors>
<Grid>
</Grid>
</Window>
Обратите внимание на пространство имен xml i
из dll System.Windows.Interactivity, а также на то, что на окно ссылаются, поэтому ему нужно присвоить x:Name
. Теперь мы просто добавляем поведение к каждому окну, в котором мы хотим выполнить раскадровку перед закрытием приложения, вместо того, чтобы копировать логику для каждого кода в каждом окне.