2012-03-16 89 views
3

我正在尋找一種在Silverlight 5中實現真正的模式對話框的好方法。我發現所有聲稱創建模態對話框的示例都不是模態的,因爲調用代碼會一直等到對話框關閉。在Silverlight 5中實現一個真正的模式對話框

我意識到這是一個挑戰,因爲我們不能實際阻止UI線程,因爲它必須運行才能使對話框(ChildWindow)正常工作。但是,隨着SL5中TPL的加入以及Silverlight在過去幾年中所採用的更高級別的應用,我希望有人找到解決方法。

我試圖解決的一個很好的代表性場景是一個動作(比如說單擊一個按鈕或菜單項),它顯示一個登錄對話框,並且必須等待登錄才能完成,然後才能繼續。

我們特定的商業案例(無論是否合理)是應用程序不需要用戶身份驗證;但是,某些功能需要「經理」訪問權限。當功能被訪問時(通過按鈕點擊或選擇菜單項等),當前用戶不是經理,我們顯示登錄對話框。當對話框關閉時,我們再次檢查用戶的授權。如果他們沒有被授權,我們會顯示一條好消息並拒絕該操作。如果他們獲得授權,我們將繼續執行通常涉及將當前視圖更改爲新的用戶可以執行任何要求的操作。

+0

典型的解決方法是將函數作爲參數的靜態(例如對話框)方法調用。您可以定義在成功與失敗時使用兩個內聯匿名函數時發生的情況。 *其餘代碼是事件驅動的,所以你應該嘗試使用異步模型,而不是反對它。* :) – 2012-03-16 15:15:23

+0

在我的情況,我們'重新實現'模式通過有一個子視圖不是一個ChildWindow沿具有半透明的視圖,防止輸入到達阻擋的元素。 「模態」系統的可見性是數據綁定的。 – jv42 2012-03-17 18:04:39

回答

5

對於關閉的緣故...

我最終得到的是一個新的啓用TPL-DialogService用類似的方法:

public Task<Boolean?> ShowDialog<T>() 
    where T : IModalWindow 

的方法創建對話框的一個實例(ChildWindow) ,將一個處理程序附加到Closed事件並調用Show方法。在內部,它使用一個TaskCompletionSource <布爾? >將任務返回給調用者。在Closed事件處理程序中,DialogResult被傳遞給TaskCompletionSource的TrySetResult()方法。

這讓我在一個典型的異步方式顯示該對話框:

DialogService.ShowDialog<LoginDialog>().ContinueWith(task => 
{ 
    var result = task.Result; 

    if ((result == true) && UserHasPermission()) 
    { 
     // Continue with operation 
    } 
    else 
    { 
     // Display unauthorized message 
    } 
}, TaskScheduler.FromCurrentSynchronizationContext()); 

或者,我可以阻止使用Task.Wait()方法 - 雖然這是有問題的,因爲正如我在原來的文章中提到它會阻塞UI線程,所以即使對話框也被凍結。

仍然不是真正的模式對話框,但更接近我正在尋找的行爲。任何改進或建議仍然讚賞。

+0

非常感謝! – lamarmora 2012-08-24 15:10:57

相關問題