2013-07-25 71 views
0

可以說我有一個組件,其中有許多較小的組件,它們會在第一個組件被初始化之前檢查先決條件。他們不相互依賴,所以我不關心訂單,並希望他們同時運行。我正在使用MEF和Caliburn.Micro進行演示。使用MEF和Caliburn Micro管理先決條件

我想過這個設置:

class Big 
{ 
    [ImportMany] 
    public IEnumerable<IBigPrerequisite> Prerequisites {get; set;} 
    public void Initialize(){...} 
} 

interface IBigPrerequisite 
{ 
    public bool IsBusy {...} 
    public bool Allow {...} 
    public void StartChecking(); 
} 

現在我想用這個來完成是實現IBigPrerequisite類可以打開一個窗口(例如「文件X未找到 - 這可能會導致錯誤。繼續?「) - 這應該是可能的。

但我只想讓一個窗口一次可見。除了同步之外,我將如何實現?

編輯 - 因爲這個問題似乎太含糊

我需要前Big將被激活,這些動作具體運行。比方說,我們啓動邏輯開關達到這樣的:

Big big; //we got this through Importing somewhere in composition 
var allow = true; 
var count = 0; 
if(!pre.Any()) //no prerequisites, show window immediately 
    windowManager.ShowWindow(big) 
foreach(var pre in big.Prerequisities) 
{ 
    pre.PropertyChanged += (s, args) => 
    { 
     if(args.PropertyName == "IsBusy" && !pre.IsBusy) // if a prerequisite finished it's check 
     { 
      allow = allow && pre.Allow; //if one prerequisite says nay we could just return, actually... 
      count++; 
      if(count == big.Prerequisites.Count() && allow) 
       windowManager.ShowWindow(big); 
     } 
    } 
    pre.StartChecking(); 
} 

現在,我明確要實現IBigPrerequisite類才能夠打開一個窗口,但如果所有的先決條件(無需用戶交互)沒有窗戶應該顯示。我不想爲這裏的每一堂課打開一扇窗戶。

我正在尋找一種方式,比如說,給IBigPrerequisite(這或許應該被稱爲IPrerequisiteViewModel反正)像bool RequestsWindow {get;}一個屬性,只有當)的視圖模型請求它和b)沒有其他先決條件窗口中創建視圖在當時是開放的。

注意:此處的代碼僅用於說明,因爲我不確定如何實現此行爲。我對這些框架(和概念)沒有經驗,所以如果這個問題看起來很愚蠢,請耐心等待。

+0

你有什麼嘗試過,沒有工作,你確切的問題是什麼:顯示對話框,同步執行或什麼? –

回答

0

我將自己回答這個問題,詳細說明我如何最終解決這個問題。

我作了一個LoaderViewModel : Conductor<PropertyChangedBase>.Collection.OneActive, IChild<Shell>並給它一個Queue<PropertyChangedBase>

它具有Show/HideWindow方法,通過遍歷父屬性直到它到達窗口級別。

它有QueueDequeue方法。 Queue用於PropertyChangedRequestsView-屬性上被觸發,如果沒有ActiveItemActiveItem未被標記爲繁忙,則調用DequeueDequeue將激活一個新的項目,如果隊列中有一個,然後致電ShowWindow,如果沒有項目,它將調用HideWindow代替。

最初的HideWindowViewAttached-事件中完成,因爲如果窗口被隱藏,CM似乎有一些奇怪的行爲。在這裏,開始先決條件的並行檢查,並註冊類似於第一篇文章中的事件處理程序。

對不起,我的代碼變得冗長了。如果有人希望我發表評論,請發表評論。

2

你在這裏混合的概念。

Caliburn.Micro中的活動視圖管理由Conductor類處理。導體派生的ViewModel可以顯示大量來自屏幕的ViewModel(或其他導體)。可用項目存儲在Items屬性中。

你可以找到一個更好的說明「Screens, Conductors and Composition

MEF無關與導體和組合機制,雖然它可以用於項目列表傳遞給導體。您可以定義一個[ImportMany]構造函數參數或公共屬性,該參數或公共屬性接收要在初始化期間顯示的屏幕並將它們存儲在售票員的Items屬性中。

使用構造函數參數更優雅,因爲您不必將項目從屬性的setter複製到Items屬性。

最後,創建視圖和視圖模型時不應顯示消息。這是應該留給後面的一步,例如。在Activate方法中。導體和MEF將這些部分組合在一起並構建UI。只有在合成步驟完成後,才能執行操作並與用戶交談。

+0

從閱讀那篇文章我認爲'Conductor .Collection.OneActive'是我正在尋找,但我不知道如何去使用它。 –

+0

我用你的提示與Conductor作爲出發點,但我自己找到了解決方案,所以我無法接受你的答案。 –