2010-08-28 62 views
6

我製作了一個相當複雜的Silverlight 4瀏覽器外應用程序。我的一個主視圖模型向Application.Current.MainWindow.Closing事件添加了一個事件處理程序。 當應用程序最初運行時,這工作正常。它可以取消關閉操作。MainWindow.Closing事件並非總是在Silverlight 4中引發OOB應用程序

但是,有時執行像顯示和關閉一個ChildWindow操作後,MainWindow的Closing事件不再調用我的處理程序。

在調試器中,我向MainWindow的底層關閉事件委託添加了一個監視。在顯示ChildWindow之前它不是空的。然後有時 ChildWindow關閉後委託爲空。這解釋了爲什麼我的處理程序不再被調用。但是,爲什麼這個代表被禁止?爲什麼它只是偶爾發生? 我的應用程序不是在任何時候解除綁定我的事件處理程序。

這是委託我看:

System.Windows.Application.Current.MainWindow.m_closingEvent 

其他的東西:我使用的是卡利微

+0

聽起來像一個非常好的問題。我首先使用的診斷是創建一個簡單的OOB應用程序(不需要校準等),只需打開和關閉ChildWindows並將RootVisuals交換出來以查看是否可以創建簡單的repro。 – AnthonyWJones 2010-08-28 16:21:41

+0

好的,我有同樣的問題 - 只要我不打開/關閉ChildWindow,那麼關閉事件觸發。有時候,如果我連接了調試器,它也會啓動,但並非總是如此。我嘗試了下面的ApplicationWrapper,沒有任何快樂。有什麼建議麼?! – Rodney 2011-04-04 04:30:14

回答

8

我有完全相同的問題。我們有一個運行OOB的大型Silverlight應用程序。

出於某種原因,m_ClosingEvent在運行一段時間後是零。我一直無法找到這個問題的原因,但我認爲這可能與我們改變根視覺或我們展示的所有子窗口有關。

我正在使用ApplicationWrapper類。

public class ApplicationWrapper : IApplicationWrapper 
{ 
    public void Initialize() 
    { 
    HookCloseEvent(true); 
    } 
    private void HookCloseEvent(bool hook) 
    { 
    if (hook && IsRunningOutOfBrowser) 
    { 
     Application.Current.MainWindow.Closing += OnClosing; 
    } 
    else 
    { 
     if (IsRunningOutOfBrowser) 
     { 
     Application.Current.MainWindow.Closing -= OnClosing; 
     } 
    } 
    } 
    private void OnClosing(object sender, ClosingEventArgs e) 
    { 
    InvokeClosing(e); 
    } 

... etc.. 
} 

而InvokeClosing方法從未被調用過。但是當我將其更改爲

public class ApplicationWrapper : IApplicationWrapper 
{ 
    private Window _mainWindow; 

    public void Initialize() 
    { 
    if(IsRunningOutOfBrowser) 
    { 
     _mainWindow = Application.Current.MainWindow; 
    } 
    HookCloseEvent(true); 
    } 

    private void HookCloseEvent(bool hook) 
    { 
    if (hook && IsRunningOutOfBrowser) 
    { 
     _mainWindow.Closing += OnClosing; 
    } 
    else 
    { 
     if (IsRunningOutOfBrowser) 
     { 
     _mainWindow.Closing -= OnClosing; 
     } 
    } 
    } 

    private void OnClosing(object sender, ClosingEventArgs e) 
    { 
    InvokeClosing(e); 
    } 

... etc... 
} 

m_ClosingEvent未被清除。

因此,試着將「初始」MainWindow存儲在一個字段中,並檢查是否可以解決您的問題。

+0

我剛剛嘗試了這一點,它似乎上班!我需要再測試幾臺機器,但看起來你已經解決了它(並且簡單地解決它!)非常感謝你!我會將此標記爲答案並儘快獎勵您的賞金。 – 2010-09-10 07:32:33

+0

我無法得到這個工作 - IApplicationWrapper類在哪裏?它似乎並不在Silverlight 4中,Google只能返回很少的信息? – Rodney 2011-03-28 01:34:37

+0

框架中沒有IApplicationWrapper接口。它只是我寫的一個接口,用於啓用依賴注入和單元測試,以取決於應用程序打包程序。但是,如果你不關心,你可以複製應用程序包裝,並從我的初始化mainwindow我猜。 – 2011-03-29 05:29:22

3

相反的鉤掛的情況下,爲什麼不註冊一個服務,而不是?創建一個實現IApplicationService和IApplicationLifetimeAware的類。後者給你一個「onexiting」和「onexited」事件。您可以通過在App.xaml中調用的部分中指定服務來將該服務放入應用程序中。我已經將它用於很多項目,並且從未遇到過未被調用的退出方法的問題。

+0

感謝您的回答,但我需要能夠取消退出事件(在提示用戶後)。該界面似乎沒有提供一個選項。 – 2010-08-31 12:11:28

+0

+1,不是因爲它是對手頭問題的回答,而是因爲它只是一個整潔的事情。此外,它很容易忘記App壽命對象,所以它很好被提醒,你不必在App Start和Exit中做所有事情。 – AnthonyWJones 2010-08-31 20:08:14

+0

+1,一直在尋找一個整潔的解決方案,那個問題。乾杯。 – 2010-09-10 07:31:11

1

好吧,拉出我的頭髮,很多出師不利I finally found the answer之後 - 這似乎是一個已知的錯誤與Closing事件,OOB和ChildWindows打開/關閉......

關鍵是要存儲的靜態引用到主窗口:

public MainPage() 
{ 
    InitializeComponent(); 
    Loaded += MainPage_Loaded; 
} 

private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e) 
{ 
    //you have to store this to work around the bug 
    //http://forums.silverlight.net/forums/p/185664/424174.aspx 
    _mainWindow = App.GetApp.MainWindow; 

    App.GetApp.MainWindow.Closing += (s, e1) => 
    { 
     if (UIUtilities.ShowMessage("Would you like to exit AMT Mobile?", "Exit Application", MessageBoxButton.OKCancel) != MessageBoxResult.OK) 
     { 
      e1.Cancel = true; 
     } 
    }; 
} 
+0

謝謝。這正是我所需要的。 – xanadont 2011-08-05 05:13:24

+0

謝謝@Rodney,但我沒有看到你在哪裏使用_mainWindow?不幸的是,silverlight.net的鏈接不再工作。 – float 2016-03-17 07:37:20

+0

也App.GetApp.MainWindow; GetApp未知? – float 2016-03-17 08:31:05

相關問題