简体   繁体   中英

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

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:

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

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 ?

There are various ways to implement MVVM into an application, it varies depending on developpers and application requirements.

But for started, let's try to keep things simple and to focus on ViewModels (because this seems to be where is your interest).

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. An important thing to note is that ViewModels mustn't know Views (meaning don't reference them). 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! 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). This means the ViewModel contains all the data required by the View, actually a ViewModel represents all the data or behaviors of a 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 ;). Here are some really great links that should help you :

  • From Josh Smith
  • Wikipedia with code samples for ViewModel
  • If you already know MVC or MVP patterns, this one will help you to spot differences

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

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 :

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. More specifically, the UI component bound to this property will be notified for being updated. To bind your UI components to the ViewModel, you can do something like that :

  <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. 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. 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). Fortunately, there are some solutions to solve this issue :

  • What we call a ViewModelLocator could be used to store and to locate 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

The downside of all this is that you would have to write more code and that's where MVVM framweworks come up! These frameworks will help you to write clean MVVM applications with minimum effort.

As a beginner, i would warmely advice you to visit MVVM Light Toolkit website. 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 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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