简体   繁体   English

在mvvm模型中实施Windows Phone应用

[英]Implement the windows phone app in mvvm model

I am trying to implement MVVM for one of my Windows Phone app that i am developing and its growing to be big. 我正在尝试为我正在开发的Windows Phone应用程序之一实现MVVM,并且该应用程序越来越大。 I have tried below code in Model class.I want to know how can i handle the scenario where user clicks on a button "Latest Entry" and it will connect to a service and executes a method asynchronously.Once the data is returned i have to display the latest record in UI which has 3 text fields EmpName,EmpID,Address. 我已经在Model类中尝试了下面的代码。我想知道如何处理用户单击“最新条目”按钮,它将连接到服务并异步执行方法的情况。一旦返回数据,我必须在UI中显示最新记录,该记录具有3个文本字段EmpName,EmpID,Address。

Code in Model Class: 模型类中的代码:

      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

The code to connect to service is below: 连接到服务的代码如下:

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

view xaml code: 查看xaml代码:

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

I was following the link http://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521153(v=vs.105).aspx . 我正在跟踪链接http://msdn.microsoft.com/en-us/library/windowsphone/develop/gg521153(v=vs.105).aspx

It was very helpful but I want to know where do i put the code to connect to service (model ? or Viewmodel ? How does the viewmodel should look like ? 这很有帮助,但我想知道将代码连接到哪里(服务?模型或Viewmodel?),viewmodel应该是什么样子?

There are various ways to implement MVVM into an application, it varies depending on developpers and application requirements. 有多种方法可将MVVM实施到应用程序中,具体取决于开发人员和应用程序要求。

But for started, let's try to keep things simple and to focus on ViewModels (because this seems to be where is your interest). 但是首先,让我们尝试使事情简单并专注于ViewModels(因为这似乎是您的兴趣所在)。

MVVM means Model View ViewModel, Model is your business/domain code, View is basically your XAML and its associated code behind, and ViewModel is the link/glue between Views and Models. MVVM表示模型View ViewModel,Model是您的业务/域代码,View本质上是您的XAML及其相关代码,而ViewModel是View和Models之间的链接/胶水。 An important thing to note is that ViewModels mustn't know Views (meaning don't reference them). 需要注意的重要一点是ViewModels一定不知道View(即不引用它们)。 This ensures a better separation of concerns, and thus try to build an application easier to test and to maintain. 这样可以确保更好地分离关注点,从而尝试构建易于测试和维护的应用程序。

So to make a long story short, ViewModels don't know Views but they have to communicate with them... And this magic is made possible thanks to Bindings! 简而言之,ViewModels不了解View,但是它们必须与它们进行通信……而Bindings使这种魔术成为可能! XAML/UI components display data, these data comes from the ViewModel which is bound to the View through Bindings mechanisms (provided on WP by the Silverlight framework). XAML / UI组件显示数据,这些数据来自ViewModel,后者通过绑定机制(由Silverlight框架在WP上提供)绑定到View。 This means the ViewModel contains all the data required by the View, actually a ViewModel represents all the data or behaviors of a View . 这意味着ViewModel包含View所需的所有数据,实际上ViewModel代表 View的所有数据或行为

Being not the best person to describe the whole MVVM pattern and all its subtilities, i'll leave this sensitive task to most knowledgeable people in the field ;). 由于不是描述整个MVVM模式及其所有功能的最佳人选,因此我将把这一敏感任务留给该领域的大多数知识渊博的人;)。 Here are some really great links that should help you : 这里有一些非常有用的链接应该可以帮助您:

All this being told, you must be a little bored with theory, so let's try to write some code. 所有这些被告知,您一定对理论有些无聊,所以让我们尝试编写一些代码。 The problem is that there are many ways to organize your code, so all that follow is just a kind of pseudo code, it cannot be used directly into your application! 问题在于组织代码的方式有很多,因此,后面的只是一种伪代码,不能直接在您的应用程序中使用!

In your case, you could create just a ViewModel like this one 在您的情况下,您可以只创建一个像这样的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
    }
}

About assignements from data service to your this.Model , we are dealing with an asynchronous callback, so maybe it would be wiser to use the Dispatcher in case the callback is not called from the UI Thread : 关于从数据服务到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.
      };
   });
}

Creating a new EmpDetailsModels before assigning it to this.Model will trigger RaisePropertyChanged and notify the View this property has changed. 它分配给this.Model之前创建一个新的EmpDetailsModels将触发RaisePropertyChanged并通知查看该属性已经改变。 More specifically, the UI component bound to this property will be notified for being updated. 更具体地说,将通知绑定到此属性的UI组件进行更新。 To bind your UI components to the ViewModel, you can do something like that : 要将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>

Do not forget to set the DataContext of your View with your ViewModel instance. 不要忘记使用ViewModel实例设置View的DataContext。 Last but not least, you have to bind your "Latest Entry" Button to the ViewModel.GetLastestEntries method by calling it from your *View.FetachLatest_Click* event handler. 最后但并非最不重要的一点是,您必须通过从* View.FetachLatest_Click *事件处理程序中调用“最新条目”按钮,将其绑定到ViewModel.GetLastestEntries方法。 All this can be achieved this way : 所有这些都可以通过以下方式实现:

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

And that's (almost) it! 就是(差不多)了! Why almost? 为什么差不多? Because the link between the View and the ViewModel is quite strong and defined into the code behind (which is something we are usually trying to avoid in MVVM). 因为View和ViewModel之间的链接非常牢固,并且在后面的代码中定义了(这是我们通常在MVVM中要避免的事情)。 Fortunately, there are some solutions to solve this issue : 幸运的是,有一些解决方案可以解决此问题:

  • What we call a ViewModelLocator could be used to store and to locate ViewModels 我们所谓的ViewModelLocator可以用来存储和定位ViewModels
  • A Command could be created in WhateverYouWantViewModel and bound to the "Lastest Entry" Button, instead of calling directly the GetLastestEntries method in code behind 可以在WhateverYouWantViewModel中创建一个命令并绑定到“最新条目”按钮,而不是直接在后面的代码中调用GetLastestEntries方法

The downside of all this is that you would have to write more code and that's where MVVM framweworks come up! 所有这些的缺点是您将不得不编写更多的代码,这就是MVVM framweworks出现的地方! These frameworks will help you to write clean MVVM applications with minimum effort. 这些框架将帮助您以最小的努力编写干净的MVVM应用程序。

As a beginner, i would warmely advice you to visit MVVM Light Toolkit website. 作为初学者,我会热烈建议您访问MVVM Light Toolkit网站。 It contains lots of useful articles about the MVVM pattern, to learn how to design an MVVM application and to handle common scenarii using this framework. 它包含许多有关MVVM模式的有用文章,以学习如何设计MVVM应用程序以及如何使用此框架处理常见场景。 MVVM Light is not the only MVVM framework running on Windows Phone but i'm quoting it because it is widely used, it has a big community and it strives to keep things as simple as possible. MVVM Light并不是Windows Phone上运行的唯一MVVM框架,但我引用它是因为它被广泛使用,它拥有一个庞大的社区,并且致力于使事情变得尽可能简单。

I'm aware this answer is only a starting point to achieve what you want. 我知道这个答案只是实现您想要的起点。 I only give you some ideas that need further study, but i hope it will help you move in the right direction. 我只给您一些需要进一步研究的想法,但我希望它能帮助您朝正确的方向发展。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM