在 mvvm 模型中实现 Windows Phone 应用程序

本文关键字:Windows Phone 应用程序 实现 mvvm 模型 | 更新日期: 2023-09-27 18:35:18

我正在尝试为我正在开发的一个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.
            }

查看 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。

这很有帮助,但我想知道我在哪里放置代码以连接到服务(模型? 或视图模型?视图模型应该是什么样子的?

在 mvvm 模型中实现 Windows Phone 应用程序

有多种

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

但是首先,让我们尝试保持简单并专注于ViewModels(因为这似乎是您感兴趣的地方)。

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

所以长话短说,ViewModels不知道视图,但他们必须与他们沟通......而这种魔力之所以成为可能,多亏了绑定!XAML/UI 组件显示数据,这些数据来自绑定到 View through Bindings 机制(由 Silverlight 框架在 WP 上提供)的 ViewModel。这意味着 ViewModel 包含 View 所需的所有数据,实际上 ViewModel 表示视图的所有数据或行为

由于不是描述整个 MVVM 模式及其所有微妙之处的最佳人选,我将把这项敏感任务留给该领域最有知识的人;)。这里有一些非常棒的链接,应该可以帮助你:

  • 来自 乔什·史密斯
  • 包含视图模型代码示例的维基百科
  • 如果您已经知道MVC或MVP模式,那么这将帮助您发现差异

综上所述,您一定对理论有点厌倦,所以让我们尝试编写一些代码。问题是有很多方法可以组织你的代码,所以下面的都只是一种伪代码,它不能直接用到你的应用程序中!

在您的情况下,您可以只创建一个像这样的视图模型

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

关于从数据服务到此的分配。模型,我们正在处理异步回调,所以如果回调不是从 UI 线程调用的,也许使用调度程序会更明智:

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

在将它分配给此模型之前创建一个新的 EmpDetailsModels。模型将触发 RaisePropertyChanged 并通知 View 此属性已更改。更具体地说,绑定到此属性的 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.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();
    }
}

这就是(几乎)它!为什么几乎?因为视图和视图模型之间的链接非常强大,并且被定义到隐藏的代码中(这是我们通常在 MVVM 中试图避免的)。幸运的是,有一些解决方案可以解决此问题:

  • 我们所说的视图模型定位器可用于存储和定位视图模型
  • 可以在WhateverYouWantViewModel中创建命令,并将其绑定到"最新"Entry"按钮,而不是在代码隐藏中直接调用 GetLastestEntries 方法

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

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

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