Working With DataGrid Selected Item In WPF With MVVM Pattern Using Blend For Visual Studio And MahApps Metro UI FrameWork

In this article, you will learn how to get the selected DataGrid item with MVVM pattern and how to customize the DataGrid visual appearance, using Blend for Visual Studio. Blend is a user interface design tool developed by Microsoft. It helps you to design XAML based Windows desktop and mobile applications. In this project, I have used Mahapps Metro UI framework for user interface. The Mahapps Metro overrides the style of the default control and it gives them back to Metro UI look.

Before starting this article, let’s look at the small overview of MVVM pattern in WPF.

What is MVVM?

MVVM stands for Model View ViewModel. The MVVM design pattern is used while dealing with UI and data binding in WPF technology. The MVVM pattern guides you to organize and structure the code to be more maintainable, testable, and extensible with high standards.

Why MVVM?

The MVVM separates all your functions for your applications (UI, Business logic, and actual data). It makes your code easier to understand, maintainable and easy to test (Unit test).

Model

It simply holds the actual data and is completely UI independent, it has nothing to do with business logic. It’s unaware of View and ViewModel.

View

View is a UI (User Interface) and Visual representation of data. It simply holds the formatted data and is unaware of Model. It manages what gets displayed

View Model

It is to my mind the master & middleman. It acts as the communication layer between Model and View. It holds the all business logics (my Logics) -. It’s responsible for data formatting and data communication.

Let’s look at MVVM Architecture.

 model

I hope you understand the concept of MVVM, now we will implement the MVVM pattern in our sample project.

Step 1

In this project we are going to follow below listed principles and you will learn implementing those principles to how to make maintainable and testable project.

  1. Simplicity
  2. Blendability
  3. Designability
  4. Testability

Note

  • Our project structure should support Data binding.
  • No code behind (*Almost).

We are going to create our project in the below structured way.

MVVM

Let’s start with new WPF Application project.

MVVM

Step 2

Create separate folder for Model, View and View Model like below image.

In this Project I have created Helper and Service folder for separate the Base class implementation and Data service layer.

MVVM

Create a new abstract class in Helper folder, rename class name to ViewModelBase.

This is base implementation logic for our Model and View Model.

In this class I have used INotifyPropertyChanged interface for client notifications.

For more details about INotifyPropertyChanged interface check below Microsoft official link.

Here is an implementation of ViewModelBase; Add the below code in ViewModelBase class.
  1. public abstract class ViewModelBase: INotifyPropertyChanged {  
  2.     public event PropertyChangedEventHandler PropertyChanged;  
  3.   
  4.     protected void IPropertyChanged(string PropertyName) {  
  5.         PropertyChangedEventHandler Handler = this.PropertyChanged;  
  6.   
  7.         if (Handler != null)  
  8.             Handler(thisnew PropertyChangedEventArgs(PropertyName));  
  9.     }  
  10.   
  11.     protected bool SetPropertry < T >  
  12.         (ref T Storage, T Value, [CallerMemberName] string Propertyname = null) {  
  13.             if (EqualityComparer < T > .Default.Equals(Storage, Value)) return false;  
  14.             Storage = Value;  
  15.             IPropertyChanged(Propertyname);  
  16.             return true;  
  17.         }  
  18. }  
With the release of Microsoft Visual Studio 2012 and .Net 4.5 Microsoft introduced some new features [CallerMemberName] attribute. For more details about CallerMemberName attribute read my previous blog How to Use CallerMemberName Attribute in WPF with MVVM Pattern.

Create a new class in Model folder, rename the class name to Person, It is an actual data property.

Here is an implementation of Person class. Add the below code in Person class.
  1. public class Person  
  2.   
  3. {  
  4.     private string _Name;  
  5.     public string Name {  
  6.         get {  
  7.             return _Name;  
  8.         }  
  9.         set {  
  10.             _Name = value;  
  11.         }  
  12.     }  
  13.     private int _SID;  
  14.     public int SID {  
  15.         get {  
  16.             return _SID;  
  17.         }  
  18.         set {  
  19.             _SID = value;  
  20.         }  
  21.     }  
  22.     private string _Location;  
  23.   
  24.     public string Location {  
  25.         get {  
  26.             return _Location;  
  27.         }  
  28.         set {  
  29.             _Location = value;  
  30.         }  
  31.     }  
  32.     private string _EDate;  
  33.   
  34.     public string EDate {  
  35.         get {  
  36.             return _EDate;  
  37.         }  
  38.         set {  
  39.             _EDate = value;  
  40.         }  
  41.     }  
  42. }  
Create a new Interface class in Service folder; rename the class name to IPerson. It is defines the signature of the functionality.

Here is an implementation of IPerson interface. Add the below code in IPerson class.
  1. public interface IPerson   
  2. {   
  3.    IEnumerable<Model.Person> GetAllDetails();   
  4. }
Create a new class in Service folder; rename the class name to PersonDataDump. It’s an implementation class of IPerson interface and dumps data for our project data representation.

Here is an implementation of PersonDataDump. Add the below code in PersonDataDump class.
  1. public class PersonDataDump: IPerson {  
  2.     public IEnumerable < Model.Person > GetAllDetails() {  
  3.         var List_Data = new List < Model.Person > ();  
  4.         List_Data.Add(new Model.Person() {  
  5.             Name = "Karthikeyan",  
  6.                 SID = 50679,  
  7.                 Location = "Pune",  
  8.                 EDate = "16-10-2016"  
  9.         });  
  10.   
  11.         List_Data.Add(new Model.Person() {  
  12.             Name = "John",  
  13.                 SID = 50668,  
  14.                 Location = "Pune",  
  15.                 EDate = "15-10-2016"  
  16.         });  
  17.         List_Data.Add(new Model.Person() {  
  18.             Name = "Vincent",  
  19.                 SID = 50669,  
  20.                 Location = "Pune",  
  21.                 EDate = "14-10-2016"  
  22.         });  
  23.   
  24.         List_Data.Add(new Model.Person() {  
  25.             Name = "Kennady",  
  26.                 SID = 50469,  
  27.                 Location = "Pune",  
  28.                 EDate = "14-10-2016"  
  29.         });  
  30.         List_Data.Add(new Model.Person() {  
  31.             Name = "Asif",  
  32.                 SID = 50569,  
  33.                 Location = "Pune",  
  34.                 EDate = "14-10-2016"  
  35.         });  
  36.         return List_Data;  
  37.     }  
  38. }  
Move the MainWindow.xaml file to View folder and change the namespace in MainWindow code behind file and App.xaml file accordingly.

Create a class in ViewModel folder; rename the class name to MainWindowViewModel.

The MainWindowViewModel class holds all the business logics and core implementations. It is works like communications layer between model and View.

Here is an implementations of MainWindowViewModel, Add the below code in MainWindowViewModel class.
  1. public class MainWindowViewModel: ViewModelBase {  
  2.         public MainWindowViewModel() {  
  3.             StartUp();  
  4.   
  5.             public void StartUp() {  
  6.                 LoadDetails();  
  7.             }  
  8.             public void LoadDetails() {  
  9.                 var p = IPersonService.GetAllDetails();  
  10.                 MasterData = new ObservableCollection < Model.Person > (p);  
  11.             }  
  12.             private Model.Person _SelectedPerson;  
  13.   
  14.             public Model.Person SelectedPerson {  
  15.                 get {  
  16.                     return _SelectedPerson;  
  17.                 }  
  18.                 set {  
  19.                     SetPropertry(ref this._SelectedPerson, value);  
  20.                 }  
  21.             }  
  22.   
  23.             private IPerson _IPersonService;  
  24.             public IPerson IPersonService {  
  25.                 get {  
  26.                     if (_IPersonService == null) {  
  27.                         IPersonService = new PersonDataDump();  
  28.                     }  
  29.   
  30.                     return _IPersonService;  
  31.                 }  
  32.                 set {  
  33.                     IPersonService = value;  
  34.                 }  
  35.             }  
  36.             private ObservableCollection < Model.Person > _MasterData;  
  37.             public ObservableCollection < Model.Person > MasterData {  
  38.                 get {  
  39.                     return _MasterData;  
  40.                 }  
  41.                 set {  
  42.                     SetPropertry(ref this._MasterData, value);  
  43.                 }  
  44.             }  
  45.         }  
The ObservableCollection immediately updates the UI with the help of INotifyPropertyChanged interface when the collections changed.

It is very useful when you want to know when the collections has changed.

Observable collections represent a dynamic data collection that provides notifications when collections have changed (Items added, removed).

For more details about ObservableCollection check the below Microsoft official link.
Step 3 Installation of Metro UI framework

For installation of Metro UI framework, please check my previous blog.
Change the Accent color Blue to Indigo and AppTheme style Base Light to BaseDark, after that changes just compile and check the MainWindow style it will look like below image.

MVVM

Step 4

Add a new DataGrid control and four textbox controls in MainWindow.xaml and align the control accordingly like below image

MVVM

Save all the changes and open the same project in Blend for Visual Studio.

Step 5 Creating Object Data Source

Press create data source then choose the Create Object Data Source like below image.

Create data Source

MVVM

Create Object Data Source

MVVM

Choose the MainWindowViewModel then hit the Ok button from the Create object Data Source Window.

MVVM

Choose the MainWindowViewModel from Data tab then Drag into the Grid like below images.

Choose MainWindowViewModel

MVVM

Drag into MainWindow Grid

MVVM

Choose the MasterData from the Data tab then Drag into the DataGrid Control like below images.

Choose MasterData

MVVM

Drag into DataGrid Control.

MVVM

Once you dragged the MasterData Collection you can see the data in DataGrid Control.

Step 6

Customize DataGrid visual appearance

 

  1. Uncheck AutoGenerateColumns
  2. Choose Gridline Visibility - All

MVVM

Once you've made  your changes you can see the changes in DataGrid Control.

MVVM

  • Alternate Row background

Change the alternating row background brush and alternation count like below image.

MVVM

Step 7

Add SeletedItem Property in MainWindow.xaml like below image.

MVVM

Choose the SelectedPerson for each property then drag into each textbox like below image.

MVVM

Once you've dragged all the properties save all the changes.

Step 8

  • Go to the Visual studio again

Choose the Yes to All to conform the Changes which have done in Blend.

Press Ctrl+Shift+B to compile the project.

Output

I had done some changes in visual appearance of DataGrid and textboxes you can refer to from attached project file.

Hit F5 to check the Output.

MVVM

Get Selected Item

MVVM

MVVM

Conclusion

I hope you liked this article .Please provide your valuable comments and suggestions.

Up Next
    Ebook Download
    View all
    Learn
    View all