4

フレームワークを使用してクロスプラットフォームのモバイル アプリケーションを構築してMvvmCrossいます。

ViewModel 間で情報を共有したいので、ビルトインを使用して、ViewModel のコンストラクター内に通知を登録していMvxMessengerます。
という名前のメッセージを想定するとShowAdsMsg、ViewModel は次のようになります。

public class AdsViewModel : BaseLookersViewModel, IAdsViewModel
{
    private MvxSubscriptionToken _showAdsMsgToken;

    public AdsViewModel()
    {
        _showAdsMsgToken = MvxMessenger.Subscribe<ShowAdsMsg>(message => onShowAdsNavigation(), MvxReference.Weak);
        MyMessenger.PublishLastMessage();
    }
    private void onShowAdsNavigation()
    {
        //Do Stuff
    }
}

事についてMyMessenger:
ViewModel への実際のナビゲーションは から実行されMainViewModelます。
ナビゲーション自体の瞬間にはAdsViewModelはまだ存在しないため、 から発行されたメッセージMainViewModelは到達できません。
したがって、私の考えは、単純にメッセージを「記憶」し、新しい ViewModel の準備ができたときに公開することでした。
からのナビゲーション呼び出しはMainViewModel次のようになります。

    private void navigate()
    {
        MyMessenger.RememberMessage(new ShowAdsMsg(this));
        ShowViewModel<AdsViewModel>( );
    }

ViewModel に移動できるようになり、すべての通知が正常にキャッチされました。

ただし...
デバイスの[戻る]ボタンを押して同じViewModelに再度移動すると、
コンストラクターが再度呼び出されるため、メッセージサブスクリプションが再度発生します。
その結果、メッセージが到着すると、onShowAdsNavigation()ハンドラーが 2 回起動されます。

ViewModel を適切に破棄する方法についての質問を議論しているこの類似の投稿を見つけまし
たが、私の問題に対する直接的な解決策は含まれていません。

私が必要としているのは解決策です。次のいずれかになります。

  1. ViewModel の ctor でメッセージをサブスクライブしない方法を考えます。
  2. ViewModel を正しく破棄する方法と時期に関するガイダンス。
  3. コンストラクターが再度呼び出される理由と、それを回避する方法についての説明。
  4. ViewModel 情報メッセージングに対するまったく異なるアプローチ。

助けてくれてありがとう!

編集:私はこのSO Answerを見つけました。これは基本的に上記のリストの項目番号3に答えます。それでも、メッセンジャーの問題に関してどのようなアプローチをとるべきか疑問に思っています。

別の編集: MvvmCross チュートリアルN-05-MultiPageで同じ動作が存在することを確認しました。SecondViewModel に ctor を追加しただけで、BACK+Renavigate を実行するたびにその内部でブレークポイントにヒットしました。

4

1 に答える 1