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.
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.
- Simplicity
- Blendability
- Designability
- 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.
Let’s start with new WPF Application project.
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.
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.
- public abstract class ViewModelBase: INotifyPropertyChanged {
- public event PropertyChangedEventHandler PropertyChanged;
-
- protected void IPropertyChanged(string PropertyName) {
- PropertyChangedEventHandler Handler = this.PropertyChanged;
-
- if (Handler != null)
- Handler(this, new PropertyChangedEventArgs(PropertyName));
- }
-
- protected bool SetPropertry < T >
- (ref T Storage, T Value, [CallerMemberName] string Propertyname = null) {
- if (EqualityComparer < T > .Default.Equals(Storage, Value)) return false;
- Storage = Value;
- IPropertyChanged(Propertyname);
- return true;
- }
- }
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.
- public class Person
-
- {
- private string _Name;
- public string Name {
- get {
- return _Name;
- }
- set {
- _Name = value;
- }
- }
- private int _SID;
- public int SID {
- get {
- return _SID;
- }
- set {
- _SID = value;
- }
- }
- private string _Location;
-
- public string Location {
- get {
- return _Location;
- }
- set {
- _Location = value;
- }
- }
- private string _EDate;
-
- public string EDate {
- get {
- return _EDate;
- }
- set {
- _EDate = value;
- }
- }
- }
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.
- public interface IPerson
- {
- IEnumerable<Model.Person> GetAllDetails();
- }
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.
- public class PersonDataDump: IPerson {
- public IEnumerable < Model.Person > GetAllDetails() {
- var List_Data = new List < Model.Person > ();
- List_Data.Add(new Model.Person() {
- Name = "Karthikeyan",
- SID = 50679,
- Location = "Pune",
- EDate = "16-10-2016"
- });
-
- List_Data.Add(new Model.Person() {
- Name = "John",
- SID = 50668,
- Location = "Pune",
- EDate = "15-10-2016"
- });
- List_Data.Add(new Model.Person() {
- Name = "Vincent",
- SID = 50669,
- Location = "Pune",
- EDate = "14-10-2016"
- });
-
- List_Data.Add(new Model.Person() {
- Name = "Kennady",
- SID = 50469,
- Location = "Pune",
- EDate = "14-10-2016"
- });
- List_Data.Add(new Model.Person() {
- Name = "Asif",
- SID = 50569,
- Location = "Pune",
- EDate = "14-10-2016"
- });
- return List_Data;
- }
- }
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.
- public class MainWindowViewModel: ViewModelBase {
- public MainWindowViewModel() {
- StartUp();
-
- public void StartUp() {
- LoadDetails();
- }
- public void LoadDetails() {
- var p = IPersonService.GetAllDetails();
- MasterData = new ObservableCollection < Model.Person > (p);
- }
- private Model.Person _SelectedPerson;
-
- public Model.Person SelectedPerson {
- get {
- return _SelectedPerson;
- }
- set {
- SetPropertry(ref this._SelectedPerson, value);
- }
- }
-
- private IPerson _IPersonService;
- public IPerson IPersonService {
- get {
- if (_IPersonService == null) {
- IPersonService = new PersonDataDump();
- }
-
- return _IPersonService;
- }
- set {
- IPersonService = value;
- }
- }
- private ObservableCollection < Model.Person > _MasterData;
- public ObservableCollection < Model.Person > MasterData {
- get {
- return _MasterData;
- }
- set {
- SetPropertry(ref this._MasterData, value);
- }
- }
- }
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.
Step 4
Add a new DataGrid control and four textbox controls in MainWindow.xaml and align the control accordingly like below image
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
Create Object Data Source
Choose the MainWindowViewModel then hit the Ok button from the Create object Data Source Window.
Choose the MainWindowViewModel from Data tab then Drag into the Grid like below images.
Choose MainWindowViewModel
Drag into MainWindow Grid
Choose the MasterData from the Data tab then Drag into the DataGrid Control like below images.
Choose MasterData
Drag into DataGrid Control.
Once you dragged the MasterData Collection you can see the data in DataGrid Control.
Step 6
Customize DataGrid visual appearance
- Uncheck AutoGenerateColumns
- Choose Gridline Visibility - All
Once you've made your changes you can see the changes in DataGrid Control.
Change the alternating row background brush and alternation count like below image.
Step 7
Add SeletedItem Property in MainWindow.xaml like below image.
Choose the SelectedPerson for each property then drag into each textbox like below image.
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.
Get Selected Item
Conclusion
I hope you liked this article .Please provide your valuable comments and suggestions.