DotNet MAUI MVVM: Deep Dive into MVVM Architecture with .NET MAUI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Welcome to CodingDroplets, your go to channel  for comprehensive tutorials on dotnet development. In this video, we are continuing our dotnet MAUI  tutorial Series, where we explore various aspects of building cross platform applications in  dotnet MAUI. If you are new to the series or want to catch up on previous episodes, make sure to  check out the playlist link provided in the video description below. In today's video, we'll delve  into the exciting topic of implementing the MVVM (Model, View, View Model) pattern in dotnet MAUI  using the powerful "CommunityToolkit.Mvvm" library. Before we dive into the project development, let's  take a moment to preview the final output of the application we'll be creating in this video. By  the end of this tutorial, you will have a fully functional application that allows you to add  employees by providing their employee ID, name email and part-time status. Now, as we add the  employee you can observe that the newly added employees are listed in a list view providing a  convenient overview of all the employees in our application. To demonstrate the dynamic nature of  our application, let's add two more employee records. As you can see, the list view is updated instantly  to reflect the additional employees we have added. This real-time synchronization ensures that  our user interface remains up to date with the underlying data. Moving forward, let's explore the  functionality to view the details of an employee by clicking on any item in the list view. We'll  navigate to a Details page that showcases the specific information we provided when adding  the employee. This seamless integration between the view and the view-model facilitated by the  data bindings, ensures that the user experiences a consistent and smooth application flow.  Now, that we have witnessed the final output and the code functionalities of our project, Now  let's dive into the project development. Having created a new DOTNET MAUI app project,  let's proceed with the project development. Our first step is to organize our code structure by  creating a folder named Pages within the project. With the pages folder in place we'll now create a  Content page inside this folder. This content page will serve as the employee detail page, providing  a dedicated view for displaying employee specific information. As we open the employee detail  page, we'll remove the default vertical stacklayout and label as they are not required for our  specific implementation. Let's proceed by providing a meaningful title for our content page we'll set  the title as employee details. Inside the content page, we'll now incorporate a table view control  which allows us to present data in a structured tabular format. The table view will play a crucial  role in displaying the employee information in an organized manner. Although we have not discussed  the table view control in detailed yet, this video will provide you with a comprehensive  understanding of how to effectively utilize it. Before we dive deeper into the table view, let's  explore one of its Key Properties called intent. The intent property defines the purpose of the  table specifically for iOS. We have four options to choose for the intent property. The first option  is data, which is used for presenting data in a tabular format. The second option is form, which is  ideal for presenting a data input form. The third option is menu, which is suitable for presenting  a selectable menu and finally the fourth option is settings, which is used for presenting a table  of configuration settings. For our employee detail page, we'll select the data intent to present the  employee data effectively within the table view. We can open the table root element where we can  define multiple table sections. For our example, we only require one table section within the table  root. To provide Clarity and Context, let's assign a title to the table section, we'll name it "Basic  Information". Now, within the table section we can add multiple cells to display different employee  details. For the first cell, let's use a text cell to display the employee ID. We'll assign the text  property of the text cell as employee ID. At this stage, we won't assign any value to the detailed  property, as we'll bind it later to reflect the specific employee ID. Next, let's add another text  cell to display the employee name. Similarly we'll add one more text cell to display the email of  the employee. To provide additional functionality, let's incorporate a switch cell which displays an  on-off switch. We'll use this cell to represent the "Is part-timer" status which is a Boolean value.  Now that we have set up the visual elements for our employee detail page, it's time to create  the corresponding view-model class to handle the data and logic behind the scenes. To keep our  code structure organized, we'll create a new folder named models within our project. Inside  the models folder, we'll create another folder named view models to specifically house our view  model classes. Now, within the view models folder let's create a new class named employee detail  view model that will serve as the view model for our employee detail page. In the employee detail  view model class, we'll create several properties to hold the data for the employee. Let's start by  creating a property named employee ID to store the employee's ID. Next we'll add a property  named employee name to store the employee's name. Following that we'll create a property named  email to hold the employee's email address. To capture the "Is Part-Timer" status, which is a  Boolean value, we'll add Boolean property with the name "is part-timer". Now that our view model is  set up, we can proceed to bind the values from the view model to the corresponding elements in the  employee detail page. In the detail property of the employee ID text cell, let's bind the employee ID  property of the view model. Similarly, in the name text cell, we'll bind the employee name property.  Before we continue, let me introduce a convenient way to simplify the binding process. To make  the Binding easier, we can assign the data type property of the content page to the view model  type. To do this we need to import the namespace of the viewmodel class into the xaml file. In  our case the namespace of the viewmodel class is "MauiMvvmDemo.Models.ViewModels". In the  xaml file, we can assign a prefix to the imported namespace. Let's use "VM" as the prefix short for  "view models". We can use the following syntax to import the namespace "xmlns:<prefix>", then "clr-namespace" colon and actual namespace. After assigning the namespace, we can set the data  type of the content page using the prefix we defined. By typing the prefix followed by a colon,  we can see the suggested view model class "EmployeeDetailViewModel", which we can select. Now, let's  continue binding the value for the email property. After providing the Binding keyword, we can see  the suggestions out of which we can select the property which we need to bind. For the switch  cell, we'll bind the "IsPartTimer" property in a similar manner. With this, we have completed  the Binding of all the properties connecting the visual elements in the employee detail page to  the corresponding properties in the view model. Now, let me guide you on how to assign the View  Model binding to the content page. Let's open the "EmployeeDetailPage.xaml.cs" class, where we can  create an instance of the viewmodel class and provide some dummy data for demonstration purpose.  Let's assign the employee ID as 1001 and the employee name as John Thomas. We can also provide  an email and set the "is part-timer" value to true. To connect the view model to the content page,  we'll utilize the BindingContext property of the content page. Let's set the BindingContext property  to the view model object we created, making the view model the data context for the content page.  Additionally, in the "app.xaml.cs" class, we can make this employee detail page the main page by  assigning it accordingly. Now, let's run the project and observe how the employee detail page appears  in the emulator. In the emulator, you can see the table view displaying the data populated based on  the object we provided in the BindingContext of the content page. The employee ID, employee name and  the other details are now showing the exact values as specified in our view model. Now let's explore  how we can populate different employee details using the same content page. To demonstrate this,  let's remove the object and the BindingContext provided in the "EmployeeDetailPage.xaml.cs"  class as we'll assign it in a different way. Inside the pages folder, let's create a new content page  named "MainPage". I am assigning the title of the main page as mvvm demo. We can remove the label  inside the auto generated vertical stacklayout. To align the contents at the bottom, let's set the  vertical options property of the vertical stack layout to end. Now let's add a label with the text  employees to serve as a heading. We can format the label to enhance its appearance. Below the label,  let's add a button with the name "employeeButton1" and the text "Employee1". we can also create  a click event for the button. Let's copy and paste two more buttons and modify their names, text  and click events. Now let's navigate to the "MainPage.xaml.cs" class. In the button click event of the first button, let's create an instance of the view model class. I'm assigning some sample  values to the employee ID, employee name, email and IsPartTimer properties of the viewmodel object.  Next, let's create an instance of the employee detail page. Then we'll assign the viewmodel  object as the BindingContext of the employee detail page. Finally, we'll navigate the user to  the employee detail page using the navigation dot push async method. Now let's copy the same  code and paste it in the click events of the other two buttons. Also, we'll make sure to modify  the employee details accordingly. Now let's move to the "App.xaml.cs" class and set the main page to  the newly created content page. We can create an object of the navigation page and assign the main  page as the root page. Let's run the application in the emulator and observe its functionality. In the  emulator, you can see the three buttons we created on the main page. Let's click on the employee one  button. Now you can see the table view displaying the data specified in the first buttons click  even. Let's try the second button now. Great! the data has been changed to what was specified  in the second buttons click event. Similarly, the third button will display the data specified  in its respective click event. By utilizing a single page, we are able to display different  data bound to it dynamically. With this approach, we can easily create reusable and flexible user  interfaces that adapt to different data sources or scenarios. Now let's explore, how we can notify  the UI when the data changes. To demonstrate this let's add an entry cell inside our table view. Let  the entry cell also displays the employee name. I am binding the employee name property to the entry  cells text property. Let's run the application and check it in the emulator. I am opening the details  of the first employee. Now we can see that the text cell and the entry cell displays the same  name. Let's try to change the value of the entry cell. But as we can see the text cell still shows  the old value. It is not updating as we change it from the entry cell. To address this issue, let's  open the view model class. We need to inherit the class from the "INotifyPropertyChanged" interface.  Visual Studio is showing an error because we need to implement a property changed event handler to  satisfy the interface requirements. Let's implement the property changed event handler in order to  inherit the interface. Next, let's create a method named notify property changed to notify the UI  when a property changes. This method will accept the property name as a parameter. Inside the method  we'll use the event handler to notify the UI. We can invoke the event handler by passing the sender  and the property changed event arguments along with the property name as the parameters. To call  this method whenever the employee name is modified, let's create a private string variable for the  employee name. Then let's assign the get and set methods of the public property. In the set method,  after assigning the value, we can also call the notify property changed method. This way whenever a  value is assigned to this property, it will notify the UI by invoking the event handler. Now let's run  the application and observe it in the emulator. You can now see that whatever changes are made in the  entry cell, the changes are immediately reflected in the text cell. By implementing the   INotifyPropertyChangedotify interface and utilizing the notify property change method, we ensure that  the UI stays synchronized with the underlying data. This allows for a dynamic and responsive  user interface that reflects the latest changes in real time. Now, I'll introduce you a library  that simplifies the implementation of mvvm with less code. The name of the library is   "CommunityToolkit.Mvvm". Maintained and published by Microsoft as a part of the dotnet foundation. Let's install it from the nuget packages. In the browse tab, we can search for the library.  Here we can see the library listed at the top. Let me install it. Now let's create a different view  model to demonstrate the usage of this Library. Let's name the class as "EmployeeDetailViewModel2". The first thing we need to do is, inherit the class from the observable object class which is  the part of the new library. Then we can declare the necessary properties as private. I'm declaring  employee ID, employee name, email and isPartTimer as private properties. Next, we need to add an  attribute named observable property for these properties. Let's copy the attribute and assign  it to all the private properties. Now you can see that it's showing an error in the class  name indicating that another partial class declaration of this type exists. This Library  actually creates another partial class of the same name which contains all the necessary public  properties and the code for notifying the UI. Let me show you where we can find that newly created  class. Let's open the dependencies of our project. Then expand the Android section. Inside the  analyzers section, we can find the CommunityToolkit.Mvvm.SourceGenerators. Inside that we can  see another class with the same name we created. Let's open it. Here you can see that the public  properties are automatically generated by this Library. Note that the property names start with an  uppercase character while our private properties start with a lowercase character. All the public  properties are automatically generated and the necessary code is implemented to notify the UI  when a property changes. So now we don't need to worry about all these implementation details.  They are taken care of by this Library. The only thing we need to do is make our class a  partial class. Now let's assign this new view model instead of the old one in the "EmployeeDetailPage.xaml". I am changing the data type to the new view model. We don't need to change the  bindings as the public properties generated by the library already match these properties. Next,  in the "MainPage.xaml.cs" class, let's change the view models we used during navigation. Now,  let's run the application and see how it works. I am just opening Employee1. You can see that,  when I change the value in the entry field, it is immediately updated in the text cell in real  time. I just wanted to show you the comparison between the two view models we created. In the  first view model without using the "CommunityToolkit.Mvvm" library, there were multiple  lines of code to achieve our requirements. But with the new view model using the library, we  only needed four private properties along with the observable property attribute. This demonstrates  how the "CommunityToolkit.Mvvm" library simplifies the implementation of mvvm with less code. Now  let's dive deeper into mvvm architecture. I am creating a new content page called employee list  page where we will implement functionality to view and add employees to the list. We no longer need  the hard-coded employee data in the main page nor do we need the main page itself. Instead,  we'll set the employee list page as the main page. I am providing a design overview without  going into detail as we have covered the design aspects in the previous videos. The entry fields  are placed here for entering employee data with the text property, initially left blank for binding  later. A button is included to add employees to the list. Next, we add a list view control to display  the added employees in the text cell. We'll bind the employee ID and employee name properties.  Now I am creating a model class for employee inside our models folder. This class will define  the necessary properties for employee data such as employee ID, employee name, email and IsPartTimer.  Next, I am creating a new view model named "EmployeesViewModel" for the employee list page.  This viewmodel class inherits from the observable object class of the "CommunityToolkit.Mvvm" library.  Let's declare the property using the observable property attribute. This property represents  the list of employee objects to be displayed in the list View and we are using an observable  collection of employees for this purpose. An observable collection is a dynamic collection that  allows objects to be added, removed or updated with automatic UI notification. When an object is added  or removed from the observable collection, the UI is automatically updated. We'll make this class a  partial class as we have done previously. Another property we need is the employee object itself  which will be bound to the entry Fields used for adding new employees to the list. We also need to  provide the observable property attribute for this property. Now, let's bind the properties in the xaml  file. First we import the namespace to assign the data type. I'll provide the namespace prefix as  "VM" and add the namespace as we did before. Next we'll assign the data type. In the entry fields for  adding employee details we bind the text property. We can see the suggestions in visual studio for  binding the properties. We are using the employee object for binding specifically binding the  employee ID, employee name, email and IsPartTimer properties to the respective entry fields. Now  let me demonstrate, how we can bind a button click event. When the button is clicked, we need to add  the provided details to the list. Let's move to the view model class. Here I am creating a new private  void method named add. This method adds the current employee object to the employees list and clears  the entry field text by assigning the employee object to a new object. Another important step is  providing the relay command attribute for this method. Now let's navigate to the xaml file and  bind the method to the button. To achieve this, we use the command property of the button and bind  it to the "AddCommand". The "CommunityToolkit.Mvvm" library automatically generates a command named  AddCommand for us and we can see this method in the auto generated class. Let's navigate to  the dependencies, then to Android, analyzers and "CommunityToolkit.Mvvm.SourceGenerators". Inside  relay command generators, we can find a class with the same name as our view model. Let's open it. The  "CommunityToolkit.Mvvm" library generated the code for the command binding. The AddCommand will  trigger our add method in the view model. Now let's move to our employee list page and bind the  values to be displayed in the List View. For the data template, we can assign the data type property.  The data type should be set to the employee class. To provide that, we need to import the namespace of  the employee model class which is "MauiMvvmDemo.Models". Let's import it with the namespace  prefix "models". Now that the namespace is imported, we can assign the data type of the data template  to employee. In the text property of the text cell we are binding the employee ID property and in  the detail property we can bide the employee name property. We also need to assign The View-Model as  the BindingContext of the employee list page. We do this in the Constructor. Next, let's set the new  employee list page as the main page in "App.xaml.cs". I forgot to assign the Item Source property of the  list view in the employee list page. Let's bind it to employees, the observable collection in our view  model. Additionally, in our view model we can initialize the employee object with a new instance  to ensure it's not null when the application loads. Now, let's run the application and check how  it works in the emulator. Let's try adding a new employee by providing the details. When we  click the add button, the employee details are displayed in the list view. Let's add one more  employee. It is also displayed in the list and now we have two employees. Now let's implement  a feature where clicking on an employee in the list, navigates to the detail page displaying the  complete employee information. We also need to make some changes in the employee detail view-model  and employee detail page. In the view-model, we can use an employee object instead of individual  properties and in the employee Details page we can adjust the bindings accordingly. We no longer  need the entry cell, as we are only displaying the details on this page. Now, in the employee list page  we can implement the navigation to the Details page when a list item is tapped. We can use the  item tapped event of the list view control. From the item tapped event arguments, we can obtain the  bound item. The items data type will be an object. But we can cast it to an employee object. Let's  create an instance of the employee detailed view model and assign the selected employee to it. Then  create an instance of the employee detail page and assign the employee detail view model as the  BindingContext. Finally, navigate the user to the detail page using the push async method. Let's run  the app in the emulator and see how it works. We are encountering some errors while compiling the  app because we previously implemented navigation in the main page and the view model structure was  different. Let's comment out those implementations since we are no longer using the main page. Now  let's run the application again. I am adding an employee to the list. When we click on the employee,  we are getting navigated to the detail page and see all the employee details. Let's add one more  employee, when we click on the second item it is also displaying the details of the second employee.  We can easily view the details by tapping on the list view items and that concludes our video on  implementing the mvvm pattern and utilizing the power of CommunityToolkit.Mvvm library  in .NET MAUI. If you found this video helpful, don't forget to subscribe to our channel for more  informative content on dotnet maui development. Hit the like button, if you enjoyed the video  and found it valuable in your Learning Journey.
Info
Channel: Coding Droplets
Views: 1,364
Rating: undefined out of 5
Keywords: maui mvvm, dotnet maui mvvm, .net maui mvvm, .net maui, dotent maui mvvm, .net maui tutorial, maui mvvm library, .net maui mvvm icommand, .net maui mvvm tutorial, .net maui mvvm vs mvu, net maui mvvm example, .net maui mvvm command, maui mvvm toolkit command, .net maui mvvm navigation, maui mvvm sample, maui mvvm command, maui mvvm toolkit example, maui mvvm navigation, maui mvvm framework, maui mvvm toolkit, .net maui mvvm template, dotnet maui, dotnet maui tutorial
Id: B-5e0PJtSDs
Channel Id: undefined
Length: 27min 21sec (1641 seconds)
Published: Tue Jun 20 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.