5

MvvmCrossを使い始めたばかりですが、ViewModelからUIコードを実行する方法についての情報が見つかりませんでした。

Caliburnにはコルーチンがあるので、ビューにアクセスして、UIコードをビューモデルコードから分離しておくことができます。私の最初のケースでは、ViewModel内のコマンドからダイアローを開く必要がありますが、正しい方法は何ですか?

現在、WinRTアプリを開発しています。

ありがとう

4

2 に答える 2

15

MvvmCross 内では、これに関するハード/ファスト ルールはありません。

通常、これを行う必要がある場合は、Messenger プラグインを使用します。

この回答は、最新の Alphav3コードを使用していることを前提としています。古い vNext コードについては、翻訳を行う必要があります。以下の注を参照してください。

このアプローチを使用するには:

Cirrious.MvvmCross.Plugins.Messenger.dllCore プロジェクトと UI プロジェクトの両方から参照しています。

次に、Setup.cs のどこかに (たとえばInitializeLastChance) 行を追加して、次のようにします。

Cirrious.MvvmCross.Plugins.Messenger.PluginLoader.Instance.EnsureLoaded();

次に、Core プロジェクトにメッセージを追加します。

public class InputIsNeededMessage : MvxMessage
{
    public InputIsNeededMessage(object sender) : base(sender) {}
}

ViewModel では、コンストラクター インジェクションまたは次の方法で Messenger を取得できます。

var messenger = Mvx.Resolve<IMvxMessenger>();

次のように呼び出してメッセージを送信できます。

messenger.Publish(new InputIsNeededMessage(this));

ビューでは、メッセンジャーに再びアクセスし、次を使用してメッセージを購読できます。

var messenger = Mvx.Resolve<IMvxMessenger>();
_token = messenger.SubscribeOnMainThread<InputIsNeededMessage>(OnInputIsNeeded);

whereはメンバー変数である_token 必要があります - そうでない場合、サブスクリプションは持続しません - サブスクリプション自体はデフォルトで弱いです (したがって、サブスクリプションを解除する必要はありません)

そしてどこOnInputIsNeededに次のようなものがあります:

private void OnInputIsNeeded(InputIsNeededMessage message)
{
    if (message.Sender != ViewModel)
        return;

    // do stuff here - you are already on the UI thread
}

上記のシーケンスは、「適切なコード」に対して通常行うことです

Messenger/EventAggregator の使用を開始すると、最初は不快に感じることがあります。これに慣れるまでには確かに時間がかかりましたが、慣れた後は、どこでも使用できるようになりました。テストおよびコードの将来のメンテナンス用 (IMO)

上記のこのアプローチの代替として、私は時々ショートカットを取ります:

  • 時々、ViewModel から通常の C# イベントを起動し、View にこれらに応答させます。
  • 特別なマーカー プロパティがあり、そこから UI コードを起動することがあります。

構文を使用して申し訳ありませんv3-しかし、切り替えが近づいており、それは私が現在コーディングしているものです...

元に戻すには、次のvNextことが必要になると思います。

  • IMessengerの代わりに使用IMvxMessenger
  • BaseMessageの代わりに使用MvxMessage
  • Subscribe-の代わりに使用SubscribeOnMainThreadしますが、メッセージを自分で UI スレッドにマーシャリングする必要があります。
于 2013-03-23T21:44:35.653 に答える