在mvvm模型中实现windows phone app

krr*_*hna 1 c# mvvm windows-phone-7 windows-phone windows-phone-8

我正在尝试为我正在开发的Windows Phone应用程序之一实现MVVM,并且它正在成长.我在Model类中尝试了下面的代码.我想知道如何处理用户点击按钮"Latest Entry"的场景,它将连接到服务并异步执行一个方法.一旦数据被返回我必须在UI中显示最新记录,其中包含3个文本字段EmpName,EmpID,Address.

模型类代码:

      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
Run Code Online (Sandbox Code Playgroud)

连接服务的代码如下:

    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.
            }
Run Code Online (Sandbox Code Playgroud)

查看xaml代码:

                        <Button Name="FetachLAtest" Click="FetachLatest_Click"></Button>
                        <TextBlock Name="EmployeeName"></TextBlock>
                        <TextBlock Name="EmployeeID"></TextBlock>
                        <TextBlock Name="EmployeeAddress"></TextBlock>
Run Code Online (Sandbox Code Playgroud)

我正在关注链接http://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521153(v=vs.105).aspx.

它非常有用,但我想知道我将代码放在何处连接到服务(模型?或Viewmodel?视图模型应该如何?

Air*_*irL 6

有多种方法可以将MVVM实现到应用程序中,具体取决于开发人员和应用程序要求.

但是对于开始,我们试着让事情变得简单,并专注于ViewModels(因为这似乎是你感兴趣的地方).

MVVM意味着Model View ViewModel,Model是您的业务/域代码,View基本上是您的XAML及其相关代码,ViewModel是Views和Models之间的链接/粘合剂.需要注意的一点是,ViewModel必须不知道Views(意思是不要引用它们).这可以确保更好地分离关注点,从而尝试构建更易于测试和维护的应用程序.

所以长话短说,ViewModels不知道视图,但他们必须与他们沟通......而且这个魔法因Bindings而成为可能!XAML/UI组件显示数据,这些数据来自ViewModel,它绑定到View through Bindings机制(由Silverlight框架在WP上提供).这意味着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
    }
}
Run Code Online (Sandbox Code Playgroud)

关于从数据服务到你的this.Model的分配,我们正在处理一个异步回调,所以如果没有从UI线程调用回调,那么使用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.
      };
   });
}
Run Code Online (Sandbox Code Playgroud)

创建一个新的EmpDetailsModels将其分配给前this.Model将触发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>
Run Code Online (Sandbox Code Playgroud)

不要忘记使用ViewModel实例设置View的DataContext.最后但并非最不重要的,您必须通过从*View.FetachLatest_Click*事件处理程序调用它来将"最新条目"按钮绑定到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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是(差不多)它!为何几乎?因为View和ViewModel之间的链接非常强大并且定义在后面的代码中(这是我们通常在MVVM中要避免的).幸运的是,有一些解决方案可以解决这个问题:

  • 我们称之为ViewModelLocator的东西可用于存储和定位ViewModels
  • 可以在WhateverYouWantViewModel中创建一个Command并绑定到"Lastest Entry"按钮,而不是在后面的代码中直接调用GetLastestEntries方法

所有这一切的缺点是你必须编写更多代码,这就是MVVM framweworks出现的地方!这些框架将帮助您以最小的努力编写干净的MVVM应用程序.

作为初学者,我会温馨地建议您访问MVVM Light Toolkit网站.它包含许多关于MVVM模式的有用文章,学习如何设计MVVM应用程序以及使用此框架处理常见的scenari.MVVM Light不是Windows Phone上运行的唯一MVVM框架,但我引用它是因为它被广泛使用,它有一个很大的社区,它努力使事情尽可能简单.

我知道这个答案只是实现你想要的一个起点.我只给你一些需要进一步研究的想法,但我希望它能帮助你朝着正确的方向前进.