47

C# で UWP (Universal Windows App) アプリケーションを作成しようとしています。私の問題はFrameコントロールです: なしNavigationCacheMode = Requiredで使用すると、ユーザーが戻るたびにページがメモリに保持されず、再作成されます。またはに設定NavigationCacheModeすると、戻ることは正しく機能します (新しいページ オブジェクトはありません)、同じタイプから別のページに移動すると、前のページ オブジェクトがリサイクルされて再利用されます (新しいページ インスタンスはありません)。RequiredEnabled

望ましい動作:

元のコントロールで次の動作を行う方法はありますかFrame(Windows Phone のように):

  1. に新しいページ インスタンスを作成するNavigate()
  2. ページ インスタンスを維持するGoBack()

私が知っている唯一の解決策は、独自のFrameコントロールを作成することですが、これは他の問題につながります (例:SetNavigationState()メソッドの欠落など...)

サンプル シナリオ:

TvShowListPageTvShowDetailsPage、 の3 つのページを使用した簡単なアプリケーションの例SeasonDetailsPage

  1. TvShowListPageエントリーページです。をクリックした後、 にTvShow移動しTvShowDetailsPageます。
  2. TvShowDetailsPageリストでシーズンを選択し、 に移動しますTvShowDetailsPage
  3. 戻る場合は、ページのリロードを避けるためにページをメモリに残す必要があります。
  4. しかし、ユーザーが戻って別のものTvShowListPageを選択すると、リサイクルされ、おそらく間違った状態になります (たとえば、最初のシーズン ピボットの代わりにキャスト ピボットを表示する)。TvShowTvShowDetailsPage

Windows Phone 7 のデフォルトの動作を探しています。移動するとページ スタックに新しいページが作成され、戻るとスタックから一番上のページが削除され、スタック (メモリに保存されている) から前のページが表示されます。

解決:

この問題の解決策がなかったため、Page、Frame、SuspensionManager など、ページングに関連するすべてのクラスを再実装する必要がありました。

これらすべてのクラスを提供するライブラリ MyToolkitは、 https ://github.com/MyToolkit/MyToolkit/wiki/Paging-Overview からダウンロードできます。

参考文献:

4

7 に答える 7

17

この問題の解決策がなかったため、Page、Frame、SuspensionManager など、ページングに関連するすべてのクラスを再実装する必要がありました。

このソリューションは、 https ://github.com/MyToolkit/MyToolkit/wiki/Paging-Overview からダウンロードできます 。

アップデート:

ページ クラスは、たとえば非同期ポップアップを表示し、必要に応じてナビゲーションをキャンセルするOnNavigatingFromAsyncメソッドも提供するようになりました...

于 2012-10-04T15:46:59.997 に答える
8

私もほとんど同じ問題を抱えていました。Metro(Windows Storeが適切)で前進しているときに、新しいインスタンスが作成されるようにしたかったのです。ただし、戻ると、保存したいデータが保持されます。

したがって、同様にNavigationCacheMode=NavigationCacheMode.Enabledを使用しました。前方または後方のどちらの方向に移動しても、すべてが常に保存されていることがわかりました。それで、私はいくつかのページを進めて、それから数ページ後退します。前進するにつれてすべてがリセットされることを期待して、私は常にそうではないことに気づきました。データを保持していました。

NavigationCacheMode = NavigationCacheMode.Disabledを含めるように独自の戻るボタンコードを作成するなど、すべてを試しましたが、役に立ちませんでした。他の人が指摘しているように、一度有効にすると、NavigationCacheModeは無効になりません。

私は解決策を見つけました。LayoutAwarePage.csにアクセスして、小さな変更を加えました。「OnNavigatedTo」の下に次の行が見つかりました。

// Returning to a cached page through navigation shouldn't trigger state loading
if (this._pageKey != null) return;

しかし、コメントは私が望んでいたものとは逆になりました。一方向のパターンで状態の読み込みを探していました。前進する場合は、状態の読み込みが必要でした。後方に移動する場合は、コメントが示す動作が必要でした。状態の読み込みはありません。

だから私は単に行を変更しました。

// Returning to a cached page through navigation shouldn't trigger state loading
if (this._pageKey != null && e.NavigationMode == NavigationMode.Back) return;

私はそれをテストしました、そしてそれは完全に働きます。これで、逆方向に移動すると、状態が記憶され、ページが同じに保たれます。前方に移動すると、フレッシュにロードされます。

おそらくベストプラクティスではありませんが、コードビハインドから「OnNavigatedTo」を呼び出しません。私は「LoadState」を介してすべてを行います。コードビハインドで「OnNavigatedTo」をオーバーライドすると、異なる動作が表示される場合があります。

ありがとうございました、

ジョセフ・アーバイン

于 2012-08-30T16:54:40.303 に答える
6

前方に移動しているとき、 Frame.Navigateを呼び出す前にNavigationCacheModeDisabledに設定できますか? 次に、OnNavigatedTo()で、 NavigationCacheModeを再度Enabledに設定します。

これにより、前方に移動するとキャッシュが無効になるはずです。しかし、新しいページ インスタンスに到達すると、OnNavigatedToはそれを再び有効にします。戻りたい場合は、Frame.GoBackを呼び出す前にNavigationCacheModeに触れないでください。これにより、キャッシュされたインスタンスが得られるはずです。

私はこれがうまくいくと信じていますが、私はそれをテストしていません。そうであるかどうか知りたいです。興味深いシナリオがあります。アプリが実際に動作しているのを見て、この動作の使用法をよりよく理解したいと思っています。

于 2012-07-18T21:04:13.243 に答える
2

NavigationCacheMode プロパティを使用して、ページへの訪問ごとにページの新しいインスタンスを作成するか、またはキャッシュに保存されているページの以前に構築されたインスタンスを訪問ごとに使用するかを指定します。

NavigationCacheMode プロパティのデフォルト値は Disabled です。訪問ごとにページの新しいインスタンスが必須ではない場合は、NavigationCacheMode プロパティを Enabled または Required に設定します。ページのキャッシュされたインスタンスを使用することで、アプリケーションのパフォーマンスを向上させ、サーバーの負荷を軽減できます。

NavigationCacheMode を Required に設定すると、CacheSize プロパティで指定されたキャッシュされたページの数に関係なく、ページがキャッシュされます。Required とマークされたページは、CacheSize の合計にはカウントされません。NavigationCacheMode を Enabled に設定すると、ページはキャッシュされますが、キャッシュされたページの数が CacheSize の値を超えた場合に廃棄の対象となります。

訪問ごとに新しいインスタンスを作成する必要がある場合は、NavigationCacheMode プロパティを Disabled に設定します。たとえば、各顧客に固有の情報を表示するページをキャッシュしないでください。

ページがキャッシュから取得された場合でも、OnNavigatedTo メソッドは要求ごとに呼び出されます。Page コンストラクターにコードを配置するのではなく、要求ごとに実行する必要があるコードをこのメソッドに含める必要があります。

于 2012-07-18T11:13:29.530 に答える
0

page2クラスからクラスを派生させるpage必要があり、同じページの 2 番目のバージョンに移動するときに、thisオブジェクトがpageまたはであるかどうかを検出しますpage2。次に、page2if I was inpageに移動し、pageif inに移動しpage2ます。

唯一の大きな欠点は、ある XAML ファイルを別の XAML ファイルから派生させる方法がないことです。したがって、すべての C# コードはpage予想どおりコード ビハインド クラスにありますが、ページの各バージョンに 1 つずつ、ほぼ同一の 2 つの XAML ファイルがあります。

XAML データをコピーしてクラス名を調整し、最初のページ クラスから 2 番目のページ クラスを生成するビルド前の手順として、おそらく小さなスクリプトを追加できます。

見苦しいですが、ほぼ完璧に動作し、C# コードの重複や奇妙なナビゲーション キャッシュの問題について心配する必要はありません。私はXMALコードを重複させてしまいますが、私の場合は決して変更されません。また、とnewの自動生成コードでキーワードを使用しないことに関する 2 つの警告が表示されます。page2.InitializeComponent()page2.Connect()

興味深いことに、pagethen to page2then to に移動しpageても問題は発生せず、pageクラスの 2 番目のインスタンスは、最初のインスタンスとは無関係の実際の 2 番目のインスタンスです。

このソリューションは、おそらく MS によって推奨されていないことに注意してください。

于 2015-10-19T23:24:50.943 に答える