Xamarin Quest: Build Maintainable Apps with Xamarin and MVVM | Kristijan Kralj | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Xamarin Quest: Build Maintainable Apps with Xamarin and MVVM

teacher avatar Kristijan Kralj

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

44 Lessons (3h 41m)
    • 1. Course Overview

      2:22
    • 2. Introduction to MVVM in Xamarin

      2:59
    • 3. MVVM in Action

      5:51
    • 4. Data Binding

      3:36
    • 5. Show Data on the Screen

      4:27
    • 6. Update UI with INotifyPropertyChanged

      5:52
    • 7. Respond to User Interaction

      4:29
    • 8. Pass Parameter with Command

      6:07
    • 9. Use ValueConvertes to Adjust Values

      6:08
    • 10. Improve UI Design of the ToDo App

      4:28
    • 11. Trigger a View Animation from the View Model

      5:08
    • 12. Basics of Unit Testing

      3:08
    • 13. Create Test Project

      2:24
    • 14. Unit Tests for the Value Converter

      6:01
    • 15. Unit Tests for the View Model

      5:56
    • 16. Section Introduction

      1:17
    • 17. Problem: Show Alert to the User

      1:29
    • 18. Solution: Use Dependency Injection

      4:46
    • 19. Tests for Displaying Alerts

      2:21
    • 20. Use Moq in Unit Tests to Fake Dependencies

      3:46
    • 21. How to Use Autofac to Resolve Dependencies

      3:53
    • 22. Calculator App: View and View Model

      4:04
    • 23. How to Organize Project Folder Structure

      2:07
    • 24. Let's Implement History View

      5:25
    • 25. Navigation Using Navigation Service

      13:32
    • 26. Pass Parameter Through Navigation

      4:59
    • 27. Pass Data Back to the Source View Model

      3:30
    • 28. Navigate to the Tab Bar Page

      7:32
    • 29. Section Introduction

      0:43
    • 30. Basics of Networking

      6:52
    • 31. Movies App: Initial Layout

      8:09
    • 32. Fetch and Display Data

      8:32
    • 33. Download Images

      8:38
    • 34. Search for Movies and Empty View

      5:07
    • 35. Section Introduction

      1:07
    • 36. Lets Setup MVVM from Scratch

      5:11
    • 37. Update Collection View to Card Layout

      2:51
    • 38. Navigate to the Movie Details View

      8:16
    • 39. Fetch Data on Navigation

      8:35
    • 40. Implement the Movie Details View - Part 1

      11:02
    • 41. Implement the Movie Details View - Part 2

      2:59
    • 42. Custom Transition on Navigation

      4:11
    • 43. Generic Repository Pattern

      3:40
    • 44. Save Data to Local Database

      7:04
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

2

Students

--

Projects

About This Class

Hey,

does this sentence sound familiar to you: I know that putting all the code in one place in Xamarin Forms is bad, but I'm not really sure how to develop apps using the MVVM pattern?

If it does, you are not alone.

That was exactly going through my mind in 2012, during my internship, while I was trying to implement MVVM pattern in one of the apps I had to develop. A colleague gave me a "simple" explanation of what MVVM is: "you have a view, you have a model, and you have a view model. And data binding is data binding. Simple."

Yeah, I wish it were simple for me at that time.

I knew that the code behind is bad, and just trying to put all the code in the same place will result in a big pile of mess. And that's exactly what's happened.

Over the years, however, I have learned all there is to know about MVVM. I have built MVVM apps in WPF, Xamarin Forms, and iOS.

That's why I created this course. To teach you what I know, so you don't have to spend years and years learning how to use MVVM in Xamarin Forms.

This course will show you how to everything you need to know to start building Xamarin Forms MVVM apps.

Throughout this course, you will see how to:

  • Build applications with Xamarin Forms for both iOS and Android at the same time

  • Avoid complicated code with MVVM pattern by splitting UI from business logic

  • Spend less time fixing bugs by learning how to unit test your apps

  • Get real-life experience by building 3 real applications

  • Make future changes easier and avoid tight coupling by using dependency injection

  • Learn the correct way to perform navigation in MVVM

  • Maintain responsiveness of your app while performing network requests

  • Pass data between view models

  • Trigger animations from the view model

After you finish the "Practical Guide for Building Business Apps in Xamarin Forms" course, you will know how to build beautiful cross-platform apps.

With all that being said, join me on the quest of learning Xamarin.Forms!

Meet Your Teacher

Hello, I'm Kristijan.

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
    0%
  • Yes
    0%
  • Somewhat
    0%
  • Not really
    0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Course Overview: Let's talk about what are you going to learn in this course? We start with the basics because it's important to get those right. You're going to learn what's the MVVM structure and how to connect all layers in this better. Next, we'll build the to-do app. So you can see in a practical example, have all of this works. You're also going to see how to respond to user actions and how to trigger animation from the ViewModel in a correct way. After this, you will see how to test your app so that you don't introduce new bugs while adding new features. You're going to see how to trigger alerts and action sheets. We're going to start building our second app, the calculator app. And I'll show you another way how to organize projects for the structured. In the section about negation, we continue with building features in our calculator app. We are going to introduce new screens and see how to pass data between mu models from source ViewModel to the target you model, but also the other way around from the target ViewModel to the source IP model. Lastly, since stub our pages are common layouts in the mobile apps, you're going to see how to navigate to them and pass some initial data. Next time for performing network requests. You're going to build the movie SAP, download data from the network. You also see how to download multiple images at once. The extra two features you're going to build in this section are the search functionality and the empty view. Do you shown when there is no data in the list? In the last section of the course, we'll continue to build the movie SEP will add movie digital screen and see how to perform custom animation on Page Transition. We will also cover saving data in a local database. And for that, we'll use our repository pattern. So if you're excited about all of this, then let's do this. 2. Introduction to MVVM in Xamarin: Let's kick off this course with a quick explanation of the MVVM pattern. Mvvm stands for Model View, ViewModel. In this image, you can see how the architecture looks like. The view is responsible for defining the UI layout of what the user sees on screen. Ideally, each view is defined in XAML with a limited code behind. That does not contain business logic. However, in some cases, the code behind my contain UI logic that implements visual behavior that is difficult to express in XAML, such as animation. The ViewModel implements properties and commands to which the viewer can data bind to and notifies the view of any state changes through data bindings. You're going to learn about data bindings soon. The ViewModel is also responsible for coordinating the views interaction with any model classes that are required. There is typically one-to-many relationship between the view model and the model classes. And lastly, we have the model layer. Model classes are classes that store data. You might ask, how are these layers organized? At the high level? The view knows about the ViewModel, and the ViewModel knows about the model, but the model is unaware of the ViewModel. And the ViewModel does not know anything about the view. Therefore, the ViewModel isolates the view from the model and allows the model to involve in dependently, or do you. What are some benefits of using MVVM? It's possible to write unit tests for the view model and the model without using the view. The unit tests for the view model can check the exactly same functionality as induced by the view. Second, the app UI can be redesigned without touching the code. Provided that the view is implemented entirely in XAML. Therefore, a new version of the view should work with the existing ViewModel. And lastly, designers and developers can work in parallel. Meaning UI and business logic be implemented independently from each other. Okay, let's dive into some code and show you how the MVVM looks like in Xamarin. In the next lecture, you're going to see MVVM parts. You're going to start slowly, create a new project from scratch and build a simple to-do app. 3. MVVM in Action: In this demo, you are going to see how to build simple to-do application just like this. So by the end of this section, you will know how to build simple application where a user can interact with the app. In this case, we can select Wanted to item has completed. And if we do that, you can see we also run the animation. Let's create this simple to-do app in Xamarin Forms. The reason I start with this simple app is to post advanced features in the background for now and just focus on the basics. Later in the course, we are going to build more complex apps. But it's easier to understand key MVVM concepts on a simple app. Let's create a new project. I'm going to select blank forms app. Click on Next, name it. To do two's, both Android and iOS platforms. Next, and create this. Always the first step I like to do in a new application is to update all NuGet packages just in case any new update to exist in packages are released. Okay, this is done now. I will just run the app to make sure everything still works. Even though we have an empty template. Welcome to summary forms. Awesome. We use our shared to do project in order to implement MVVM in any app. So instead of main page XAML, I'm going to create a new view and call it to you. So I can delete this and I will create new file. It will be Forms Content page with XAML, and I'm going to call it to do. So this will be new layer for our screen. Okay, for now is just empty. Going to add just one label with a simple text. Hello, MVVM. Okay, we have our view layer. Next. Let's add another class for our ViewModel. So typically we name our view models as screen name. So in this case, cream name is to do. And it ends with view model. And this is our ViewModel. For now. It's empty, but we are going to populate it throughout this section. Lastly, what we need is our model layer. And for that, I'm going to create a new class and call it a to-do item. Thank you. Remove this default constructor. And as you could see in the demo, I showed you at the start of this lecture, each to-do item should have two properties. So first is the name of that to-do item. And second, we need some kind of indication if this to the item is completed or not. I'm going to add two new properties. So first property will be string name. So this will be the name of our todo item. And we need another property to represent whether or not these to-do item is completed. So we will indicate that with bool completed property. Okay, let's run the app. And we're going to call here to do view. So and you can see Hello MVVM. So this comes from this label. Now, what I would like to do is to create a new method which will return some sample data in order to show it on the screen. So I'm going to create a new static method. Get to-do items, need to resolve all the missing pieces. And also I'm missing a constructor which takes name as a parameter. So I can right-click on my to-do item class, quick fix, Generate Constructor, select name. And this is automatically generated for me. In order to display this data. In our view, we need to use data binding. 4. Data Binding: In this lecture, we're going to talk about data binding and communication between view and view model. What is data binding in MVVM? Data binding is a concept to describe how to connect the view and the view model. The property in the view is connected with the property in your model in such a way that change in one property automatically updates the other property. Please note that in Xamarin Forms, there could also be a data binding between two view controls. For example, a slider in a label control. This is known as view to view binding. How exactly our view and remodels properties connected. Well. The ViewModel is the binding source in our case. It exposes public property with some data. On the other side, we have view, which is the binding target. It has a UI property or some control. This property can be our text property on a label, for example. And data binding is what connects these two properties. So when the property in the viewModel changes, the property interview is also automatically changed. Okay, how this looks like in code. Let's say we want to display hello binding text from the ViewModel on the view. First, we start by defining this as a public String property. Next, bind, that is, connect that property with the property text of the label. To bind these two properties, we are using binding keyword and the name of the property we bond bind to. The last step is to tell the view where the data is coming from. What is the source of the data? X forms uses the binding contexts property of the view to connected with the source of the data. We assign binding contexts to be an instance of the view model. And then the view uses public properties of the view model. As a result, we can see our text on the screen. What are the data binding modes between source and target property? First, data binding mode is a way to describe in what directions data flows between two connected properties. The binding mode is specified with our binding mode enumeration. First, we have default. This means if the mode is not specify, the default value is used and the default value is one way binding. One-way binding means that data goes from the source to the target. In our case, from the ViewModel, you do a means. Data goes both ways between source and target. One way is to source. Data goes from target to source. One time, data goes from source to target, but only when the binding contexts property of the view changes. Hopefully, this explains a thing or two. Let's go back to the code. 5. Show Data on the Screen: Okay, our to-do item model contains the list we want to show in our view. And in order to show in view that list, we need to, we need to pass that list to our ViewModel. So view and the model, they don't communicate directly. Instead, they're using ViewModel. Its purpose is to prepare data for the view. And the way you model and view communicate is to public properties of the viewModel. So I need a property which will store the least of our to-do items. So I need one new property. And this property will be type of observable collection. If you are not familiar with observable collection. This is our dynamic data collection that provides notification when an item is added or removed or when the whole list is refreshed. So if we change any item in our collection, w will be automatically updated. This observable collection is generic, and we will store our to-do items in here. Let's call this items. And what I need to do is to populate This items. So this is a new observable collection of to-do items and data comes from the model layer. In this case, this is todo item gets to-do items. Next, we need to update our view. So we want to show in the in the list view the list of todo items. For that, I need to use list view that item template and use data template. For now, we can store it in our texts, sell the property text or the text cell is going to show our name from the todo item. And the way we connect that is true binding syntax. So we have our parentheses and we type binding. And after that property, which we will like to bind to, we would like to bind to the name. And we also need to provide the source for our items. So item source will be bind it to our list of items. Now, if we try to run that, we will see that nothing happens. This is completely normal because we are missing one last step, which is data binding. From the view to the ViewModel. We use binding contexts property available in our view in order to connect view and the view model. So binding context for our todo view is to do view modal. Okay, if we run this now, we have our list of to-do items. Great. 6. Update UI with INotifyPropertyChanged: Let's try to run our app on iOS. So I will set my to-do iOS, start a project and hit run. The app works. The next feature I would like to implement is when I click on any to-do item, I would like to have this to-do items displayed in a title of our screen. So for, for a start, we need, we need to wrap our view into navigation page. So this is easy to do here. I'm just going to add new navigation page. Let's try to run to see that the title appears. So we have our bar now. And what I need to do is to bind the title of my to-do view to some kind of property in the viewModel. So I'm going to say that title is equal to binding for page title. Okay? I also need a property of type string to represent this page title. And in the ListView, I need to bind selected item to our property, which I will quote, which I will call selected. Let's go with the selected item. K also need a string property for that. So selected item. And I will add private string field to store our selected item. So in my getter returns selected item and setter. I need to store the value we received from the view into selected item. And also we would like to update our page title to be equal to this value. Actually selected item is to-do to-do item. And here as well, I need to change this to do item. And page titles should be equal to 2 name. Let's try to run this app. And we get a crash since initially we don't have selected item. And here we need to apply optional chaining. So if we don't have selected to-do item, then we won't update our page title. If I click on this, nothing happens. I can just quickly debug to see what's going on. So yeah, we are getting the value. Go to gym. But page title hasn't been updated. And the reason for that is that we need a way to signal to the view that property on a ViewModel is changed. And for that views, I notify property change interface. So if we take a look at the documentation of I naught phi property change interface, we can see that we notify clients and that our property value has changed. So we need exactly that. And the simplest way the ViewModel can implement this interface is by inheriting from mineable object. The object class provides methods to raise events to indicate that something has changed and the Vue receives that change. Okay, Back to the code. So we need to implement bind the object. Let's resolve this. So we're already seeing Xamarin Forms. And here we want to call on property changed for page title. So now if we run our app, Let's see if this fixed the issue. So family type, family type has appeared in title. 7. Respond to User Interaction: In this lecture, I'm going to show you how to respond to our user interaction, such as a user clicking on a button. And in MVVM, we use the command interface in order to do that. So let's see this inaction. The feature I want to develop in this lecture is to add a new button to the toolbar. I want to add button to add a new to-do item. Let's extend our content page with toolbar items. And I'm going to add new toolbar item. Text will be at item. So order is primary and priority 0. Let's see how this looks like. When we run our app. We have this button. And what we want is when we click on this Add Item, that new item appears in this list. And Toolbar item has a command property to bind to our action. I'm going to call this Add Item command. So we need a new property in our view model for this command. I'm going to call it, I command. Resolve this and call it Add Item command. If we take a look at my command interface, if we inspect the high command interface, you can see that it has one event can execute changed. So this event occurs when changes occur that affect whether or not the command should execute. And also we have two methods. First one is can execute. This method defines whether the command can execute or net. And the execute command. This actually invokes our command. So command is an action we want to perform when our user clicks on a button. And in this case, we want to perform new command. And this command takes action. So we want to call Add New Item method. This method doesn't exist yet, so I'm going to generate this method. And simply what we want to do in this method is to add a new item to our list of items. So we add new to do item. Let's call it to do item. And then just have Tom plus 1. So we are using string interpolation indicated with this dollar sign to add items count to our string k. Let's now run and see what happens. It works. Yay. So now the app adds a new item to the list. Every time we tap on the button. 8. Pass Parameter with Command: The next functionality we are going to add is a swipe functionality. So when we swipe to left, we will mark this item as completed. And in Android will get the button in the toolbar so we can complete this item. Instead of having text cell. I'm going to change this to View cell so that I can add a new menu item. Okay? So View Cell, dot contexts, actions. I'm going to add a new menu item. It's text will be complete. And for actual layout of the cell, I'm going to use stack layout and add label and bind text of that label to the name of our to-do item. So bind to name. And if we run this, we shall get the swipe functionality we want. Yeah. So now we need to add a command to our menu item so we can actually complete this item. Okay, let's add a new command. And we need to bind this to ViewModel. But one thing we have to keep in mind, that view cell is actually binded to the to-do item. So ListView is binded to the items property of the ViewModel. But our view cell is binded to the todo item. In order to fix this, we need a way to reference our todo view from our menu item. So first, I'm going to name this content page. Let's say to do, to do View Page. And now I can reference it inside my binding property. So we want to bind that to our command is the binding context. And the command these mark as completed command. But the actual source of our binding is our todo view page. So here I need to reference to do View Page. We also want to pass the to-do item we want to mark as completed. And for that, we will use command parameter. This command bar parameter is going to be the to-do item. So if we bind, if we use binding dot, that means we have passed the whole to-do item. Okay, now we can finally go to the to-do ViewModel and create a new command for Mark as complete. Let's implement this. So in this case, we will use generic command. That means that we are passing one extra parameter. And this parameter is todo item. And we will implement this in Mark as Completed method. Let's generate this. So what we want to do is to set completed of our item to true. So I'm going to just put a breakpoint here. So we can see that this actually executes. Let's complete this. And as you can see, we have passed our go-to work. Item. Completed is set to false. After we execute, this method, completed is set to true. So now we have that functionality. And in the next lecture, you are going to see how to indicate that the item has been completed. 9. Use ValueConvertes to Adjust Values: Like I mentioned in the last lecture, we want to indicate in our view that the item is marked as complete. Let's say we would like to show all completed items with the green text. And for that, I need to bind text color to the completed property. So if our item is completed, then we would like to have loops. Then we would like to have green color. However, our completed property is a type of bull and the text color. This is a type of Xamarin Forms scholar. So we need a way to convert completed bull to a color. And for that, we use where you convince converters. Where you converters are used in data bindings in case where source property and target property are not of the same type. So for example here, our source property is bool and our target property is color. Let's add one per one value property. This is just regular class. Let's call it bool to color converter. And one important thing is that these coordinator implements, I wear your converter. So we have, we have two methods. First method is convert and this Mutton covariance value from ViewModel to the view. The second method convert back. This converts value from the view to the viewModel. So we need to implement convert method. In our case. The value we get here is both. So if our, if our value is equal to true, then we are going to return color forest green. Otherwise, we are going to return just default color. And now we can use this in our view, in our binding. So first, I need to reference our local namespace. So our namespace local is equal to To-do namespace. And the second thing, I need to define my video converter as rare source on this content page. So inside resources and resource dig dictionary, I'm going to use my two converter to assign key to color. And I can use this as convertor parameter. So let's call this resource in this binding. The second thing we want to achieve is to move that completed item to the end of the list. The easiest way to do that is to remove that item from the from the list and then simply added back. If we run the app, we could, we can see the changes. The exact same procedure is if we want to add a strike through the completed to-do item. You can see it here. So we define our text declarations for this. We bind these two completed and use a new converter, this time bolt to text decoration converter. And if our to-do is completed, then we return strikethrough. Otherwise, there is no text decoration. Same thing here. We added that to resource dictionary so we can use it inside our binding property. 10. Improve UI Design of the ToDo App: In this lecture, we are just going to add some finishing touches to our to-do app. So far we color all the basics. And in this lecture I'm going to move a bit faster. First, I need to update the item template of our cell. And for that, I have already prepared the code for this. So we are adding frame around our label. The next thing I'm going to update r is the value converter. So I'm just going to change these colors. If we around the app, we should see the change. Okay, the separators are not necessary. Let's remove the separator so sets a greater visibility to none. And also make sure our background color is white. Next, let's add the progress bar to the list header. So here is our progress bar, and we will bind it to the complete his progress property of the ViewModel. We are also going to add a new label, which will tell us how many items have been completed. One last thing before I go to the ViewModel, I'm going to just format the whole selection. Let's go to the new model. I need two new properties. So this one will be for text to indicate how many, how many items have been completed. And the second one is a double value for our progress bar. Let's also expose these two new properties. So completed, their completed progress properties. What we want to do is to update these two properties whenever we change something on our list. So if we mark our item has completed, we want to call a method which will calculate this complete header properties. So I'm going to name this method calculate completed header. Let's generate this method and just some simple implementation. So what we want is to divide the number of completed items with the total number of items to get how many items have been completed. And also, we want to update our progress with the same calculation. It will be also good to call this method whenever we add a new item. And also we can call this method in our constructor. So let's just run the app and complete couple of items. So let's split this and completed this. And as you can see, the progress bar and the label were updated. Let's also a preview of how the thing works in Android. So it behaves exactly the same. 11. Trigger a View Animation from the View Model: If you are wondering how to trigger of view animation when something inside of you model has changed. Then this lecture is just for your, the way we are going to implement this is that we are going to have event in our todo view model. And we are going to trigger that event when something changes inside view model. And our view is going to subscribe to the, to the event. And we are going to trigger the view animation. So let's see how to implement this. The first thing I need is event. So public event, event handler, where we are going to pass double value. The reason we are passing double value is to animate the update of progress bar. And for that, we need double value passed to the view. We are going to name this event updates progress bar. Okay? We have our progress bar event and calculate completed header. So progress is changing. In this method. We are going to raise, update progress bar event. So I'm going to invoke this. Width. Parameter. Sender is this, and w is completed progress. Now do you have to subscribe to that event? In order to do that, we need to define new, new local instance of our to-do ViewModel. And also to do ViewModel. Let's ascribe to this event. So top, to create a new event handler method. And in this method, we are going to reference our progress bar and trigger animation. To update the value of progress bar. First, we need to name somehow our progress bar. So let's add a new name for it. We'll call it progress bar. Let's remove this value. Since now we are going to trigger it from the code behind. Okay, back to our code behind. And we're going to use progress bar, the progress too. So double value. This value duration is 300 milliseconds and easing let's say, linear progression of our bar. This progress to method is available. So I need to await this and also put our sink here. And let's preview this change. As you can see, the progress bar has beautiful animation now, this concludes our to-do app for now. In the later section, you are going to see how to trigger and display prompt, which will pop up. And then you can insert a new to do item and that item will be added to the list, but more on that later. The reason we are using this event in the ViewModel and attaching this event handler interview. So that ViewModel doesn't, doesn't become aware of view. And what's going on in the code behind. I might have mentioned this before, but Khan behind is fine if we are using it just for animation. And if we are not having the whole business logic in the code behind. 12. Basics of Unit Testing: This section covers Unit Testing. The reason we are talking about unit testing early in the course is because it's very important mainly for minimizing the number of bugs in any app. What is unit testing? Unit testing is a type of testing where individual components of the software are tested. The purpose of unit testing is to confirm that each unit of the software works as expected. Our unit is a small piece in a codebase, usually a single method in a class, but it can be the class itself. Some benefits of unit testing. R increases confidence in changing code. If good unit tests are written in, if they are run, every time any code is changed, you will be able to fast catch any bug introduce by the change. Next, development is faster. How? Without unit tests usually have to check that the code works through the UI. So you have to build your app, you have to run your app, and then you have to click through the app to make sure everything works. With unit testing in place. You write the test, write the code, and run the test. Writing unit tests take some time, but the time is compensated by the less amount of time it takes to run the tests. And finally, it's easier to fix a bug while unit testing. It's faster to fix a bug during development if you have unit tests, then later in the process, when your app is already out on the App Store or Google Play Store. So if you find a bug after your AP was published, then you'd have to debug through the app, fix the bug, and then build and submit the app to the stores. And that usually takes some time. Unit test structure. It has three parts. First part is arrange objects, where we create and set all necessary data for that test. The second part is performing an action we want to test. This is the OCT part or the unit test. And the third is to assert that something is as expected. Okay, Let's see unit testing in action. In the next lecture, we are going to create some tests for the value converters. And in the lecture after that, tests for our todo view model. 13. Create Test Project: In this lecture, we are going to write tests for bull to text decoration converter. And we are going to write tests for our Convert method. So this method returns text-decoration, dot-dot-dot strikethrough if the item is completed. So if the value is true, if our value is false, then it returns none. First, let's create a new unit testing project. Right-click on our solution. Add New Project tests, and add x unit test project. As you can see, there are different options here. And x unit MSTest. The difference is which testing framework is used for testing. We are going to use x unit for testing. Next. Next. And we're going to name this Todo tests. I'm going to remove this default test class and add a class for testing Bu to text decoration converter. So at mu plus and name it bool to text decoration converter tests. I like to name these tests classes as a combination of the class under test. So in our case, this is bolded text decoration converter and add the test suffix. So why tests and not test? Because this class is probably going to contain multiple tests method and that's why I'm using poorer test. Okay? I don't need this constructor and I'm ready to create first unit test. 14. Unit Tests for the Value Converter: A quick side note on tests naming convention. I'm using convention unit of work underscore, expected behavior, underscore scenario under test. So our unit of work is usually a class or method we are trying to test. Expected behavior is what is the outcome when we call the method or where we perform some tick on class. And scenario describes when the expected behavior occurs. In the case of our converter, the unit of work or subject of testing is the Convert method. Expected behavior is that this method returns strike through text decoration. And the scenario under test is that this happens when the item is completed. That is when the past value is true. Okay, back to the Visual Studio. Let's create our first unit test. So this is going to be public void method. And the name is so our our work under test is the Convert method. The convert method returns strike through. And was the scenario when it returns strike through? Well, when item is completed. In order to mark this method as unit test, we need to use fact attribute. So that x unit knows that this is a unit test. Like I mentioned. Every unit tests usually has three phases. So first phase is arrange. Next phase is act. And the third phase is assert. In the orange face, I need to create my converter. And in order to do that, I need to add a reference to the main project. So using to do our converter, these new bool, I'm just going to check whether or not this is public. So if this class is not public, then we cannot see it in our unit tests. So new bool to text decoration converter. In the act part, we call the Convert method. And we are going to store the result in a variable. So we are calling the Convert method. As you can see, Convert method has four parameters, but only first one is necessary. We are going to pass through. And other parameters can be null since they are not used in the converter. And in the assert, I need to check that the result is equal to text decoration strikethrough. I need to use Xamarin Forms here. And we assert that something is true or false. Using assert dot equal. First parameter is what's expected. So we are expecting that this declaration that strike through is our result. With this assert statement, we are trying to confirm that the result is equal to text decoration, that structural when we call convert method with true parameter. So let's now run our test. In case you now have this unit tests bar. You can add it to VW unit test. And let's run the test. And test passes, which mean the Convert method works as expected. Great. Now let's also check that none is returned if value is false, that is, if the item is not completed. So the fastest way to create another test is to copy the first test. And we need to make sure that convert returns none when item is not completed. So item is not completed. It means that it's property completed is set to false. And here in the third part, we need to make sure that our result is equal to none. Let's now run all tests. And both tests are passing. 15. Unit Tests for the View Model: In this lecture, Let's test the view model. It has a bit more business logic. To test it, we need a test class. I have already created the test class and name it to do view model tests. We can start with a simple tests to test that items are populated correctly. So I will create our first test. Viewmodel. Populates items correctly. I have to add effect attribute. First step is to create the view model. So to do your model, What's the result of this model is equal to new Todo model. And assert that the number of items initially in the list is five. Your model items count should be fine. We can now run the tests and all tests are passing. Let's add another test. The next thing we could test is that when we click on the add item, that is, when we execute the Add Item command that a new item is added to the list. This is public void. Unit under test is our height. I can command. We want to check that at Item command, Add new item to the list. Also, we need to add the effect attribute. And first step is to create the viewModel. So we can copy and paste this. Second thing. We need to call our Add Item command. So you model calls, exposes the Item command. And the way we call the command from our test suite executes method. We can have this default parameter. And what we want to assert is that the number of items is six. Now, the second thing we want to check is that our new item is named properly. So it's named to-do item six. And for that, I need to call last. This is provided by link. And here I need to check what's the name. Let's run tests now. And we have failed here. So I didn't change this to six. Let's run this one more time. You can see when the test fails, you get what's expected versus what was actually in the list count. And now this are fine. The next test will be for Mark as Completed command. I have already created that test, so we are again creating ViewModel. After that we are calling as completed command. And we want to check that our last item is completed. The other thing we want to check for our mark as completed command is that it updates a progress bar correctly. So both completed header and completed progress are updated after recall mark as completed. As you can see. This is also fine. And that's it for now, on the basis of the unit testings, these were all simple scenarios. But as we go along, you are going to see advanced testing scenarios. 16. Section Introduction: Hi. In this section, you're going to learn more about dependency injection in MVVM, how to show alerts to the user. And we are going to start working on our second app, the calculator app. By building this app, you will learn everything you need to know about navigation in MVVM. In this and the next section of the course, you will learn how to build an app like this. It performs calculations, but also buses some parameters to the top page where we have to use. So you can see history, our performed calculations. And the second view is about app information. You will see how to use Xamarin Essentials to populate basic application information. This history view also passes some data back to the calculator you. So by the end of the next section, your low how to do that as well. 17. Problem: Show Alert to the User: I have created a new empty Xamarin Forms app and named it navigation. I have also added main view, added one button to show alert. This main view is bound to the main ViewModel. So if we run our app and click on the Show alert, we are going to get the alert. We want. The easiest way you can implement alerts in Xamarin Forms is to call application that current, that main page and displayed alert. We can also call this inside the ViewModel. But with that, we are crossing boundaries with UI and the business logic. Main page and display alert belongs to the UI part of the MVVM, so we cannot directly call it from the main view model. There is also a warning that you don't do this in your own apps. In order to fix the issue we have here, we need some kind of reference for this functionality so that the ViewModel is not directly coupled to the UIKit functionality. And we will provide the same functionality through that wrapper. And for that, we use dependency injection. 18. Solution: Use Dependency Injection: Okay, In the last lecture, I'll tell you that we need to use dependency injection to the couple UI from business logic. What is dependency injection? Anyway? Dependency injection is nothing more than giving a class dependencies it needs. Instead of tasking the algebra with responsibility of making its dependencies. In case with our main view model, the dependency it needs is the functionality to display alerts. What are the benefits of dependency injection? First, the coupling. When you use dependency injection, you can define an interface which some dependency must implement. And then you can change that implementation as you wish. As long as the implemented class satisfies the interface. You can also decouple UI from the business logic or your models in the case of the MVVM. Second, the stability. The class which has dependency injected is independent and it's easier to unit tests. It is installation using stops or mock objects that simulate other objects not under test. This is all testing is often the first benefit noticed when using dependency injection. There are three main types of dependency injection. First one is constructor injection. In the constructor injection, the class gets its dependencies to constructor. Second one is property injection. And as you might guess in this injection, that dependency is set to public property of a class. And last method injection. In this type of injection, the class gets its dependencies true method call. From these three types. Construction injection is the most common. Okay, let's see you how we can achieve decoupling and testability with dependency injection. First, decoupling, I have defined a new interface called Dialogue message, which will represent a contract for displaying alerts and other messages if necessary. It has one method for displaying alerts. Next, we need on actual implementation of this interface. The actual implementation is this dialogue message class. It implements display alert method. And here we call main page that display alert. With this, we have isolated the UI part of our app from our business logic. Next step is to perform dependency injection and inject this interface into the view model. So I'm going to delete this. I need a new field to store that would message. This will be private dialogue message. And we'll use constructor injection to provide dependency of Type II dialogue message. Right-click on the main ViewModel. Quick fix, Generate Constructor, the generic constructor with this dialogue message. And now my implementation of show alert, I call the alloc message that display alert title. Hello. Messages. Hello there. And the button is, okay. We need to provide this dialogue message implementation. And for that, I'm going to use the actual implementation. New dialogue message. Show alert. The same behavior as before. But now the UI part is decoupled from our main ViewModel. And also we can write tests for the logic. 19. Tests for Displaying Alerts: The other benefit of dependency injection is disability. We can write our unit test for the main ViewModel and check that the show alert method works as expected. But instead of passing the real dialogue message class, we can create a class which will implement the same interface, but it won't actually display on alert and call the Xamarin Forms. The reason I'm not using the real implementation in tests is because I will get an error if I tried to use it. And the real display alert method requires the user to interact with the app. The point of unit tests is to automatically check that the code works as expected. Here we have an alternative implementation of our dialogue message. We have called this class dialogue message mock. This is fake class, and its only purpose is to confirm that display alert call was occurred. And for that, we use this count property. Let's see how to create a test for display alert command. In our test, we start with defining a new instance of the main view model. But instead of passing the dialogue message, we pass the instance of dialogue message MOOC. After that, we call our display alert comment. And in the assert part of the test, we check that the least play alert call count is equal to 1. And this means that the display alert was called. If we run the test. The test. 20. Use Moq in Unit Tests to Fake Dependencies: Writing these mocks we use to test our class can be very time-consuming. And to make the process of writing unit tests faster, we use mocking libraries. What are making libraries? These are libraries we can use to automatically fake some interface and inject that in our classes under tests. In this project, I'm going to use mock us are mocking library. The first step is to install MOOC to the navigation tests project. After that, we can start using the MC library. So instead of having this manually implemented doubt message MAC, I'm going to recreate another mock using MC library. So var MAC message is equal new Mock. And we need to provide the interface we want to mock that interfaces HIE dialogue message. Now we need to define what method we want to mock. And we want to mock the display alert method. Since that method is used in our main view model. First rewrite the custom implementation for the display alert method. So Mach dollar message setup, this method. The method is displayed heart. And then main remodel calls. This method, will return, just complete a task. Now, instead of injecting dollar message MAC, we inject our mock dialogue message. But we need to provide the object which was actually implemented. And that's i dialogue message. In the assert part of this test, what you want to do is to check that our display alert method was called with exactly this parameter. And it's called just once. Now if we run our tests, we can see that the test seal passes. In the resource section of this lecture, I have attached the link to the mock documentation. So if you are interested in learning more about Mach, then use the documentation to learn more about it. 21. How to Use Autofac to Resolve Dependencies: Better way to organize our dependencies is to use inversion of control container. And what are those? You might ask? Well, I'm glad you asked. Inversion of control. Containers are classes or packages which help us to register dependencies and then automatically resolved them when we need them. And in this project, we will use out of luck. This is Inversion of Control container for dotnet Core, ASP.net Core and dotnet framework. In our case, main view model has dependency on dialogue message. And to initialize the main view model, we have to provide an instance of dialogue message at the time of creation. This is currently down in the main view, but this is not convenient. A better way would be to pass an interface of ViewModel to the main page. And now you are going to see how to do that using out-of-bag. First, we need to add new, new package for outer PEC Alto. After we have installed the out-of-stock NuGet package. Now, we need a way to automatically go through our project and automatically register all classes. An interface we have out of whack offers very comprehensive documentation on how to do this. And I'm going to implement this. Here. You can see how to implement the registration. So we need a new instance of our Container Builder. Then we go through our executing assembly, register, all types as implementation and off interface. But also as those glasses itself. Based on the builder, we create the container class. This class contains all registered classes. So here, instead of new main view, I can, I can result mine main view to this container. The second change I can make is instead of initializing the main view model in this constructor, I can pass it as a constructor parameter. So main ViewModel. Viewmodel, and use that as binding contexts. What exactly happens here is when we call our result of main view. This in turn creates a new instance of main view. It also scans what dependency it needs. So main view needs main model and it's going to create a new instance of main ViewModel. Maybe your model requires dialogue, message, and this will be also provided by the alto fuck container. And this all automatically works. If we try to show alert, functionality stays the same, but dependencies are automatically result. 22. Calculator App: View and View Model: I will finish this section by showing you how I implemented the initial version of this calculator app. So I have added calculator view and calculator ViewModel. The app now performs basic arithmetic operations. So we can add, subtract, multiply, and divide numbers. We can also clear numbers using this clear buttons. If you have followed along. Thus far, you want to continue to follow. I have attached to this lecture, calculator view in calculator view model implementation. The reason I'm not showing you how to implement the layout of this app is because these are all basic XAML controls. So we can quickly go through the, our view. So our view is implemented as agreed. And this greed has six rows and four columns. The first row is display, center out is clear, and the remaining gross are these buttons. So these are all implementation of these buttons. The main thing here, our bond commands. So our clear button is bound to the clear command, and our other digit buttons are bound to add char command. Every command has command parameter. And in case of our operations, our command operator is actually an enum which represent the operation. Let's see how this looks like. So we have the enum for operation. The default operation is none. So there is no operation. Then we have add, subtract, divide, multiply, AND operation equal, which will trigger the calculation. We also have an enum for state in which Calculator currently is. So whether we are populating the first number or the second number, Let's just quickly go over through command. So first command is for clear text. So if we are populating first number, then we are going to clear that number. If we are populating the second number, we are going to clear death number when the user clicks the clear button. We're also going to clear the display text. So display text is a property. Ritual display, the number we are currently entering or the result of operation. Next, we have a command for adding a new character to the existing number. So if we are populating the first number, we are adding this character to the first number. If we are populating the second number, we are adding that character to the second number. And final piece is our perform operation method. So if operation is equal and both numbers are populated, we are going to calculate the result of these two numbers. After we get the result of the operation, we store that result into display text and our interview is updated with new value of the display text. We then reset our calculator and can enter new calculation. 23. How to Organize Project Folder Structure: We'll finish this section with a quick tip on how you can organize your folder project structure. Some people like to organize projects structure by layers and type files. So they have folders for interfaces, view, models, views, et cetera. I like to organize code by modules and functionality or features of the app. This approach was suggested by Robert C Martin, also known as Uncle Bob. I'll put links if you want to learn more about it. I usually have three top folders. So application, this contains any Up y components, initializer or configuration files. In this folder usually contains only few files. In my case, I have up the XAML and assembly info. Next, I have column. This is used for all common utility and view components grouped into sub folders. Some examples might be dialogue, messages, controls, models, extensions, or data storage. And finally, we have Modals. You can think of one module as one screen. In the modules folder, I organized screens into logical groups, which are basically sections of the app presented to the user. So every module folder usually contains the view and the view model. In my case, have Calculator view and calculate the ViewModel. And for the main view, I have many view admin view model. I like to group the files this way because usually when I have to change the view, I also need to change the viewModel. So if I need to add a new functionality and I like to have files that change together in a single folder. 24. Let's Implement History View: Let's take this app further by creating a new screen. This screen is going to contain the history of performed calculations. As you can see, I have already created the history ViewModel for that screen is going to have just one property for items. This is the least of performed calculations. Now let's create the history view. A new file, forms and name it history view. I have also set this history view for now to be our main page when we run our up so we can see how the design looks like. As you can see, the screen is for now empty. And let's change that by adding some layout. What I want to do is to show our list of data. And for this, I can use the collection of you. If you're not familiar with the Collection View. This is an alternative, the list you and it's a bit more performant than the ListView for source of data. Collection view uses item source. And I'm going to bind that to our items. Okay? Now we need to define our item template. First. Let's just define simple labeled with some padding. And the Text property. We are, we are going to bind it to the item itself. Last week. We need to do is to set the binding context for our history view. This is going to be history of your model. So model, I'm going to inject it to constructor and set binding context to be equal to that new model. If we run our app, it shows the list of calculations. The last feature I would like to add is to have swipe to delete functionality. For this, I'm going to use swipe you, swipe you is our control that wraps around an item in the list and provides context menu items that are revealed by a swipe gesture at the time of recording, this swipe view is still in pre-release mode. And in order to use it, I need to set this feature flag. So I need to set this flag before forms that in it. In the main activity of the 100 bridge project and also in the AppDelegate of the iOS project before him forms that in it. Let me just build and run the app to make sure it's built with the swipe view. And now we can implement the swipe functionality. So swipe to you, as I said, is our wrapper around our list item. In this case, this is label. And let's implement swipe. You write items. These are the items that appears after we swipe from right to left. I'm going to define one new swipe item for deleting our history items. The delete command is a command defined in our view model, and it simply removes the item from the list of items. The other thing I have done is just slightly changed the way I initialize the items. So now it's initialized from the constructor. So if I tried to swipe success, a cool feature that Collection View offers is a way to define empty view. That is, if there are no items for this, I have just created a simple stack layout with two controls, image and label. So if I delete all items, then this custom empty view appears. 25. Navigation Using Navigation Service: Okay, we are back to the start of our app, and I have switched to the main page of our app to be the calculator view. Again. Now what I want to do is to navigate from the calculator view to the history of view. For that, I'm going to wrap this calculator view in a navigation page and have this, and have the navigation bar here with a button. And when I click on the button, I will navigate to the history view. First. Let's wrap this in an allegation page. That's fairly easy to do. So navigation page is a new navigation page. And the root view of our navigation page is the calculator view. Main page of our app becomes navigation. In the calculator, you have already created this toolbar item. So text is info and command I want to bound to its showed history command. So if I run the sub, I get this button in order to go from our calculator view to the history of view, we will use a separate class for navigation. And I'm going to name this class navigation service. And it's going to implement an interface called AI navigation service. Navigation logic can reside in our views code behind or in a view model. While placing navigation logic, interview might be the simplest approach, it is not easily testable through your interests. Placing navigation logic in ViewModel classes means that the logic can be checked through unit tests. In addition, the ViewModel can then implement logic to control navigation to ensure that certain business rules are enforced. For example, an AP might not allow the user to navigate array from a page without first ensuring that the entered data is valid. Okay, I'm going to use the common folder to create a new folder called navigation. And let's also just quickly put this dialogue messages In assembler in a separate folder called dialogue. I start with the interface, which I'll call ionization service. This interface will defined actions our navigation service class should support. I will create two methods for now. Want to go to the next page, next to you, and one to go back. So I need a method to go to the next few. I'm going to name it push async. And this method will be generic. That is, it will take a type of the view model we wish to navigate to. So in this example, we want to pass history ViewModel as a generic type parameter to the push async method. Let's name this parameter to a view model. And also we could define one parameter. That will be the data we want to pass from one model to the next one. I also need to set on additional rule where my ViewModel. We need to be sure that this is ViewModel type. And we will achieve that by adding new type of model, Bayesian model. So if a class is our ViewModel, it will inherit from the base view model. For now, this class is going to inherit from venerable object. And this Bayesian model, we have 11 method for initializing the state of immortal. So in this method, we are going to take the parameter that was passed to this ViewModel and then we will initialize state of our view model. So task initialized async with object parameter. This is public ritual task. In the view model, we will return task.com a task. And we will make sure that no one can actually create a new instance of this class. So our history will inherit from Bayesian model. Okay? That's one method. And the other method is for, go back to the previous page. For that. I'm going to name this method Pope async. Let's implement this interface in a class called navigation service. What this clause needs, He's our two fields. So one field is for the object, which will actually perform the navigation. In our case, this will be the property of the navigation page called navigation. So negation, negation. We can see this is AI Navigation object, which actually performs negation. So that's the one field I need to add. And I'm going to add him at it as our function which resolves my navigation. The second field we need is an instance of AI component context. This is a class provided by outer foc to automatically resolve new classes, navigation service will need something like this in order to create a new view and new ViewModel. And then it can navigate to that new view. I'm going to create a constructor for this. Take both these fields. The reason I have this funk I navigation here, instead of plain I navigation, is that because at the time of registering interfaces and classes, our navigation page is not the not yet available. And I need a way to provide this I navigation if we go back to the XAML dot. So yes, you are going to see the change I have made in order to register the navigation. So first change is negation page is null, and now I need to register type navigation service. This font, I navigation, navigation funk and just returns navigation page navigation. And I inject that as a navigation parameter to the navigation funk. At this point in time, navigation page is still null and attempting to provide navigation page navigation to here will result in an app crash. That's why I need a way to provide lazy loading. After we build the container navigation page is initialized and it set for the main page of our app. Okay, back to the navigation service. First, we are going to implement pop Async. This is fairly simple. I'm just going to retrieve my navigation object and perform pop async. Await this set, this method as async. Push a sink is next. And the first thing we need is to actually transform this view model type to the view type we are going to navigate to. In this case, I'm just going to use a simple dictionary which will map these two things together. So for history of your model, resolve that to the history view. The first step is to retrieve the page type from that dictionary. So this page map, retrieve by key of type of the viewModel. Next, let's resolve this page using our container. So Resolve, resolve the actual page type. So what will this line do is to use our container provided by out-of-stock to create a new instance of page. In our case, this will be history view. The next step is to actually navigate to that page. I'm missing async here as well. So push async. And once we are on our page, you can use that page to retrieve binding context. In our case, this is a type of base view model. And the end then we can initialize our ViewModel with past parameter. Once we have our navigation service, it's actually easy to perform ligation from the calculator view model. So I initialize it with a parameter of my navigation service. And then in my show history command, I call navigation service dot push, async, history, viewModel. Can't in-app. This looks just like this. So this still works. But what we want to do is to pass the parameters from the history view model. 26. Pass Parameter Through Navigation: We want to pass our list of pass calculation to the history view. In order to do that, I need to populate the list and then pass that list. Another view model, this list will contain our previous calculation. I'm going to define new list of strings. Calculator history. This is going to be populated in the calculate method. So here we are performing our calculation and have access to the first number, second number, and the result of our operation. Let's add that to the calculator history and the new string. First number, and then the name of the operation. For that, I'm going to create a method which will return that. So get operation string. Then second number is equal to result. Let's just generate this method. Our current operation field contains the actual operation which is currently performed. So I'm going to switch over current operation and return string, which will, which represents our operation. Let's use C-Sharp, a feature called switch expressions. So I return based on the current operation, the actual result. So if I have operation, I'm going to return plus. If I have operation subtract, I'm going to return minus string. If I have operation that divide, I'm going to return slash. And if I have operation multiply, I return asterisk sign to represent my operation. Let's just that the default case. In this case we are going to return empty string. If you are not familiar with the switch expression, I'm going to provide a link to the documentation as an added resource to this lecture. So let's pass this calculator history as our parameter. So here I pass calculator history. We need to change our history ViewModel. So we are going to remove these hardcore discrete strings. And instead, we will use what's provided By the calculator view. And we will get, if we override initialized async, the initialized async will get us the list of calculator history through this parameter. So here I will initialize my items as new observable collection of strings and cast my parameter as a list of strings. Let's raise on property changed for our items. If I run the app and navigate to the history, for now it's empty. But let's perform some operation. And now we get this result. 27. Pass Data Back to the Source View Model: Let's say we want to modify the list we got from the calculator of your model. For example, delete one item and then pass this modified list back to the calculator view. In order to do that, we will use messaging center. Messaging center is a class that implements our publish subscribe pattern. It's used for communication between classes. So this mechanism allows publishers and subscribers to communicate without having our reference to each other. This helps to reduce dependencies between them. One note is that messaging center needs to be used carefully or it can cause memory management issues. Let's see how to use it. So in my Delete item method, once I remove the item, I want to send that item through messaging center. So this class is sending the message. The message name is items, and the parameter is this new modify list of strings. We get from the items. Calcutta remodel is going to subscribe to this message. So I'm going to create new methods subscribes to message. And in this method, I'm going to subscribe to history ViewModel. So when history view model sends me the least strings, subscriber is this instance. Message name is items. What I want to do when I get the list of strings is to set the calculator history to be policed. We can just add a breakpoint here to see what happens. So if I add some calculations and pass that to the history view. After that, if I delete one calculation, the calculator remodel is going to get our message that there is only one item left in our list of calculator history items. And that's it. Not too complicated. 28. Navigate to the Tab Bar Page: We will wrap up this section of obligation by showing you how to navigate to the tab page. Since top page is our common page layout in the mobile apps, I have added one more screen up information view to show the app version up name and author. I have added two labels and bound them to name up version and outer properties in the ViewModel. In order to display up name and up version, I'm going to use App Info class from Xamarin Essentials. Xamarin Essentials provides developers with cross-platform API for the mobile applications. And it has class for showing up information. So this class epi info, has that name to get the application name and version string to get the application version. Now, what I would like to do is to show up information and history view in a tab page. So the first step is to add a new file which will be tabbed page. So let's add in for you. And also I'm going to add in for viewModel. So in for ViewModel, let's delete for now this default constructor. And in my info you need to pass before you model and use it as binding context. This top page will be empty page. And in the code behind, we will just set up the taps. So let's do that. Now. I need history view and I need information for you. The first child is going to be history view. So to the property children, I'm going to add history view. And second tab is app information view. So I'm going to add that to the children as well. Okay, let's just remove unused using. And what we need to do now is in the navigation service, add another page map entry. So when we have typeof in for ViewModel, we will resolve that to the info. That is, we will navigate to the Info view when we call with navigation service in for your model. Let me just do that right now. So at the moment, when we tap on the Info view, the calculator view model navigates to the history of your model. But what we want to do instead is to navigate to the Info View Model. Okay, just resolve this. And what I'm missing is inform your model has to inherit from the base view model. Now, if we try to navigate to the info, you should show these two in tops. So we have our history and we have up info as well as information about application name, app, version, and author. One last thing, what we need to do is to pass parameter to the history of your model. So if I try to pass this operator history to the history of your model, it doesn't end up here. Since we are navigated to the ViewModel. And our viewModel gets the calculator history. In order to fix this. First, I need to override method initial async. And here I'm going to get this perimeter. The second step, what I will do here is to define new property for history ViewModel. So this history ViewModel, it's going to get this parameter. Okay, let's just generate constructor with the history of your model. And now in our initialized async method, Let's pass this parameter to the history view model. Great. Now we have history of view model and we have passed the parameter to it. The only thing What's missing is that the binding context of this history view is another instance of the history ViewModel and not the instance we have in our info ViewModel. The fix for this is really simple. I just need to set binding context to be in full view model that history ViewModel. So ViewModel, that history ViewModel. So if I try to calculate something and pass that to the history view. Now, it works. While I think I can do is to just add some icons to the tabs in order to make application bit prettier. 29. Section Introduction: In this section, you will learn all the basics you need to know about networking in Xamarin Forms so that you can perform network calls to retrieve data from a back-end. You will learn how to create this movie. This movie app uses Network API to retrieve data. You will see how to populate a list with the network data and how to download multiple images asynchronously. After this section, you will know how to develop apps similar to this. So if all of this sounds exciting, then let's go. 30. Basics of Networking: Let's see how to perform network requests in Xamarin Forms. Here you can see one example of how to implement network service in Xamarin Forms. So for performing network calls, we use HTTP client. But we are going to have some kind of wrapper around it. And that wrapper we'll call network service. And this will expose its methods through interface. The reason we do this is if we use interface instead of real implementation, then we can fake network calls in our unit tests. Okay, time to fire up Visual Studio and implement the network service. I'm going to create a new blank forms and call it movies. The first step is to just update all the packages. And after we are done with that, let's just quickly run our app to make sure the initial template works. Okay, everything is fine. The app already, it looks awesome. And now let's create our network service. I'm going to add a new class and call it network service. So as I mentioned before, I need a new private field for HTTP client. Let's resolve this and initialize HTTP client. So if we take a look at what methods HTTP client offers, so it offers matter for GET, post, PUT, delete. All of these are asynchronous method for performing network requests. The last thing we need to do before we start implementing our network service is to add Newtons on Jason dotnet package to our solution. The reason we do this is because this package is a great way to serialize and de-serialize JSON objects. And as you know, we mostly use JSON disease through transfer our data through network. So let's add this to our project. Okay, right click, Manage NuGet packages. And already, first recommendation is this package. This is a very popular package. So we are going to add it. Okay? We are going to start with GET method. And this method is going to be asynchronous. And also we are going to make it generic so we can download any kind of data with. This method is going to be public. Async method that returns signed kind of generic result. I need to resolve task. And I'm going to call it get async. Async method will take one parameter that is string urea. Based on our parameter. We are going to call HTTP client and get async and pause our parameter. The result of this call we are going to store in. A variable type is HTTP response message. Let's call it response. Okay, once we have our RFP response, first, we are going to read it as string. So string serialized. After we have our string, we need to transform it into our result object. And for that, we will use Newton's own Jason. So the actual result is Jason convert the serialized object type be the result. And we are going to use this string and we can just return our result. And now we have our simple but powerful method for retrieving data. I'm not going to implement all the remaining methods. So boast, PUT delete, but you can find it in the last lecture of this section in the source code. 31. Movies App: Initial Layout: Okay, let's continue with the creation of this movie app. In order to better visualize the design we're going to implement. I have added this simple placeholder image to both movies Android and also movies iOS. First, I'm going to remove this default main page and create a new page. So XAML and call it main view. Okay. This is going to be the main page of our app. And also I need a view model for this view. So new class. And I'm going to call it main view model. Okay, to keep things simple, I'm going to binding context here. So main view model. Now let's build the layout. I will show this data in the collection view. And source for this data is going to be binded the items property of the ViewModel. But we still need to add that property. Okay, let's quickly add that property. So that will be observable collection of strings for now. And we are going to call it item. Let's have simple data populated here. Let's initialize it to some default data. So new observable collection. And we are going to add some orange or smoothly. So Avengers, let's say a tuple term. And Avengers Infinity worse. Having some default data helps us to better visualize the design we are trying to implement. So back to the collection view. Let's define how the cell is going to look like. So Collection View, icon template. And we need to use data template for that. And let we are going to present this in a simple, simple grid. The reason we are using grid is that we can have image and then label on top of it. So great. With horizontal options. Ooh, center and expand. And for now, let's just image so we can see how the layout looks like. For now. Source is our placeholder. Aspect is aspect fill. So we want to fill the screen from end-to-end. And let's have height of 300. One thing we forgot here is to inherit our main view model from findable object. So let's go back to the main view model. And this is going to inherit from findable object. And let's raise on property change for our items. Okay, now we can see some placeholder images are starting to appear. Let's continue to build this layout. I'm just going to place the simulator on the right so we can see how the layout looks like. So next thing is to add a label. Vertical option is nT. So it's going to be at the bottom of our cell. Texts. We are going to bind to the R movie item. Now we just need to apply some designed to this. Let's say font size 38, text color, white. I'm going to have black, background color. Add some opacity for a better visual look and feel. Vertical text alignment. So we are going to place it at center at some padding. So let's see how this looks like. There are also going to have fixed height of 70 and lasting. Let's add a line break mode to be truncation for now. So if text cannot fit to this data and we are going to truncate at the end. And here we have our initial layout. For now, it doesn't look too exciting. But in the next lecture, we are going to download some data and then display data from the network. 32. Fetch and Display Data: Okay, we are now more than ready to download some data over the network. And as our movies back and I'm going to use IMDB API. So the open Movie Database, in order to use it, you need to request on API key. It's free for 100 requests per day. So just enter your email FirstName, LastName, where we are going to use it and just submit that and to your email should allow the API key. The end point we are going to use here is for searching movies. So we are going to use the S parameter for movie title to search for. And if we perform our basic Git for this endpoint, you can see how this looks like. So I have served for Avengers and I get this JSON result. One might think, I'm going to mention here, which will be useful later, is the link to the movie poster. So you can see this Sx 300. So this represents image width. In our app, we are going to use a slightly larger images. So we are, we are going to modify this URL when we get to the point of downloading images. One cool trick you can use when generating the glasses for this kind of JSON is to use JSON to C-sharp dot com website in order to generate your C-sharp classes. So if I paste my result JSON and click Generate, I'm going to get the C-sharp classes. I can feel with this JSON. And I can then just copy this. Go to Visual Studio and create new, new file. Let's just call it models. And I keep, I can paste this class is here. So we'll just need to use this namespace. And that's it. We have our network data classes. Okay, So back to this API. What we need is some kind of method which will create this search URI. So key parameter here is S. And for that, I'm going to create another class, and I'm going to call it the constants. So this can be static glass. It will have just one utility method for returning deconstructed URL. So public, good, movie URI. So based on your search term, we are going to return a string. And I'm going to use string interpolation here. And instead of this hard-coded renders, I'm going to bust our search term. This of course, return string, and this is a static method. Okay? We are now ready to call this network. So we need our network service. But first, we need to create that interface. So from this network service, I'm going to quick fix, Extract Interface, get. Okay? And this is going to create me I network service. And now I can create a new private field for IE network service. Network service. And we are going to pass that in constructor. Network service and power network service is equal to network service. I'm going to remove this hard-coded data now, since we will be populating these items from network. But I'm going to implement Get and Set. And we need a method to fetch movie data. So let's create a new method. Get movie data. This method, of course does not exist, so I'm going to create it. And it's going to be async. In this method. I want to get result of get async of network that gets async. And type we want to return is our throat object. So this is our object. It has searched, this is list of searched titles. Okay, I'm going to call that. And I need to pass the URI. So constants get movies. And for now I'm just going to hardcode the search term to our interests. And I need await keyword. Okay, so once we have our result, our Route object, I can assign to the, to the items. So item is new observable collection of strings. And we are going to populate it with result re.search, dot select, and we're going to select for now just title. Okay, We have one error here, so we are missing constructor parameter of network service. I'm going to pass the network service. Okay? I need to rise on property changed for the items. And let's try to run our app now. Okay, we have our movies now. The next step is to download the actual images for our movie titles. And you're going to see how to do that in the next lecture. 33. Download Images: Okay, so far we have downloaded the list of movies, and now we have to display images for those movies. Since attempting to implement all the logic required to download these images synchronously. And the ability to download multiple images at once would require a lot of work. What we are going to do is to head over to the GitHub, to the FF image loading. But first, we need to download and follow these guidelines to setup this package. So let me go back to the Visual Studio and I'm going to right-click to the solution. Manage NuGet packages and search for FF image loading. I need to download both Xamarin FF image loading and Xamarin FF image loading forms. I'm going to add those two packages to movies, movies, Android and iOS. Once these packages are added, I need to follow these steps to initialize this component. So in my iOS project, I'm going to add the line in the app delegate. So AppDelegate. And let's put that here. Okay, next is Android. I'm going to add this to the main activity. And let's see if we have to do anything else. Okay, I'm going to also copy and paste this. So to the main activity and resolve any references. And to add this to the app delegate. And here as well, I need to resolve my references. And let's just quickly build and run the app to make sure everything still works. Okay, Let's see example how to use this. So in our XAML, I need to add a new namespace for FF image loading. So in our main view, I need to add a new namespace for FF image loading. And instead of our image, I need to use FF image loading cached image. Let's just quickly clean up the XAML code. And as you can see, for source, we have to use URL of our image. So this placeholder PNG is not good anymore. So this place holder PNG, we are going to use it for loading place holder. And for our source. We need to buy to something that will have image, image, URL. So at the moment, or our items are collection of strings. And this is not enough anymore. Instead, we need to add a new class to represent, to represent our movie data. I'm going to create new, new movie data class. So it will have two properties. First property. First property is for title, and second property will be image URL. Let's create our constructor for this and use this instead of our string in our observable collection. Going to feel calm. Okay, let's try to use that now. So instead of drink items, I'm going to have movie data. And here I need to create new movie data. We title and poster URL to convert this to observable collection of data as well. Okay, let's now try to run our app to see if this works. And I am missing a proper biding for title. So instead of moving the data, I need to bind this to title. This looks good for now. One last thing I'm going to do here is still request image with higher resolution. So I can do that by going to the main view model and in, in my and change the poster property. So if you remember, the image URL was ending with ASX 300 and 300 in that case was image width. We are going to replace that width of 300. We let say image of 600. So I need to replace S6. S6 600. Okay, let's see if that works. Yeah, that's all Zhi Shu images are now have a better quality. 34. Search for Movies and Empty View: The last two things we are going to do in this app is to implement search functionality and also add an empty view to our collection view. Let's start first with the search bar. In order to place another control in our content page content, I need to wrap all of this with a stack layout. Let's just as a bit of margin to this. And I'm going to drop the whole collection view around it. Now, I can add search bar control. And it's text I'm going to bind to let's say search term. And also on search command. I'm going to bind this to perform search command. If we run this now, the search bar should be available on the top of our screen. Yep, here this Let's add new properties to the main view model. First one is search term, and the second one is perform search command. So this is I command, perform search command. Let's implement this. So we want a new command. And this command, we are going to perform async call to our movie data. So I'm going to await this and call the get data here hungering to remove void and add task. Since this is really correct way to implement our async methods. And I don't need this. It's not a good idea to perform on async call inside the constructor. Instead of that, we will use our search bar to trigger movie data fetching. Also, I'm going to remove this hard-coded string and use search term provided by the search bar. Let's see the results. Okay? Now this is empty since we haven't search for anything. But if I search for, let's say our interests, I get the results. Let's also implement our empty view. So now this view is empty. But we can change that to implement inside collectionView. Empty queue. Those are some time I have already prepared this. So created a stack layout with image and label, where it says enter your search term above. One final look to see how this looks on Android. And we are more or less done with this app. The app also looks great on Android. 35. Section Introduction: In this section, we'll continue to build the features of the movie step. We'll start by organizing the project files. So you have a good foundation to build new features. Then you're going to learn how to implement a custom transition to the movie detail screen. We'll implement our new control call expander and see how to add this small animation when we click on the button. And lastly, we'll save the information that we marked a movie as a favorite, a local database. So the next time we navigate to the same movie, the movie will be marked as favorite. This will be achieved using generics. So you can have a single class for assessing database tables. We'll be covering some advanced stuff here. So if you have any questions, please let me know. Okay. We have a lot of work to do, so let's get started. 36. Lets Setup MVVM from Scratch: We'll kick off this section by organizing the movies project. So we can have a good foundation to continue to build features on top of the existing. The first step, which I have already done is that I split the application files into three main folders. So just as in the last project, we have three top folders, application common and modules. In application you have up at the XAML and assembly info. In common. I have put our models slightly change here is that I have renamed these two classes. So now the root class is named list of movies, and the search class is renamed to the base movie information. Other folder we have here is network will slightly change, is in the class which was previously named constants. I have renamed it to API constants just to better reflect its main purpose. And the last folder is modules. We have our main screen here and our main view, the XAML and main view model that we also reuse subclasses we have used in previous sections. So I'll head over to the course. And here you can see we have our resources section. And here we have MVVM code, snippets resources. So if I click on this link, I can find all the necessary snippets for MVVM. So the first snippet is for dependency injection. So I'll just copy that into the XAML dot cs. And I need to install artifact package. I'm also missing some references, so let's just resolve that out. And system reflection. And I also will need navigation service. So that's also available in this code snippets. Let's just, let's just take all of this and create a new folder for navigation. And add a new class for navigation service. Let's just add the missing colors. And also I need base view model in order to have new model to ViewModel navigation. So we also have the Bayesian model implementation here. Let's add a new folder called Bayes and put a new class based view model. Let's just resolve the missing reference and try to build this. And Bill is successful. The reason I'm going through these steps is to show you how easy is to set up our new MVVM structure. So you just copy and paste the code I have provided you results on references and you are more or less done. You can continue to build your features. One final note is about the Bayesian model. So I have added a new method called set property. With this method, we update the backing field of the property and raise on property changed event so that the UI can be updated. 37. Update Collection View to Card Layout: Okay, the final step we are going to perform is to just slightly changed the main view. So I'm going to add a title to the main view. I need a label for title. I'm going to call this view Movie Database. Font size. It's going to be title font attributes. Let's have a bolt and just introduce small padding. The other change I am going to make is to slightly change how the collection view items look. So I'm going to wrap our item, D naught frame. No padding. I'll add some corner radius, let's say 50. Then I'm going to add some margin. So then 20, 10, 0. And for horizontal option. And we are going to display that in center. And we are going to clip the content of this frame. Let's just wrap up our greed. In frame. We can remove this horizontal option. And in order to frame actually takes margin into consideration, I need to wrap it inside of stack layout. So that's the final step. Let's just quickly format the XAML file and now build the app. Okay, We have our title here, Movie Database. And if I try to look for movie, you can see that now we have Card layout achieved. This concludes this lecture, and in the next lecture, we are going to navigate to the Movie Details view. Just a small correction here. I can remove the navigation bar. So navigation page, as the negation bar set to false, to move up the title and the content. 38. Navigate to the Movie Details View: Okay, We have our list of movies results. But what we want to do is store when we click on our movie, navigate to the next view to show additional information about every movie. I'm going to create one new folder, call it Movie Details. And inside this folder, I'm going to create two classes. So one class will be Movie Details view model. We can remove the default constructor, and this can inherit from base view model. And the second class is our view. So let's create new content page. Call it movie titles, film. And we can inject Movie Data, View Model and set it as binding context. Let me just format this file a little bit at just small label for now and set this to movie details. Now, what we need to do is to go to the main view, not XAML, and specify that once we click on our collection item that we want to navigate to the next view. So our collection view will have selection mode single. So we just want to select single item at once. And we need to bind the selected item to our new property. Let's call this new property selected and respond to the Select selection changed command. So we will also need to introduce a new command. Let's call this command movie trained command. Okay, let's go to the main view model. Like I mentioned, I need two new properties. So the first property is for selected more. We need to reference the Bayesian model here. So we can have access to the set property methods, which will automatically update the UI once the property is changed. And the next thing we need is our new command to navigate to the next view. And recall this command, movie changed command. So in our gut will call new command to go to the movie details. So since we will be using navigation service, we need async await here. And let's call this new method, go to Details and generate this method. You have extra semicolon here. At the end. Let's just rename this to fixed typo. And in order to navigate to the movie details, I need a new field for navigation service. I need this dependency. So my navigation service, navigation service. And let's initialize our private field with the navigation service. Now, let's just add the route to the movie details in our navigation service. So if I want to navigate to the movie details view model, then navigation service should show movie detailed view. Okay? And in our movie details, we can now call a weight navigation service and push to the Movie Details view model. And this needs to be a sink. In order to remove the error with about the weight. What we will need to pass to the movie details. Viewmodel is the selected the morning. So we will pass the Select movie so we can show additional information about the selected movie. Okay, let's just run the app to see if this works. We have one error. So here we need to inject main view model to, to automatically resolve all necessary dependencies. That's actually great. So we don't need to resolve them. Resolve them manually. If we now try to build and run the app, we can see the Movie Details view. The last thing we want to do is to just once we navigate to the navigation service, we want to set the selected movie back to null. So it wants to unselect the selected item. And since this will update the UI and trigger the movie changed command, we need to check at the beginning of this method whether or not we have selected movie. So if selected movie is equal to null, then we just ignore the change. 39. Fetch Data on Navigation: In this lecture, we are going to continue to build the functionality of the movie details. As you can see, when we navigate to the digital sphere model, we also send the selected movie property. So let's go to the movie details, ViewModel, and override initial async in order to store this parameter into a new property. So I'm going to define this new property list. Let's just call it movie data. And this property movie data is going to be populated with the perimeter. And let's just cast the object into data. Okay, One quick look at the movie data. So as you can see, we currently have just titled and image URL in this class. What I would like to do is to pass some additional information. This initial information will come from the base movie information. So I would also like to pass the year in order to display year on the view and also this IMDB ID. This property is used in order to query additional information about the movie. So let's just first at these two properties to the movie data. And we can extend this constructor in order to receive these two new properties. So we will receive year and also IMDB ID. Let's just make it uppercase. So here is equal to a year and IMDB ID is equal to IMDB ID. And we need to slightly change how we initialize our movie data. So we need to pass year and we need to pass IMDB ID. Let's go over to the IMDB API website to see how to use IMDB ID to fetch the additional information about the movie. As you can see, if we have some IMDB ID, we can pass that to the query that has this i parameter. Then we can select the plot size, so it can be full or short. And if we select the response in JSON, we will get the following JSON. So in this window I have queried the same endpoint like we did before. Let's navigate to the JSON utils this time because the size we have previously used has died. Meanwhile. So if we enter the JSON text here and submit that, we will get the following C-sharp classes. I can just copy and paste this and go back to the Visual Studio. And I can copy that to the models.py CS and written, rename this to full movie information. Okay, this file becomes a little bit messy. So what I'm going to do is to split all these classes into separate files in order to have better overview of our models. So let me just quickly do that. Okay, let's now go to the movie details ViewModel. And let's try to fetch the full moody information class. For a start, I need two new properties. So 11 is network service, the other one is navigation service. So in the next lecture, we are going to navigate back to the main view model. Let me just quickly create a constructor for this new properties. So generic constructor. And let's say we want to generate for navigation service and network service and click Okay. So now in our initialized async method, we want to call the network service get async and we want to get full information. So we are missing async. And we don't need this anymore. But what we need is a URL to the full moon information. We are going to get that URL, same as before. So true API constants. But in AP constants, we need a new method to return this movie based on IMDB ID. So let me just create new method, public static, string, get movie by ID. And we are going to pass the IMDB ID. Let me just copy this URL, and I'm going to paste that here. So instead of hard-coded ID, I'm going to use IMDB ID. Okay, well let's go back to the movie details view model. And now we can call API constants. Get movie by ID. And our ID, we can get that from movie data that IMDB. We also need to store somewhere. This information we get. And for that, I'm going to create a new property called moving information and store this data we get from get async into movie information. So now we have all the information we want to display in our movie details view. And what we need to do is to actually implement the UI part. 40. Implement the Movie Details View - Part 1: What we are going to achieve by the end of this lecture is implement the small details view soil have this big image, will have this close button. And once we click on this button, we will navigate to the main view. And we will also display information in the expander control and also the cast in the expanded control. The last feature is the mark S favorite button. So once we click on it, we will change the state into his favorite. And on transition will have this animation. So let's implement this now. Let's navigate to the Movie Details view and start implementing features. Oops, it looks like we have a crash. So this is due to, we are using HTTP, we need to use HTTP S instead. Okay, That was quick fix. Let's try one on time. And now we can navigate it to the movie details. Let's start implementing the movie digital sphere. The first thing I want to show is the movie image. For that, I'm going to use FF image loading library and create new cached image. So instead of label, I'm going to wrap everything into scroll view. We were to call option and expand. And I'm going to add white background color. Now let's add our view. So that's FF. Image loading. Cached image source is we're going to bind that to the to the movie data dot image URL. For aspect, we are going to use Aspect Fill. And let's request height of 500. So the next thing I want to do is to have the close button, which we'll navigate back to the main view. And that button will be shown on top of D cached image. So the easiest way to do this is to have our grid and place both elements inside the same grid. So that will going to be image button. Source is closed dot PNG. For background color. I'm just going to use white. And let's bind that to the go back command. I'm going to rub this image button inside frame element to get the circle button. So we can see we have the button. Now. Let's go and implement the go back command. So this is just going to be a simple command which will pop the current page. Finally, to resolve some references. And let's see if this works now. Okay, it works. Let's continue to build the movie details view. The next thing I want to show is the movie title. And since ScrollView can have only one main content, I will wrap this parroting into a stack layout. And this will now show the title of the movie. I can also remove this navigation bar since I have a way to navigate back to the main view. So navigation page has navigation bar is equal to false. Okay, let me just quickly re-size Visual Studio so we can see how the viewer looks like in real-time below the title. By also want to show year in which the movie was released. So I need another label and bind label. The movie data year. So let's bind that to the movie data here. And I'm going to use string format to show the year text before the actual year. So I'm going to have year. And then I will display the actual year. Let me just introduce some padding. So let's say 2800. And text color is going to be great. Okay, we have our year as well. The next thing we will introduce is the image button. When we click on it, it will mark movie as favorite. So let me just quickly format this selection. And let's move on. So again, I'm going to use grid to show two elements within the same horizontal position. So I'm going to wrap this label inside it and add another image button. Let's name it as Image button. The source we are going to bind to the new property we are going to define shortly. And we are going to call this property is favorite. Let me just quickly style the button and bind the click event to the command, which we will name favorite meant. And let's add these two new property. So we need property is favorite, favorite command. So the first thing we need is a new property called is favorite. And the second thing we need is the command for the new button. So I have prepared this favorite command and the only purpose of it is to change the state of D is favorite. So it'll set it higher to true or false based on the previous is ferrets state. Now the source is expected to have some kind of image, image source, but we are providing the Boolean, so we need another converter to convert the bowl to image. Let's add another folder for converters. Converters. And add one new converter. I'm going to call it bolt to favorite image converter. It's going to implement AI converter. And Let's implement this interface. Fix the indentation, can expand Visual Studio now, resolve missing references. And what this ball2 favorite image converter does is that if the value is true, we are returning for heart that PNG, otherwise we are returning empty heart PNG. Let's use this converter in the movie details you. So the first thing I need to do is to reference this new folder, this new namespace. Then what I need to do is to add this converter to the resources dictionary of this view. So I have included both molto favorite image converter. The key to access it is molto favorite. And I can use it in the source property of our image button. So I'll add this converter, molto favorite. And now we see the button. If we click on it, it changes the state. Next, let's add a small animation to it. So once we click on it, we will trigger a new event Image button. Underscore clicked. And what we are going to do in the event handler is make image a little bit bigger. We're going to animate it during the 200 seconds. After that, we are going to scale it back to the original size. So you can see this small animation. 41. Implement the Movie Details View - Part 2: The last two information we want to show is the plot and cast. And for that, we are going to use the expanded control. The control is our new control introduced in Xamarin Forms 4.6. And what it does, it provides unexplainable container to host any content. It has two main sections. The first one is header. And once we click on the header, it expands and show the actual content. If we click again on the header, the content collapses. At the time of recording this, the expanded control is steer experimental, and I need to set it using the expander experimental flag. So in AppDelegate and also in the main activity, I need to set this experimental flag in order to use the expander. Okay, let's use this control expander. And the first thing we're going to define is the header. The header is going to be our simple label with the text block. And let's have it. Click to expand. We're just going to add some padding to make it bold and font size. It can be medium. The actual content. It's going to be another label and text is going to be binded to the movie. Deformation dot plot. Let's also introduce some padding and have the great texts color. Let's see the result. If we click on the plot, we get the plot. We can click again to collapse the content. And the last thing is another expander control, which will show movie actors. So we can click on the cast. It'll show all the actors. 42. Custom Transition on Navigation: To implement the custom transition on navigation, I'm going to use the plugin Xamarin and that plugin that shared transitions. So with this plugin, we can activate shared element transition between pages in Xamarin Forms. So if you have an image on one page and we want to navigate to other, then we can use this beautiful animation. The first step is to install this plugin. So mentioning your packages. And let's type shared transitions. And install. This plugin comes with very detailed implementation. So I'm going to follow this documentation to implement the transition. Nor is it's not that complicated. Just fewer steps and we are done. So the first step, what we have to do is in our app, the XAML dot cs, change the type of the navigation page. At the moment, we are using navigation page from Xamarin Forms, but we have to change this to shared transition navigation page. We just resolve this. And here we will initialize a new instance of shared transition navigation page. Next, let's go to the source of our transition to our main view and implement the necessary changes. The first step is to reference the shared positions plugging. Then we need to assign a unique ID to the transition selected group. I'm going to define a new property shortly called selected movie ID, which this will be IMDB ID. So we have i unique transition ID. The element which is the source element of our animation is the FF image loading cached the image. We're recurrently display the image URL. So few additional changes need to be done here. So we need some common transition name. I'm going to name this movie image. And the transition group. I'm going to bind this as well to the IMDB ID. Okay, in the ViewModel, we need to specify the property for the selected movie ID. And once we are ready to go to the movie details, we need to initialize it. So in this case, selected movie ID is going to be selected movie IMDB ID. Okay? These were the steps we had to add to the movie that XAML. We also need to add some properties to the movie titles view. And we are done. I need to specify the shared positions namespace here as well. And at the transition name to these cached image. Let's see how this looks like. As you can see, the animation works smoothly. 43. Generic Repository Pattern: In this lecture, we'll talk about generic repository pattern. What these repository part on. Simply put, our repository pattern is a class that separates business logic from the database. So if you need to add, Remove, update, or select database items. This is done through this class. And generic repository pattern is our repository that can work with multiple classes. You write one code and use it to manipulate multiple tables. The only requirement we have is that the class we want to store in the database has to conform to the database item interface. So here you can see we have methods to get one item by ID. We can delete the item. We can get all items from our particular table, or we can save changes to the item. The database item interface I mentioned a minute ago has only one property ID, and it serves to get a single item from the database based on the ID. So let's head over to the Visual Studio and see how the repository pattern is actually implemented. Here you can see the implementation of the repository pattern. The main field is the database field. This is the SQLite async connection to the database. We use this fill in all of our methods. In get by ID. We query this connection to retrieve the table and get a single item where ID of that item is equal to the, uh, provided by the next day, delete async, removes an item from the database, get all async returns all items from the table. And lastly, we have save Async. This method updates the item if it has an ID, which mean that it already exists, otherwise, it inserts, it creates a brand new item. If we take a look at the database constants class, we will see that in the background. We use SQL light. In this class, I have put the database file name constant, and also some flags which tell us in which way the SQL connection is open to the database. Finally, we have this database bad property. This tell us where the database file is stored on our mobile device. So we will use local application data folder. One important note is that we need to install the SQLite net PLC package. Let me just show you that. So we need to SQLite net PCL package author is SQLite net. So we need this package in order to use all these flags and classes. 44. Save Data to Local Database: In this lecture, you will see how to save the information that we mark movie or show as favorite. So the next time we get to the same movie, this, this heart will be filled, which will mean that the movie was previously marked as favorite. The class, I want to store the information that the movie was marked as favorites is the full movie information. So in order to use full movie information, we with my repository class, first step is to go to the full movie information and this class needs to implement AI database item. The only requirement is that this class has to have the ID property. So we will do that here. And since we are here, we are going to use this property to mark that as a primary key. So we go, we're going to mark it as primary key. And we want to auto increment this field every time we create new item in our table. The other important note is that SQLite doesn't know how to save the alleles in the database. So it only works with more primitive types. In this case, ratings will be ignored. So we don't store ratings, which is a list of rating in our table. Okay? The next step is to go to the app dot XAML dot cs and register the repository type to work with for movie information. So we will need to register type repository that outer fuck knows. It needs to resolve repository with the full movie information. When we request the repository with full movie information, which means when I request I repository for movie information, it will resolve it to repository full information. Okay. I need to inject this property. So I need a repository for information, for moving information. And assign that to the information repository. Okay, let's use this repository to save information that the movie was marked as favorite in our method set movie favorite. What I'm going to do is I will use Movie information. And here I need another property for his favorite. Let me just go to for more information and at another property for his favorite. So when we click on the favorite command and change the favorite, then we will also update is favorite property with the same information. And the last step is to use this repository and save changes to the movie information. We also need to wait since this is on async method. Okay? And the last thing we want to do is when we navigate to the screen, we want to restore that information whether or not movie was marked as favorite. So first, what I'm going to do is store called the repository to get all items. And I want to select first or default item. For this, I need to use link which satisfies, satisfies the condition of IMDB ID is equal to movie information, IMDB ID. If this kind of item is not null, then I'm going to update movie information. Dot ID with the DB for ID. I will set is favorite, 0 dB info dot is favorite. Okay, let's preview the changes. So let's say I like the Train Your Dragon movie. I'm going to mark it as favorite. Then when I go back and go again to the same screen, the movie will be marked as favorites. If I go on this, you can see it's not marked as favorites. But if I marked as favorite, then on navigation it will be marked as favorites.