2016-08-19 12 views
0

私は2日間だけプリズムを使っていますので、以下のナビゲーション問題を説明しようとすると間違った前提がないと判断してください。Prism RequestNavigate behavior

1つのリージョンと2つの異なるビューがあるとします。ビューAは、起動時からカスタムRegionBehaviorによってそのリージョンにロードされます。私が使用するのは、その動作のRegionManagerでRequestNavigateだけです。私は最初のビューを設定するためのより良い解決策を見つけられませんでしたが、ここでの要点ではありません。

ここでは、各ビューに別のビューに移動するボタンがあります。コマンドは各ViewModelで実行され、RequestNavigateを再度呼び出します。 コンテナ(Autofac)でのナビゲーションのためにビューを登録するために定数を使用し、RequestNavigateを呼び出すために同じ定数を使用します。 すべてが一目ぼれでうまくいきます。しかし、私はビューを切り替えるたびに、新しいビューとビューモデルが作成されることに気付きました。さらに悪いことに、RegionManagerは以前のものすべてへの参照を保持しています。これはメモリリークのようです。今シングルトンとして自分のビューを登録することに切り替えることができますが、私はまだRegionManagerがそのように動作する理由を理解していませんでした。なぜ彼は私がナビゲーションを要求し、新しいナビゲーションを作成するのではなく、そのナビゲーションをアクティブにするという視点をすでに知っていることに気付かないのですか?何のために名前として定数を使用していますか?

私はこの投稿を見つけましたPRISM WPF - Navigation creates new view every timeこれは実際にはこの問題を解決します。ビューの登録にタイプの名前を使用すると、すべてが期待通りに機能します。ビューとビューモデルは、最初の使用時に作成され、再度ナビゲーションを要求されたときに再利用されます。

IRegionMemberLifetimeを実装し、KeepAliveでfalseを返すことができます。これは、これが私の欲しいものではない場合や、毎回新しいビュー/ビューモデルを作成することをお勧めします。そして、少なくとも元のものはRegionManagerから消去されます。 もし私がそれらを消去したくないのに、この古いメモリを消費したいなら、私はまだINavigationAwareを実装し、IsNavigationTargetでfalseを返すことができます。このようにして、RegionManagerは毎回新しいインスタンスを作成し、古いインスタンスへの参照を保持します。 もう1つは、登録名がタイプ名と等しくないときに私が新しいインスタンスを作成するのを止めることができません。その場合、IsNavigationTargetに到達していないため、RegionManagerは既存のビューをまったく参照しません。では、なぜ私はナビゲーションのために私の見解を登録した名前に応じて、ここで2つの異なる行動を取るのですか? 上記の追加のプロパティを使用して他のすべてのシナリオを作成できるため、両方の名前が同じ場合に適用される動作が唯一のものであると考えると間違っていますか?

スティーブ

答えて

1

あなたは、容器内のいくつかの名前を持つビュー(モデル)を登録します。次に、登録名を与えられたビュー(モデル)のインスタンスを作成することができます。これにより、RequestNavigateはビュー(モデル)を作成し、登録名を指定してそれをアクティブにすることができます。

ただし、RequestNavigateがターゲットビューの可能な既存インスタンスのインスタンスを検索している場合(IsNavigationTargetを要求している可能性もあります)、リージョン内のビュー(モデル)のインスタンスを処理する必要があります。彼らの登録名は利用できません - コンテナだけがそれらを知っています。したがって、RequestNavigateは、登録名がView型のNameまたはFullNameのいずれかであることを前提としています。

したがって、すべての機能を使用する場合は、ビュー(モデル)を型名で登録する必要があります。それを行う便利な方法があります - RegisterTypeForNavigation。