0

最初のコンポーネントが初期化される前に、前提条件をチェックする多数の小さなコンポーネントを含むコンポーネントがあるとします。それらは互いに依存していないので、順序は気にせず、同時に実行したいと考えています。プレゼンテーションには 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 が見つかりませんでした - これはエラーにつながる可能性があります。続行しますか?」) - これは可能であるはずです。

しかし、一度に表示できるウィンドウは 1 つだけにしたいと思います。同期するだけでなく、どうすればそれを達成できますか?

編集 - 質問があいまいすぎるように見えたので

これらのアクションを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;}a) ビューモデルがそれを要求し、b) 他の前提条件ウィンドウが開いていない場合にのみビューを作成する方法を探しています。

注: この動作を実装する方法がまだわからないため、ここのコードは説明用です。私はこれらのフレームワーク (および概念) の経験がないので、この質問がばかげていると思われる場合は、ご容赦ください。

4

2 に答える 2

2

ここで概念を混合しています。

Caliburn.Micro のアクティブ ビュー管理は、Conductor クラスによって処理されます。Conductor から派生した ViewModel は、多数の Screen から派生した ViewModel (または他の Conductor) を表示できます。利用可能なアイテムは Items プロパティに格納されます。

「スクリーン、コンダクター、コンポジション」でより良い説明を見つけることができます

MEF は、アイテムのリストをコンダクターに渡すために使用できますが、コンダクターおよび構成メカニズムとは関係ありません。[ImportMany] コンストラクター パラメーターまたはパブリック プロパティを定義して、初期化中に表示する画面を受け取り、それらをコンダクターの Items プロパティに格納できます。

プロパティのセッターから Items プロパティに項目をコピーする必要がないため、コンストラクター パラメーターを使用する方がより洗練されています。

最後に、ビューとビューモデルを作成するときにメッセージを表示しないでください。これは後のステップのために残しておくべきものです。Activate メソッド中。コンダクターと MEF はパーツを組み合わせて UI を構築します。アクションの実行とユーザーとの会話は、構成ステップが終了した後にのみ行う必要があります。

于 2013-07-25T13:58:03.973 に答える
0

私はこの質問に自分で答え、どのようにしてこれを解決したかを詳しく説明します。

を作ってLoaderViewModel : Conductor<PropertyChangedBase>.Collection.OneActive, IChild<Shell>を与えましたQueue<PropertyChangedBase>

Window-Level に到達するまで、Parent-Properties をトラバースする Show/HideWindow メソッドがあります。

QueueおよびメソッドがありDequeueます。が-Property で起動Queueされたときに使用され、プロパティがないか、ビジーとしてマークされていない場合に呼び出します。キューに新しいアイテムがある場合は新しいアイテムをアクティブにしてから を呼び出し、アイテムがない場合は代わりに呼び出します。PropertyChangedRequestsViewDequeueActiveItemActiveItemDequeueShowWindowHideWindow

ウィンドウが非表示の場合、CM は奇妙な動作をするように見えるため、イニシャルHideWindowViewAttached-Event で行われます。ここで、前提条件の並列チェックが開始され、最初の投稿と同様のイベント ハンドラーが登録されます。

冗長で申し訳ありませんが、コードが少し長くなりました。誰かが私に投稿してほしい場合は、コメントを書いてください。

于 2013-07-29T12:16:46.967 に答える