<<

How to: Use the MVVM Pattern in POS

Sample files

 Sample project

Further reading

 Microsoft Dynamics AX 2012 for Developers [AX 2012]

 SDK Download

 Model-View-ViewModel pattern

Introduction AX Retail Point of Sale utilizes a form of the Model-View-ViewModel (MVVM) pattern to separate UI from business logic. MVVM has its roots in SmallTalk’s Model-View-Controller (MVC) pattern and became popular in recent years wwithith WPF developmentdevelopment.. The pattern has been applied mainlymainly to newer forms found in the InteractionDefaults project but can be found in other projects too.

History The POS code base has gone through several iteratioiterationsns and one long term goalgoal has beenbeen to separate business logic from UI code. This effort is not completecomplete and the following summarizes the current state:state:

 Legacy forms exist in core and individual services as well as the Dialog service where most business logic is mixed with UI handler code

 New forms have been added to the InteractionDefaults project, accessed via a new Interaction service

MVVM in POS The idea behind MVVM is that /state is containedcontained with the model, business logic is spread across the model and view-model and the user interface is the view. The view binds to the view-model and the view-model wraps or controls access to the model..

View

View-Model

Model Model

In POS, the model is often the existing eentitiesntities and the view-model is designed to translate commands in the UI to cchangeshanges in the underlying data.data. The model does not know about the view-model and the view-model does not know about the view..

Data Binding POS utilizes Windows Forms object data binding to bind UI cocontrolsntrols to propertpropertiesies in the view-model. For data binding to work, objects implement the .Component.INotifyPropertyChanged interface which specifies a PropertyChanged event.

Tutorial

In the tutorial, we araree going to implement a simple form that displays thethe name of a person. It also has a button that changes the person’s name to “Tom Jones”.Jones”. Traditionally we would have just added this code directly into the form class but we want to keep the UI separate from the business logic so we are

not tightly coupled with any particular UI tectechnolohnology.gy.

1.1. Start a new Windows Forms project in Visual Studio called MVVMSample.. 2.2. Create a new Person class that represents a person in the system. To keep it simple, it has two string properties: FirstName and LastName..

class Person {{

public string FirstName {{ get; set; }}

public string LastName {{ get; set; }} }}

3.3. Create a new PersonViewModel class which will be our view-model class for the UI to bind to which

wraps the model passed in to the constructor. The view-model is a form of the Adapter and Mediator design patterns. Our view-model exposes a single Name property that aggregates the underlying FirstName and LastName properties of Person.

using System; using System.ComponentModel;

class PersonViewModel : INotifyPropertyChanged {{ private Person person;

PersonViewMPersonViewModel(Personodel(Person p)p) {{

this.person = p; }}

public string Name {{ get {{ return string.Format(“{0} {1}”, this.person.FirstName, this.person.LastName); }} }}

public void ExecuteNameChangeCommExecuteNameChangeCommand()and() {{ this.person.FirstName = “Tom”; this.person.this.person.LastNameLastName = “Jones”;

// Trigger the Name property changed OnPropertyChanged(“Name”); }}

// Implementation of INotifyPropertyChanged … }}

4.4. Next we data bind our controls to a data source (our(our view-model). We do this by openiopeningng up the Windows Forms designer and dragging a BindingSource to our form.

5.5. In the properties for the BindingSource, drop down the DataSource property and choose “Add project data source…””, this will display the Data Source Configuration Wizard::

Choose Object and then select the PersonViewModel as the data object::

6.6. Now we want to bind the Text property of our TextBox to the Name property of our ViewModel.. Select the TextBox on the form and in the Properties window, select DataBindings -> -> Text and in the drop-down choose the Name property of the PersonViewModel..

Now the TextBox will reflect the value ooff PersonViewModel.Name.. 7.7. Next we override OnLoad for the form and create the view-model and add it to the BindingSource..

private PersonViewModel viewModel;

protected override void OnLoad(EventArgs e) {{ if (!this.Des(!this.DesignMode)ignMode) {{ // Create some demo data Person person = new Person() { FirstName = "Bill", LastName = "Gates" };

// Create view model that wraps Person and add it to the binding source viewModel = new PersonViewModel(person); this.bindingSource.Add(viewModel); }}

base.OnLoad(e); }}

8.8. Lastly we want to execexecuteute commands against the view-model. To do this we listen to the Button’s’s Click event and call the ExecuteNameChangeCommand() method on the PersonViewModel. This updates the underlying Person object and fires a PropertyChanged event that the data binding system listens for and will automatically update the value of the TextBox in the UI.

private void OnButton_Click(objecOnButton_Click(objectt sender, EventArgs e) {{ this.viewMothis.viewModel.ExecuteCdel.ExecuteChangeNameChangeNameCommand();ommand(); }}

Summary

The UI binds to the viewview-model-model and executes commandcommandss against the view-model and any changes are reflected up from the view-model. The UI does not maintainmaintain state or hold business logic. ThiThiss keeps thethe business logic and state separated from the UI whichwhich allows the UI technology to be moremore easily changed in the future without affecting tthehe businessbusiness logic.

Even though this is a simple example, it demonstrates the pattern used in POS. POS makesmakes use of some more advanced data binding features such as converters to convert from one type in the view-model to a different type needed by the UI but the MVVM pattpatternern forms tthehe basis for data bibindingnding in POS.