Frage

Ich möchte in meiner Anwendung ein Fenster in / out verblassen.
Schwund tritt in auf Window.Loaded und ich wollte auf eine enge (Window.Closed oder Window.Closing) auszublenden. Verblassen in funktioniert perfekt, aber Window.Closing ist kein gutes Preis-RoutedEvent Eigenschaft erlaubt.
Welche RoutedEvent sollte ich für Close verwenden?

    <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>

Ich erhalte einen Fehler auf, Value ‚Window.Closing‘ kann nicht auf Eigentum ‚RoutedEvent‘ zugeordnet werden. Ungültige Ereignisnamen.

War es hilfreich?

Lösung

Closing ist kein Routingereignis, so dass Sie es nicht in einem Eventtrigger verwenden können. Vielleicht könnten Sie das Storyboard in der Prozedur des ClosingEvent in der Code-Behind-Start und das Ereignis ... so etwas wie das Abbrechen:

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();
}

Andere Tipps

Ich dachte, ich eine andere Lösung, dies zu tun hinzufügen würde, Verhaltensweisen aus dem Ausdruck SDK und es mit der Lösung von @Thomas kombinieren. Mit, dass, können wir eine „CloseBehavior“ definieren, die den Code behandelt hinter der ein Storyboard und das Fenster zu schließen beginnt, wenn es fertig ist.

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);
        }
    }
}

Das Verhalten definiert ein Storyboard als Abhängigkeitseigenschaft, also können wir es in XAML festlegen und wenn die AssociatedObject (das Fenster, in dem wir das Verhalten definieren) enden, das Storyboard gestartet wird mit Storyboard.Begin(). Nun, in XAML fügen wir einfach das Verhalten auf das Fenster mit dem folgende 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>

Beachten Sie die XML-Namespace i aus der System.Windows.Interactivity dll, und auch, dass das Fenster Bezug genommen wird, so hat es eine x:Name zugewiesen haben. Nun fügen wir einfach das Verhalten zu jedem Fenster, auf das wir wünschen, ein Storyboard auszuführen, bevor die Anwendung schließen, anstelle dem Kopieren die Logik zu jedem Code-behind in jedem Fenster.

Ich bin kein Experte für WPF, aber ich glaube, dass, wenn Sie die erste Abschlussveranstaltung abbrechen wird das Fenster verschwunden sein, bevor die Animation einmal begonnen.

Nach dem Window.Closing Ereignisse empfängt, sollten Sie das Ereignis abbrechen und die Animation starten. Wenn die Animation fertig ist, können Sie das Fenster schließen.

Das ist noch einfacher und kürzer. Fügen Sie ein Verhalten wie folgt:

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;
        }
    }

Dann in Ihrem Fenster fügen Sie einen Verweis:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:wt="clr-namespace:Desktop.Themes.WindowTask;assembly=Desktop.Themes"

Legen Sie das Verhalten:

<i:Interaction.Behaviors>
     <wt:WindowClosingBehavior />
</i:Interaction.Behaviors>

Set Autoreverse auf "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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top