私はPrism 5.0を使用していますが、既存のビューを再利用するように設定するのに問題があります。 IRegionManager.RequestNavigate(string regionName, Uri source)
が呼び出されると、以前に作成されたビューを使用する代わりに、新しいビューが作成されます。不思議なことに、CLRProfilerはまた、Prismの地域マネージャーが、以前に作成されたすべてのビューインスタンスへの参照を保持し、メモリリークを引き起こすことを示しています。Prismがナビゲーションで新しいビューを作成しないようにします
私のビューモデルはINavigationAware
を実装し、true
をIsNavigationTarget()
に返しますが、このメソッドは呼び出されません。私は同じ結果で同様にビューに実装しようとしました。
テストでは、ビューにIActiveAware
を実装しました。これは、別のビューに移動するとすぐに非アクティブ化されることを示しています(これは適切ではありません)。
私はこの質問を見つけました:PRISM WPF - Navigation creates new view every timeしかし、私のV-VM命名規則は答えのものと一致します(私はAutoFacを使っています)。
私は回避策を見つけました。ビューモデルのINavigationAware.OnNavigatedFrom()
実装でNavigationContext.NavigationService.Region.Remove()
を使用して、地域からアクティブビューを削除しました。これを行うと、Prismの地域マネージャーがビューへの参照を解放します。これはうまくいきますが、必要なときに常にビューを再作成するのは非効率的です。
ほとんどの関連する質問は、ナビゲーションイベントで新しいビューを作成する方法を尋ねるので、デフォルトの動作ではビューが再利用されると仮定します。私はここにポインタが必要です。私たちは、ビューを登録するAutoFacのAutofacExtensions.RegisterTypeForNavigation<T>(this ContainerBuilder builder, string name = null)
を使用
EDIT
。ビュー間のナビゲーションにはIRegionManager.RequestNavigate()
を使用します。 INavigationAware
はViewModelsに実装されています。ただし、INavigationAware.OnNavigatedTo()
とOnNavigatedFrom()
が呼び出されますが、IsNavigationTarget()
は呼び出されません(後者は、ビューがINavigationAware
を実装していても呼び出されません)。
ビューのctorにブレークポイントを設定することで、新しいビューが作成されたことを検出できます。また、CLRProfilerヒープ・ダンプは、リージョン・マネージャーに、ナビゲートされた回数だけのビューのインスタンスがあることも示しています。 ViewModelは、AutoFacで単一インスタンスとして登録されているため、一度だけ作成されます。
一時的な対策として、ビューをIRegionMemberLifetime
に実装しました。KeepAlive
はfalse
を返します。これはあまり効果的ではありません。ビューは必要になるたびに再作成されますが、リージョン・マネージャーは以前のビューを保持できません。
IRegionMemberLifetimeプロパティとKeepAliveプロパティを使用する必要があります。 –
@AyyappanSubramanianビューがIRegionMemberLifetimeを実装し、KeepAliveがtrueを返す場合、リージョンマネージャはビューへの参照を保持しますが、ナビゲートするときに新しいビューを作成します(ビューにIRMLが実装されていない場合はデフォルトでなければなりません)。 KeepAliveがfalseを返す場合、ビューは破棄されるため、再作成する必要があります。私の質問は、プリズムを元のビューに再利用させる方法だったので、これは解決策ではありません。 – Drew
私は現在、すべての私の見解ではないが、同じ問題を抱えています。それは私の問題を引き起こしている特定のページの下にあるようです。 – user3265613