1

私が開発している Windows Phone アプリの 1 つに MVVM を実装しようとしていますが、そのアプリは大きくなっています。Model クラスで以下のコードを試しました。ユーザーが「最新のエントリ」ボタンをクリックすると、サービスに接続してメソッドを非同期的に実行するシナリオをどのように処理できるかを知りたいです。データが返されたら、私はしなければなりませんEmpName、EmpID、Address の 3 つのテキスト フィールドを持つ UI に最新のレコードを表示します。

モデル クラスのコード:

      public class EmpDetailsModel:INotifyPropertyChanged
        {

            private string _EmpName;
            public string EmpName
            {
                get { return _EmpName; }
                set {
                    if (value != _EmpName)
                    {

                        _EmpName = value;

                        RaisePropertyChanged("EmpName");
                    }
                }
            }

            private string _EmpId;
            public string EmpId
            {
                get { return _EmpId; }
                set {
                    if (value != _EmpId)
                    {
                        _EmpId = value;

                        RaisePropertyChanged("EmpId");
                    }
                }
            }

            private string _Address;

            public string Address
            {
                get { return _Address; }
                set {
                    if (value != _EmpId)
                    {

                        _EmpId = value;

                        RaisePropertyChanged("Address");
                    }
                }
            }

            #region myfirstmodel inotify members
            public event PropertyChangedEventHandler PropertyChanged;

            private void RaisePropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion

サービスに接続するコードは次のとおりです。

    EmpAzureSer empAzureSer = new EmpAzureSer();
    empAzueSer.GetLatestEntry += new GetLatestEntryCompletedEventHandler(LatestEntryCompleted);
    private void LatestEntryCompleted(object sender, GetLatestEntryCompletedEventArgs e
            {
              //get the data from e as e.Name,e.Id and e.Address and bind them to UI.
            }

xaml コードを表示:

                        <Button Name="FetachLAtest" Click="FetachLatest_Click"></Button>
                        <TextBlock Name="EmployeeName"></TextBlock>
                        <TextBlock Name="EmployeeID"></TextBlock>
                        <TextBlock Name="EmployeeAddress"></TextBlock>

リンクhttp://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521153(v=vs.105).aspxをたどっていました。

それは非常に役に立ちましたが、サービスに接続するコードをどこに置くべきか知りたいです(モデル?またはビューモデル?ビューモデルはどのように見えるべきですか?

4

1 に答える 1

6

MVVM をアプリケーションに実装するにはさまざまな方法があり、開発者やアプリケーションの要件によって異なります。

しかし、最初は物事をシンプルに保ち、ViewModel に焦点を当てるようにしましょう (これがあなたの興味の対象と思われるためです)。

MVVM は Model View ViewModel を意味し、Model はビジネス/ドメイン コード、View は基本的に XAML とそれに関連するコード ビハインド、ViewModel は View とモデルの間のリンク/接着剤です。注意すべき重要なことは、ViewModel が View を認識してはならない (つまり、それらを参照してはならない) ことです。これにより、懸念事項がより適切に分離されるため、テストと保守が容易なアプリケーションを構築しようとします。

簡単に言うと、ViewModel は View を認識していませんが、ViewModel と通信する必要があります...そして、この魔法は Binding のおかげで可能になります! XAML/UI コンポーネントはデータを表示します。これらのデータは、バインディング メカニズム (Silverlight フレームワークによって WP で提供される) を介してビューにバインドされた ViewModel から取得されます。つまり、ViewModel には View に必要なすべてのデータが含まれており、実際にはViewModel は View のすべてのデータまたは動作を表します

MVVM パターン全体とそのすべての機微を説明するのに最適な人物ではないので、このデリケートな作業はこの分野の最も知識のある人々に任せます ;)。ここにあなたを助けるはずのいくつかの本当に素晴らしいリンクがあります:

以上のことから、あなたは理論に少し退屈しているに違いないので、コードを書いてみましょう。問題は、コードを整理する方法がたくさんあることです。そのため、以下に示すのは一種の疑似コードにすぎず、アプリケーションで直接使用することはできません!

あなたの場合、このような ViewModel だけを作成できます

public class WhateverYouWantViewModel : INotifyPropertyChanged
{
    private EmpDetailsModel _model;
    public EmpDetailsModel Model
    {
        get { return _model; }
        set
        {
            if (value != _model)
            {
                _model = value;
                RaisePropertyChanged("Model");
            }
        }
    }

    public void GetLastestEntries()
    {
        // put in here the code calling your service
    }
}

データ サービスからthis.Modelへの割り当てについては、非同期コールバックを扱っているため、コールバックが UI Thread から呼び出されない場合はDispatcherを使用する方が賢明でしょう。

EmpAzureSer empAzureSer = new EmpAzureSer();
empAzueSer.GetLatestEntry += new GetLatestEntryCompletedEventHandler(LatestEntryCompleted);
private void LatestEntryCompleted(object sender, GetLatestEntryCompletedEventArgs e
{
   Deployment.Current.Dispatcher.BeginInvoke(() =>
   {
      this.Model = new EmpDetailsModel()
      {
        //get the data from e as e.Name,e.Id and e.Address and bind them to UI.
      };
   });
}

this.Modelに割り当てる前に新しいEmpDetailsModelsを作成すると、 RaisePropertyChangedがトリガーされ、このプロパティが変更されたことをビューに通知します。より具体的には、このプロパティにバインドされた UI コンポーネントに更新が通知されます。UI コンポーネントを ViewModel にバインドするには、次のようにします。

  <Button Name="FetachLAtest" Click="FetachLatest_Click"></Button>
  <TextBlock Name="EmployeeName" Text="{Binding Model.EmpName}"></TextBlock>
  <TextBlock Name="EmployeeID" Text="{Binding Model.EmpId}"></TextBlock>
  <TextBlock Name="EmployeeAddress" Text="{Binding Model.Address}"></TextBlock>

ViewModel インスタンスで View の DataContext を設定することを忘れないでください。最後になりましたが、*View.FetachLatest_Click* イベント ハンドラーから呼び出して、"Latest Entry" ボタンをViewModel.GetLastestEntriesメソッドにバインドする必要があります。これはすべて次の方法で実現できます。

public partial class YourView : BasePage
{
    private WhateverYouWantViewModel _viewModel;

    public YourView()
    {
        InitializeComponent();
        _viewModel =  new WhateverYouWantViewModel();
        this.DataContext = _viewModel;
    }

    private void FetachLatest_Click(object sender, RoutedEventArgs e)
    {
        _viewModel.GetLastestEntries();
    }
}

そして、それは(ほとんど)それです!なぜほとんど?View と ViewModel の間のリンクは非常に強力であり、コード ビハインドに定義されているためです (これは通常、MVVM で回避しようとしているものです)。幸いなことに、この問題を解決するための解決策がいくつかあります。

  • ViewModelLocatorと呼ばれるものは、ViewModelの保存と検索に使用できます。
  • コード ビハインドでGetLastestEntriesメソッドを直接呼び出す代わりに、 WhateverYouWantViewModelでコマンドを作成し、「最終エントリ」ボタンにバインドすることができます。

これらすべての欠点は、より多くのコードを書かなければならないことであり、そこに MVVM フレームワークが登場します! これらのフレームワークは、最小限の労力でクリーンな MVVM アプリケーションを作成するのに役立ちます。

初心者として、 MVVM Light Toolkitの Web サイトにアクセスすることをお勧めします。MVVM パターンに関する有用な記事が多数含まれており、MVVM アプリケーションを設計する方法や、このフレームワークを使用して一般的なシナリオを処理する方法を学習できます。MVVM Light は、Windows Phone で実行される唯一の MVVM フレームワークではありませんが、広く使用されており、大きなコミュニティがあり、物事をできるだけシンプルに保つよう努めているため、引用しています。

この答えは、あなたが望むものを達成するための出発点に過ぎないことを認識しています。さらなる研究が必要ないくつかのアイデアのみを提供しますが、正しい方向に進むのに役立つことを願っています.

于 2013-10-13T22:09:18.997 に答える