Windows Phone Mango: Getting Started with MVVM in 10 Minutes
published on: 6/20/2011 | Views: N/A
Currently rated 4.62 by 29 people
In this article I am going to talk about using the MVVM design pattern in Windows Phone 7.1 Mango applications. The purpose is to explain everything you need to know about this pattern in just 10 minutes with less theory and more sample code.
To begin with lets first mention in short what is MVVM: the Model-View-ViewModel (MVVM) pattern provides a flexible way of building Windows Phone applications by separating the application into three groups of components:
- View: Here you put all the XAML
- ViewModel: Here you put all the presentation logic that connects the UI and the data
- Model: Here you put all data classes and business objects that you will need
NOTE: For more information you can also take a look at the official MSDN documentation.
Why choosing MVVM? Any benefits?
Here is why you should care about the MVVM pattern:
- view / presentation logic separation: by separating the view / XAML from the presentation logic MVVM enables developers to think only about code and designers - only about XAML
- automated unit testing: this view / logic separation also greatly improves automated unit testing of the presentation logic
- improved code re-use: since the presentation logic is in separate components / classes from the views / XAML you can easily combine them using inheritance and composition in any way you like, just like you can with any other class
- design time data support: you can see how your UI will look like in Blend. I.e. the designers can test the UI with sample data and even simulate a fully functional data binding scenario.
- multiple views: the same ViewModel can be presented with multiple views, depending on the the user role for example - a really nice to have bonus from the MVVM pattern
Basically we will need a sample Windows Phone 7.1 Mango project. Before we begin I need to mention that in this example we will use the DelegateCommand: a Reusable ICommand implementation that we implemented in our previous post: Building a Reusable ICommand implementation for Windows Phone Mango MVVM apps. Note that commanding is a new feature that comes to Windows Phone with the Mango update.(where commanding means that some of the controls now support commands)
MODEL
The first thing we need to do is to define our Model. We will create a sample Person class with two properties: Name and Age. One of the most important things here is to implement the INotifyPropertyChanged interface because we need the UI to be notified when a change happens in a Person object. (In our example this is used in order to update the corresponding item in the ListBox when the SaveChanges button is pressed. See the View section below for more info.):
public class Person : INotifyPropertyChanged { private string name; private int age; public string Name { get { return name; } set { if (this.name != value) { this.name = value; this.RaisePropertyChanged("Name"); } } } public int Age { get { return this.age; } set { if (this.age != value) { this.age = value; this.RaisePropertyChanged("Age"); } } } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }VIEW MODEL
The next step is to define the PersonViewModel. It consists of the following parts:
- SaveChangesCommand - this command is used to save the changes that a user has made for the selected Person object.
- LoadDataCommand - this command is used to populate the ObservableCollection of Person objects
- SelectedName - this property represents the name of the selected Person object
- SelectedAge - this property represents the age of the selected Person object
- SelectedPerson - this property represents the whole selected Person object
public class PersonViewModel : INotifyPropertyChanged { private string name; private int age; private ObservableCollection<Person> personDataSource; private ICommand loadDataCommand; private ICommand saveChangesCommand; public PersonViewModel() { this.loadDataCommand = new DelegateCommand(this.LoadDataAction); this.saveChangesCommand = new DelegateCommand(this.SaveChangesAction); } private void LoadDataAction(object p) { this.DataSource.Add(new Person() { Name = "John", Age = 32 }); this.DataSource.Add(new Person() { Name = "Kate", Age = 27 }); this.DataSource.Add(new Person() { Name = "Sam", Age = 30 }); } private void SaveChangesAction(object p) { if (this.SelectedPerson != null) { this.SelectedPerson.Name = this.name; this.SelectedPerson.Age = this.age; } } public ICommand LoadDataCommand { get { return this.loadDataCommand; } } public ICommand SaveChangesCommand { get { return this.saveChangesCommand; } } public ObservableCollection<Person> DataSource { get { if (this.personDataSource == null) { this.personDataSource = new ObservableCollection<Person>(); } return this.personDataSource; } } public string SelectedName { get { if (this.SelectedPerson != null) { return this.SelectedPerson.Name; } return string.Empty; } set { this.name = value; } } public int SelectedAge { get { if (this.SelectedPerson != null) { return this.SelectedPerson.Age; } return 0; } set { this.age = value; } } private Person selectedPerson; public Person SelectedPerson { get { return this.selectedPerson; } set { if (this.selectedPerson != value) { this.selectedPerson = value; if (this.selectedPerson != null) { this.name = this.selectedPerson.Name; this.age = this.selectedPerson.Age; } this.RaisePropertyChanged("SelectedName"); this.RaisePropertyChanged("SelectedAge"); } } } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }VIEW
The final step is to define the View. For the purposes of this example we will use MainPage.xaml. Basically we will create :
- "LoadData" button which will use the LoadDataCommand to populate the DataSource with data.
- ListBox data bound to the PersonViewModel and also two separate TextBox controls for editing the properties of the selected Person object: Name and Age
- "Save Changes" button that will be used to save the changes through the SaveChangesCommand.
- NOTE: Do not forget to set Binding with Mode=TwoWay on the two TextBox controls, so that you will be able to edit/update values!
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Button Content="LoadData" Command="{Binding LoadDataCommand}" /> <ListBox ItemsSource="{Binding DataSource}" SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" Height="100"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="Name:"/> <TextBlock Text="{Binding Name}" /> <TextBlock Text="Age:" Margin="10,0,0,0"/> <TextBlock Text="{Binding Age}" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <TextBlock Text="Name:"/> <TextBox Text="{Binding SelectedName, Mode=TwoWay}" /> <TextBlock Text="Age:"/> <TextBox Text="{Binding SelectedAge, Mode=TwoWay}" /> <Button Content="Save Changes" Command="{Binding SaveChangesCommand}" /> </StackPanel>A simple way to bind the view to the view model is just to set the DataContext:
public MainPage() { InitializeComponent(); // simple way to bind the view to the view model this.DataContext = new PersonViewModel(); }Here are some screen shots:
Here is a demo video to see the example in action:
That was all about getting started with MVVM in 10 Minutes (in Windows Phone 7.1 Mango). Here is the full source code:
I hope that the post was helpful.
You can also follow us on Twitter: @winphonegeek for Windows Phone; @winrtgeek for Windows 8 / WinRT
Comments
posted by: @cleytonferrari on 6/21/2011 3:19:25 PM
Cool! I'm learning about the MVVM pattern for use in Desktop applications in WP7 can, thanks for the help clear steps!
posted by: Joshy on 6/22/2011 8:37:28 AM
Very neat and simple enough for even dummies(read me) to understand!
UI Sketch
posted by: jeff on 6/22/2011 4:12:24 PMNice, clean coding style. Love it. I find the need to sketch the UI first and then create the ViewModel. Is this breaking the rules? Thanks WPG!
RE: UI Sketch
posted by: winphonegeek on 6/22/2011 5:09:54 PMIf starting from the UI makes you more productive then go for it. You just have to make sure that you are not doing too much compromises with your ViewModels because of this. Otherwise it's fine.
Usings
posted by: Rich on 7/20/2011 8:20:58 PMI find articles like this very helpful, as I'm teaching myself programming. I do wish, however, when people wrote articles such as this, they would include the using statements, instead of assuming that people know what references they need to include for things such as INotifyPropertyChanged, ObservableCollections, etc. Otherwise, nice, simple, easy to follow example that helps a lot.
RE:Using
posted by: winphonegeek on 8/19/2011 7:34:24 PMThank you for the suggestion. We will take your suggestion into account when writing future articles.
posted by: Tuan Huynh on 11/3/2011 9:48:29 AM
In MainPage.xaml, I think we must put Text="{Binding SelectedName, Mode=TwoWay}" for Name Textbox instead Text="{Binding SelectedName}", if we don't use Mode=TwoWay, we can't save the value for name when it's changed.
RE: @Tuan Huynh
posted by: winphonegeek on 11/3/2011 11:46:35 AMIndeed having the Mode of a binding set to TwoWay is important for having the value written back from the UI control to the property in the view model. However, if you take a second look at the code sample in the article you will notice that this is already done:
<TextBox Text="{Binding SelectedName, Mode=TwoWay}" />
Refresh.
posted by: helpNeeded on 11/15/2011 4:42:46 PMAs the title suggest, I am required to continuously retrieving data from the server ( I did the above method to display the data out). I created a method to call my web service.
My thoughts is having a refresh button. But somehow, by calling the method again, the data I got back was in a mess.
Could I get a help on this.
Thanks.
no sense whatsoever
posted by: not a newb on 6/22/2012 2:42:22 AMThis is a terrible example. Some code is literally thrown over the wall with no explanation of what links to what, how, or why. "Here it is, get it? No? Well you're SOL he he he.. tweet me"
Who posts this garbage?
Model / ViewModel Mixup?
posted by: Greg Woods on 9/16/2012 10:34:23 AMI'm just starting out, so trying to get a handle on the whole MVVM pattern.
However, it seems to me that implementing INotifyPropertyChanged in the model is wrong. Doesn't it belong in the ViewModel?
Surely if the model is business logic it should have no knowledge of Silverlight of Windows Phone. You should in theory be able to move the Model into a separate Visual Studio project, and use it in (for example) a web application.
I really want to get my head round the right way to implement the pattern, so any feedback would be very much appreciated.
RE: Model / ViewModel Mixup
posted by: winphonegeek on 9/20/2012 12:42:08 PMGreg,
Indeed, it is a good idea to get a good understanding of MVVM and other basic principles as well. Having that understanding will repay for itself over and over again.
While you are correct that the model should contain business logic and should not be related to any presentation technology, implementing INotifyPropertyChanged just adds another feature to your model and does not tie it to the view.
Actually, implementing INotifyPropretyChanged is a good practice, if you are using local database, as explained in this article: http://windowsphonegeek.com/articles/Performance-Best-Practices-Windows-Phone-Mango-Local-Database
How to Bind Json Api Data that'll come Dynamically
posted by: Devil on 9/12/2013 8:15:04 AMHI,
We have a Web Api and we need to bind that api data into Listbox after api parsing. But our Listbox is not populated with required instead it throwing Exception at Xaml layout.
Help Please
Regards.
Need a better example
posted by: krrish on 11/23/2013 4:24:47 AMThe above example is very useful for the beginners .It would be great if you can have another example which shows where the code to connect to db,local db or service should be placed in MVVM..
Top Windows Phone Development Resources
- Windows 8 Development Guide
- Windows Phone Development Guide
- Windows Phone Toolkit In Depth e-Book
- WindowsPhoneGeek Developer Magazine
- Top Components for Windows Phone and Windows 8 app development
- 400+ Windows Phone Development articles in our Article Index
- PerfecTile, ImageTile Tools for Windows Phone and Windows 8
- Latest Windows Phone Development News & community posts
- Latest Windows 8/ WinRT Development News & comunity posts
- Windows Phone & Windows 8 Development Forums
Our Top Tips & Samples
- What's new in Windows Phone 8 SDK for developers
- Implementing in-app purchasing in Windows Phone 8
- All about Live Tiles in Windows Phone 8
- Send automated Email with attachments in Windows Phone
- All about the new Windows Phone 8 Location APIs
- Creating Spinning progress Animation in Windows Phone
- Getting started with Bluetooth in Windows Phone 8
- The New LongListSelector control in Windows Phone 8 SDK in depth
- Make money from Windows Phone: Paid or Free app, which strategy to choose
- Getting Started with the Coding4Fun toolkit ImageTile Control
- Building cross platform mobile apps with Windows Phone and PhoneGap/Cordova
- Windows Phone Pushpin Custom Tooltip: Different Techniques
2 komentar:
Find out how THOUSAND of people like YOU are working for a LIVING by staying home and are living their dreams TODAY.
SUBSCRIBE NOW
If you're looking to lose weight then you have to try this brand new personalized keto diet.
To create this keto diet, certified nutritionists, fitness trainers, and professional cooks united to provide keto meal plans that are productive, convenient, money-efficient, and satisfying.
From their launch in January 2019, 1000's of clients have already transformed their body and well-being with the benefits a good keto diet can offer.
Speaking of benefits: in this link, you'll discover 8 scientifically-certified ones offered by the keto diet.
Posting Komentar