Fermer la fenêtre de la wpf
je veux effacer une fenêtre d'entrée/sortie dans mon application.
La décoloration se produit dans le Window.Loaded
et je voulais fade out sur fermer (Window.Closed
ou Window.Closing
).
La décoloration dans fonctionne parfaitement, mais Window.Closing
n'est pas autorisé de la valeur pour RoutedEvent
propriété.
RoutedEvent
devrais-je utiliser pour fermer?
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:2" FillBehavior="HoldEnd" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Window.Closing">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:2" FillBehavior="HoldEnd" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
j'obtiens une erreur sur la fenêtre, Value'.La fermeture ' ne peut pas être attribuée à la propriété 'RoutedEvent'. Invalide nom de l'événement.
5 réponses
la fermeture n'est pas un événement routé, donc vous ne pouvez pas l'utiliser dans un EventTrigger. Peut-être pourriez-vous commencer le story-board dans le handler du ClosingEvent dans le code-behind et annuler l'événement... quelque chose comme ça :
private bool closeStoryBoardCompleted = false;
private void Window_Closing(object sender, CancelEventArgs e)
{
if (!closeStoryBoardCompleted)
{
closeStoryBoard.Begin();
e.Cancel = true;
}
}
private void closeStoryBoard_Completed(object sender, EventArgs e)
{
closeStoryBoardCompleted = true;
this.Close();
}
j'ai pensé ajouter une autre solution de faire ceci, en utilisant les comportements de L'Expression SDK et en la combinant avec la solution de @Thomas. En utilisant cela, nous pouvons définir un "CloseBehavior" qui gère le code derrière le démarrage d'un storyboard et la fermeture de la fenêtre quand il est fait.
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);
}
}
}
le behavior définit un storyboard comme une propriété de dépendance, donc nous pouvons le définir dans xaml et quand le AssociatedObject
(la fenêtre où nous définissons le comportement) se ferme, ce storyboard est a commencé à utiliser Storyboard.Begin()
. Maintenant, dans xaml nous ajoutons simplement le comportement à la fenêtre en utilisant le xaml suivant
<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>
notez l'espace de noms xml i
à partir du Système.Windows.L'interactivité dll, et aussi que la fenêtre est référencé, donc il doit avoir un x:Name
assigné. Maintenant nous ajoutons simplement le comportement à chaque fenêtre sur laquelle nous voulons exécuter un storyboard avant de fermer l'application, au lieu de copier la logique à chaque code-derrière dans chaque fenêtre.
Je ne suis pas un expert en WPF mais je crois que si vous n'annulez pas l'événement de fermeture initial, la fenêtre disparaîtra avant même que l'animation ne commence.
à la réception de la fenêtre.Événement de clôture, vous devez annuler l'événement et commencer l'animation. Lorsque l'animation est terminé, vous pouvez fermer la fenêtre.
C'est encore plus simple et plus courte. Ajouter un comportement comme suit:
public class WindowClosingBehavior : Behavior<Window>
{
protected override void OnAttached()
{
AssociatedObject.Closing += AssociatedObject_Closing;
}
private void AssociatedObject_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Window window = sender as Window;
window.Closing -= AssociatedObject_Closing;
e.Cancel = true;
var anim = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(0.5));
anim.Completed += (s, _) => window.Close();
window.BeginAnimation(UIElement.OpacityProperty, anim);
}
protected override void OnDetaching()
{
AssociatedObject.Closing -= AssociatedObject_Closing;
}
}
puis dans votre fenêtre Ajouter une référence:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:wt="clr-namespace:Desktop.Themes.WindowTask;assembly=Desktop.Themes"
insérez le comportement:
<i:Interaction.Behaviors>
<wt:WindowClosingBehavior />
</i:Interaction.Behaviors>
Définir AutoReverse À "True"
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" AutoReverse="True" From="0" To="1" Duration="0:0:0.5" FillBehavior="HoldEnd" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>