سؤال

وأريد أن تتلاشى نافذة داخل / خارج في طلبي.
يتلاشى في يحدث في Window.Loaded وأردت أن تتلاشى على وثيقة (Window.Closed أو Window.Closing). يتلاشى في أعمال تماما، ولكن لا يسمح Window.Closing قيمة الممتلكات RoutedEvent.
ما RoutedEvent يجب أن تكون تستخدم لإغلاق؟

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

وأحصل على خطأ على، قيمة "Window.Closing" لا يمكن أن تسند إلى خاصية "RoutedEvent. اسم الحدث غير صالح.

هل كانت مفيدة؟

المحلول

والإنتهاء ليس حدثا توجيهها، بحيث لا يمكن استخدامها في EventTrigger. ربما كنت قد تبدأ لوحة العمل في معالج من ClosingEvent في التعليمات البرمجية الخلفية وإلغاء الحدث ... شيء من هذا القبيل:

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

نصائح أخرى

واعتقدت أن إضافة حل آخر للقيام بذلك، وذلك باستخدام السلوكيات من 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>

لاحظ i أكس مساحة من دلل System.Windows.Interactivity، وأيضا أن تتم الإشارة النافذة، لذلك لا بد أن يكون x:Name المعين. الآن نحن ببساطة إضافة السلوك إلى كل نافذة التي نود أن تنفيذ القصة المصورة قبل أن يغلق عند التطبيق، بدلا من نسخ المنطق على كل رمز وراء كل نافذة.

وأنا لست خبيرا في WPF ولكن أعتقد أنه ما لم تقم بإلغاء حالة الإنتهاء الأولي ستزول نافذة قبل بدء الحركة حتى.

وعند استلام هذا الحدث Window.Closing، يجب إلغاء الحدث والبدء في الرسوم المتحركة. عندما يتم الرسوم المتحركة يمكنك إغلاق النافذة.

وهذا هو أبسط وأقصر. إضافة السلوك كما يلي:

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

وبعد ذلك في نافذة إضافة مرجع:

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

وأدخل السلوك:

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

وتعيين AutoReverse ل"صحيح"

<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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top