c# - WPF التطبيق لا تغلق عند إغلاق النافذة الرئيسية




3 Answers

في MainWindow.xaml.cs ، حاول القيام بذلك:

protected override void OnClosed(EventArgs e)
{
    base.OnClosed(e);

    Application.Current.Shutdown();
}

في هذا الرابط ، يمكنك أيضًا تعيين ShutdownMode في XAML:

http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="MainWindow.xaml"
    ShutdownMode="OnExplicitShutdown"
    >
</Application>

تتوقف التطبيقات عن العمل فقط عندما يتم استدعاء طريقة Shutdown Application . يمكن أن يحدث إيقاف التشغيل ضمنيًا أو صريحًا ، كما هو محدد بواسطة قيمة الخاصية ShutdownMode .

إذا قمت بتعيين ShutdownMode إلى OnLastWindowClose ، OnLastWindowClose Windows Presentation Foundation (WPF) ضمنياً إيقاف التشغيل عند إغلاق الإطار الأخير في تطبيق ما ، حتى إذا تم تعيين أي إطار تم إنشاؤه حاليًا كنافذة رئيسية (انظر MainWindow).

يؤدي ShutdownMode من OnMainWindowClose WPF استدعاء "إيقاف التشغيل" ضمنيًا عند إغلاق MainWindow ، حتى في حالة فتح الإطارات الأخرى حالياً.

قد لا يعتمد عمر بعض التطبيقات على وقت إغلاق النافذة الرئيسية أو النافذة الأخيرة ، أو قد لا يعتمد على النوافذ على الإطلاق. بالنسبة لهذه السيناريوهات ، تحتاج إلى تعيين الخاصية ShutdownMode إلى OnExplicitShutdown ، والتي تتطلب استدعاء أسلوب Shutdown صريح لإيقاف التطبيق. خلاف ذلك ، يستمر التطبيق قيد التشغيل في الخلفية.

يمكن تكوين ShutdownMode بشكل تبادلي من XAML أو برمجيًا من التعليمات البرمجية.

هذه الخاصية متوفرة فقط من مؤشر الترابط الذي أنشأ كائن Application .

في حالتك ، لا يتم إغلاق التطبيق نظرًا لأنك على الأرجح تستخدم الافتراضي OnLastWindowClose :

إذا قمت بتعيين ShutdownMode إلى OnLastWindowClose ، WPF يستدعي ضمنياً إيقاف التشغيل عندما يتم إغلاق الإطار الأخير في أحد التطبيقات ، حتى إذا تم تعيين أي إطار تم إنشاؤه حاليًا كنافذة رئيسية (انظر MainWindow ).

نظرًا لأنك تفتح نافذة جديدة ، ولا تغلقها ، فلن يتم استدعاء إيقاف التشغيل.

أنا معتاد على WinForms البرمجة في Visual Studio ، ولكن كنت أرغب في إعطاء WPF محاولة.

أضفت نافذة أخرى إلى مشروعي ، تسمى Window01. يسمى الإطار الرئيسي MainWindow. قبل المصمم العام MainWindow public MainWindow() أعلن Window01:

Window01 w1;

الآن أقوم بإنشاء هذه النافذة في:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    w1 = new Window01();            
}

لدي زر تظهر فيه النافذة: w1.ShowDialog(); .

الشيء "المضحك" هنا هو حقيقة أنه في حالة بدء التطبيق (مع تصحيح الأخطاء) والخروج منه بعد ثوانٍ قليلة (لا أفعل أي شيء في التطبيق) ، لا يتوقف Visual Studio عن تصحيح الأخطاء كما لو كان التطبيق لا يزال قيد التشغيل.

إذا قمت بنقل السطر w1 = new Window01(); إلى طريقة النقر فوق الزر ، وهذا يعني فقط فوق ShowDialog() ، يعمل Visual Studio بشكل صحيح - وهذا يعني أن التصحيح يتوقف عند الخروج من التطبيق.

لماذا هذا السلوك الغريب؟




لأن http://msdn.microsoft.com/en-us/library/system.windows.application.shutdownmode.aspx الافتراضي في تطبيق WPF هو OnLastWindowClose ، مما يعني توقف التطبيق عند إغلاق النافذة الأخيرة.

عند إنشاء كائن إطار جديد ، تتم إضافته تلقائيًا إلى قائمة الإطارات في التطبيق. لذا ، كانت المشكلة أن التطبيق الخاص بك كان يقوم بإنشاء نافذتين عند بدء التشغيل - MainWindow و Window01 غير الموضح بعد - وإذا قمت فقط بإغلاق MainWindow ، فإن Window01 سيبقي التطبيق قيد التشغيل.

عادة ، ستقوم بإنشاء كائن نافذة بنفس الطريقة التي ستقوم باستدعاء ShowDialog الخاص بها ، وستقوم بإنشاء كائن نافذة جديد في كل مرة يظهر فيها مربع الحوار.




تعثرت عبر هذا السؤال عند البحث عن شيء آخر وفوجئت بأنني لم أتمكن من رؤية أي من الإجابات المقترحة التي تشير إلى Window.Owner .

    {
       var newWindow = new AdditionalWindow();
       newWindow.Owner = Window.GetWindow(this);

       // then later on show the window with Show() or ShowDialog()
    }

يعتبر الاتصال بـ Window.GetWindow(this) مفيدًا تمامًا في طريقة عرض تطبيق MVVM عندما تكون بعيدًا عن الشجرة المرئية التي لا تعرف مكان تثبيتها ، يمكن أن يطلق عليها عن طريق توفير أي عنصر FrameWork (مثل UserContol أو Button أو Page ). من الواضح إذا كان لديك إشارة مباشرة إلى النافذة ثم استخدم هذا أو حتى Application.Current.MainWindow .

هذه علاقة قوية للغاية تحتوي على عدد من الفوائد المفيدة التي قد لا تدرك أنها تبدأ (بافتراض أنك لم ترميز نوافذ منفصلة لتجنب هذه العلاقات).

إذا MainWindow بك MainWindow النافذة الرئيسية والنافذة الثانية كما AdditionalWindow ثم ....

  1. تصغير MainWindow سوف أيضاً تصغير MainWindow
  2. استعادة MainWindow أيضاً استعادة MainWindow
  3. إغلاق إغلاق MainWindow سوف MainWindow ولكن إغلاق MainWindow إغلاق MainWindow
  4. لن تحصل على AdditioanlWindow أبدًا "ضائعة" تحت MainWindow ، أي AddditionalWindow يظهر دائمًا فوق MainWindow في الترتيب z إذا استخدمت Show() لعرضه (مفيد جدًا!)

شيء واحد أن نلاحظ على الرغم من ذلك ، إذا كان لديك هذه العلاقة ، ثم لا يتم استدعاء الحدث Closing على AdditionalWindow ، لذلك عليك أن تتكرر يدويا عبر مجموعة OwnedWindows . على سبيل المثال ، قم بإنشاء طريقة للاتصال بكل نافذة عبر واجهة جديدة أو طريقة أساسية.

    private void MainWindow_OnClosing(object sender, CancelEventArgs e)
    {
        foreach (var window in OwnedWindows)
        {
            var win = window as ICanCancelClosing;  // a new interface you have to create
            e.Cancel |= win.DoYouWantToCancelClosing();
        }        
    }



Related