The MVVM pattern separates an application into three main components: the Model, the View, and the ViewModel. The Model defines the data and business logic. The View displays the UI. The ViewModel acts as an intermediary between the Model and View by providing data and handling UI logic and user input. It notifies the View of changes using events. This allows for separation of concerns and testable code. The View binds to the ViewModel rather than the Model directly using properties, commands, and events to update the UI asynchronously as data changes.
4. Model
public class Person
{
public Person() { }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Age { get; set; }
}
5. ViewModel
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
6. ViewModel
private Person _selectedPerson;
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
if (_selectedPerson != value) {
_selectedPerson = value;
NotifyPropertyChanged("SelectedPerson");
}
}
}
10. • The Mode property determines how changes are synchronized
between the target control and data source
– OneTime – Control property is set once to the data value and any subsequent changes
are ignored
– OneWay – Changes in the data object are synchronized to the control property, but
changes in the control are not synchronized back to the data object
– TwoWay – Changes in the data object are synchronized to the control property and vice-
versa
<TextBlock x:Name="FirstName"
Text="{Binding FirstName, Mode=OneWay}"/>
11. • ViewModels implement INotifyPropertyChanged
public class ProfileViewModel : INotifyPropertyChanged
{
private Person _person;
public Person Person
{
get { return _person; }
set {
if (value != _person)
{
_person = value;
NotifyPropertyChanged("Person");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (null != PropertyChanged)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
12. <Button Command="{Binding EditCommand}"
CommandParameter="{Binding SelectedPerson}"
Content="Edit" HorizontalAlignment="Center"
VerticalAlignment="Center"/>
class EditPersonCommand : ICommand
{
ViewModel _viewModel;
public EditPersonCommand(ViewModel viewModel)
{
_viewModel = viewModel;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object person)
{
_viewModel.EditPerson(person as Person);
}
}
13. • Reuse Model and View-Model code
• Test the ViewModel with unit tests
• Maintainability
• Can show design-time data in Expression
Blend and the Visual Studio designer