web-dev-qa-db-ja.com

ページからページへのデータの受け渡し

ページ間でデータを渡す方法のベストプラクティスを探しています。

ページAには、ページBから起動するボタンがあります。
ページBには、ユーザーが情報を入力できる6つのテキストボックスがあります。ユーザーが完了したら、ボタンをクリックしてページAに戻ります。

そのデータをページAに戻したい.

私は次の提案を見てきました:

  • xMLドキュメントを作成して分離ストレージに保存する
  • appクラスを使用してプロパティに情報を保存します
  • クエリ文字列のように渡します

ベストプラクティスを探しています。マイクロソフトが推奨するものや、一般的に最良の方法として受け入れられているものはありますか?

ありがとう

44
webdad3
PhoneApplicationService.Current.State["yourparam"] = param
NavigationService.Navigate(new Uri("/view/Page.xaml", UriKind.Relative));

その後、単に他のページで

var k = PhoneApplicationService.Current.State["yourparam"];
63
LXG

個人的には、ページBに入力された値を、ページAにもアクセス可能なモデル(オブジェクト)に保存します。

2回目のページAへの移動方法によっては、次の1つ以上がページ間の値の受け渡しを理解するのに役立つ場合があります。

Windows Phone 7で1つのxamlページの画像値を別のxamlページに渡す方法

WP7 Silverlightアプリケーションでのナビゲーション中に複雑なオブジェクトをページに渡す

xamlページから別のページにオブジェクトを渡す方法

WP7のSilverlightページ間で値を渡す方法?

xamlページから別のページに移動し、値を渡す方法は?

23
Matt Lacey

考えられることの1つは、MVCを使用することです。アプリをコントローラーにして、モデルにすべてのデータを保存し、ページは純粋なUIロジックを含む単なるビューです。この場合、ページはペインタであり、モデルオブジェクトを渡します。これにより、ビジネスロジックとUIを適切に分離できるため、簡単に変更できます。

BTW、Silverlight、およびXAMLはMVCの優れたツールであるため、自然に一致します。

4
Peon the Great

ここにはいくつかのことがあります。まず、ユーザーがボタンではなく[戻る]ボタンを使用してページAに戻る場合、またはテキストボックス内の情報が交換されているかどうか(戻る=キャンセル、または戻る= OKですか?)

つまり、NavigationService.GoBack(NavigationService.Navigateの代わりに使用する必要があります。Navigate呼び出しを使用する場合、バックキーを繰り返し押すと、ユーザーにあらゆる種類の不適切なUXが発生するため)オプションではありません。 WP7 Silverlight navシステムでは、ページが実際に相互に参照する方法がないため、サードパーティを使用してデータを保持する必要があります。そのためには、(a)分離ストレージ(低速で重いがフェールセーフ)、(b)PhoneApplicationService.Stateディクショナリを使用、または(c)何らかの種類のグローバルプロパティを使用して、アプリケーションからハングアップすることができます。オブジェクト、またはStatics/Singletonsを使用...

これを行うときは、トゥームストーンの動作を忘れないでください。ページは、(a)アプリケーションでナビゲートするとき、(b)ページBでの作業を完了するときに戻るとき、または(c)時にOnNavigatedToメソッドを処理しますそのページからアプリを廃棄し、Backキーを使用してアプリケーションに戻ります。

申し訳ありませんが、より直接的な回答はありませんでした-多くは特定の状況によって異なります。最も一般的なケースでは、PhoneApplicationServiceでApp State Dictionaryを使用することを強くお勧めします。これは軽量で使いやすく、廃棄を生き延びます。キーが必要なだけ一意であることを確認してください。

3
avidgator

新しいWindows Phoneプロジェクトを作成し、Windows Phoneデータバインドテンプレートを使用すると、ほとんどの作業が完了します。

行うことは、ViewModelを設定して、アプリのすべてのデータを含めることです。 IsolatedStorageを使用してこのデータをシリアル化および逆シリアル化すると、アプリケーションセッション全体およびトゥームストーン時に保存されます。

テンプレートでは、MailViewModelおよびItemViewModelに注目します。 MainViewModelは、ItemViewModelのObservableCollectionなど、アプリケーションに必要なすべてのデータを格納し、ItemViewModelはアプリケーションの個々のデータ型を表します。

DetailsPage.xamlページで、各テキストボックスをApp.MainViewModelアイテムにデータバインドします。ユーザーがDetailsPage.xamlのデータを操作するとすぐにViewModelが更新されるようにするには、バインディングをTwoWayに設定します。オプションで、バインディングをOneWayに設定し、変更をViewModelに書き戻し、IsolatedStorageに保存する[OK]ボタンを使用できます。

バインディングがどのように見えるかの例を次に示します。

<TextBlock x:Name="ListTitle" Text="{Binding LineOne}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

この場合、LineOneはItemViewModelのプロパティであり、ユーザーがMainPage.xamlからアイテムを選択すると、ページはクエリ文字列からこのデータを取得します。ページのDataContextは、データバインドされた情報がどこから来るかを決定します。

MainPageがViewModelからDetailsPageに選択されたアイテムを渡すスニペットを次に示します。

// Handle selection changed on ListBox
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // If selected index is -1 (no selection) do nothing
    if (MainListBox.SelectedIndex == -1)
        return;

    // Navigate to the new page
    NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative));

    // Reset selected index to -1 (no selection)
    MainListBox.SelectedIndex = -1;
}

DetailsPageが選択されたアイテムを取得する方法は次のとおりです。

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    string selectedIndex = "";
    if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
    {
        int index = int.Parse(selectedIndex);
        DataContext = App.ViewModel.Items[index];
    }
}

上記のデフォルトのテンプレートで遊んで、追加の質問をしてください。

データバインディングとObservableCollectionの利点は、データを更新するだけで、UXがそれらの変更をすぐに反映することです。これは、データに変更を加えるとイベントが発生するためです。

public string LineOne
{
    get
    {
        return _lineOne;
    }
    set
    {
        if (value != _lineOne)
        {
            _lineOne = value;
            NotifyPropertyChanged("LineOne");
        }
    }
}

この情報をビューにブロードキャストするNotifyPropertyChanged()。

2
Omar Shahine

私はこのように実装しました。その正しいかどうかはわからない..

ニュースリストページをクリックすると、ニュース詳細ページが開きます。ニュースリストページからニュース詳細ページに、選択したニュースアイテムのコンテンツを渡します。

ニュースリストページには次のメソッドが含まれています。

 protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
        NewsDetailsPage newsDetailPage = (e.Content as NewsDetailsPage);
        if (newsDetailPage != null)
            newsDetailPage.SelectedNewsItem = SelectedNewsItem; //Contains the news details
        base.OnNavigatedFrom(e);
    }

ニュースの詳細ページ。 Uは、その(SelectedNewsItem)オブジェクトにアクセスできます。

これは正しい場合とそうでない場合があります。

1
Mahantesh

1つのオプションは、Application.Resourcesを使用することです。

データの保存:

Application.Current.Resources.Add("NavigationParam", customers);

NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));

データの取得:

var customers = (List<Customer>) Application.Current.Resources["NavigationParam"];

これについて詳しく説明したブログ投稿があります: http://mikaelkoskinen.net/windows-phone-pass-data-between-pages-application-resources/ (author:me)

1
Mikael Koskinen

シンプルに保ち、基本的にハッシュテーブルであるPhoneApplicationService.Current.Stateを使用することもできます。アプリの寿命を延ばすには、隔離されたストレージとの間で独自のマーシャリングを実装する必要があります。

このページでは、おそらくWindows Phoneデータバインドテンプレートを使用することをお勧めします。これは私の提案と同じですが、学習曲線が長くなるという犠牲を払って、より良い結果(より保守しやすいコード)が得られます。

私のやり方でやり直してから、オマールのやり方でやり直してください。

1
Peter Wone