-
Notifications
You must be signed in to change notification settings - Fork 0
MVVM approach
With the MVVM approach the UWP application encapsulates visualization logic and business logic separately. Developer has to create a page (that is View) just for visualization the data. The SQL queries or queries to the services must be implemented in the separated class (that is ViewModel), where results of these queries should be stored in public properties. This approach uses Two-Way Databinding and Commands for communicating between Views and ViewModels. In many cases, the ViewModel implements the INotifyPropertyChanged interface to notify the View about changing in the properties.
Let's implement the simple UWP page (View) and related class (ModelView) that extracts departments and related employees from database model and visualizes these rows.
The XAML of Page:
<Page x:Class="ExamplesWithoutBusinessModels.MvvmView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<ListView ItemsSource="{Binding Departments}"
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayName}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Male employees:</TextBlock>
<TextBlock Text="{Binding MaleEmployees}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Female employees:</TextBlock>
<TextBlock Text="{Binding FemaleEmployees}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
The code-behind of Page:
using Windows.UI.Xaml.Controls;
namespace ExamplesWithoutBusinessModels
{
public sealed partial class MvvmView
{
public MvvmView()
{
this.InitializeComponent();
this.DataContext = new MvvmViewModel();
}
}
}
The related ViewModel:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using Database;
using Database.Models;
namespace ExamplesWithoutBusinessModels
{
public sealed partial class MvvmViewModel : INotifyPropertyChanged
{
public class DepartmentResult
{
public Guid Id { get; set; }
public string DisplayName { get; set; }
public int FemaleEmployees { get; set; }
public int MaleEmployees { get; set; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private ObservableCollection<DepartmentResult> departments;
public ObservableCollection<DepartmentResult> Departments
{
get => this.departments;
set
{
if (value != this.departments)
{
this.departments = value;
this.NotifyPropertyChanged();
}
}
}
public MvvmViewModel()
{
using (var db = new DatabaseContext())
{
this.departments = new ObservableCollection<DepartmentResult>(db.Departments
.OrderByDescending(d => d.Employees.Count())
.Take(5)
.Select(d => new DepartmentResult()
{
Id = d.Id,
DisplayName = d.Name,
FemaleEmployees = d.Employees.Count(em => em.Gender == DBConstants.Gender_Female),
MaleEmployees = d.Employees.Count(em => em.Gender == DBConstants.Gender_Male),
})
.ToArray());
}
}
}
}
The key features are:
- In XAML code of View should be defined controls that will be bind to the public properties of ViewModel
- In code-behind of View should be realized logic for creating the ViewModel and linked it to the View by DataContext property
- In ViewModel should be realized logic for extracting data and storing this data into the public properties
Also, the ViewModel can implement the commands that can be executed from View.