1

我正在尝试为我正在开发的一个 Windows Phone 应用程序实现 MVVM,并且它正在变得越来越大。我在模型类中尝试了下面的代码。我想知道如何处理用户单击“最新条目”按钮的情况,它将连接到服务并异步执行方法。一旦返回数据,我必须在 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

连接到服务的代码如下:

    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.
            }

查看xml代码:

                        <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

这很有帮助,但我想知道我在哪里将代码连接到服务(模型?或 Viewmodel?viewmodel 应该是什么样子?

4

1 回答 1

6

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

但首先,让我们尽量保持简单并专注于 ViewModel(因为这似乎是您的兴趣所在)。

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

所以长话短说,ViewModels 不知道 Views,但它们必须与它们进行通信......而这种魔力是由于 Bindings 而成为可能的!XAML/UI组件展示数据,这些数据来自ViewModel,ViewModel通过Bindings机制绑定到View(在WP上由Silverlight框架提供)。这意味着 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 线程调用回调,使用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* 事件处理程序调用它来将“最新条目”按钮绑定到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
  • 可以在WhatYouWantViewModel中创建命令并绑定到“最后一个条目”按钮,而不是在后面的代码中直接调用GetLastestEntries方法

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

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

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

于 2013-10-13T22:09:18.997 回答