Xamarin on Steroids: Xamarin Forms Shell and MVVM | Kristijan Kralj | Skillshare

Playback Speed

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

Xamarin on Steroids: Xamarin Forms Shell 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

43 Lessons (4h 3m)
    • 1. Course Overview

    • 2. What is Xamarin.Forms Shell

    • 3. Create New Project

    • 4. Define the Initial Layout of the App

    • 5. Build the Side Menu

    • 6. Style the Side Menu

    • 7. Build the Tab Bar Using Shell

    • 8. Tip 1: Use Code Snippets for Faster Development

    • 9. Dependency Injection Using Autofac

    • 10. Tip 2: Reuse Styles With Resource Dictionaries

    • 11. Working With Charts in Xamarin.Forms

    • 12. Build the Assets Collection

    • 13. Build the Latest Transactions Collection

    • 14. Wallet View Final Touches

    • 15. Build the Transactions View

    • 16. Populate List With Data

    • 17. Navigation in Xamarin.Forms Shell

    • 18. Generic Shell Navigation

    • 19. Navigation With Parameters

    • 20. Radio Buttons in Xamarin.Forms

    • 21. Radio Button - Xamarin.Forms 5 Update

    • 22. Implement the Add Transactions View

    • 23. Validation Rules

    • 24. Validate Amount Entry

    • 25. Generic Repository Pattern

    • 26. Save Data to the Database

    • 27. Load Data from the Database

    • 28. Update Existing Data

    • 29. Override Back Button Behavior Using Shell

    • 30. Generic Network Service

    • 31. Get Data From the Crypto API

    • 32. Calculate Data for the Assets View

    • 33. Implement the Assets View

    • 34. Implement the Loading View

    • 35. Introduce the Login Flow

    • 36. Update Navigation Service to Change Between Flows

    • 37. Implement the Onboarding View

    • 38. Navigate to the Register View

    • 39. Implement the Register View

    • 40. Register Functionality

    • 41. Login View Implementation

    • 42. Update to Xamarin.Forms 5

    • 43. Course Recap

  • --
  • 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.





About This Class

Build Native iOS and Android Mobile Apps in Less Time Using the Deadly Xamarin Forms Shell + MVVM Combination


Do you know what's the most important currency in the world?

And no, it's no bitcoin.

It's time.

Once you spend it, there is no way to get it back.

Do you want to know how to build a native Android and iOS app at the same time?

By using the Xamarin Forms framework.

What is the Xamarin Forms framework?

It is a free cross-platform framework for building native mobile applications on Windows or macOS. You can develop both iOS and Android native apps at the same time. Think about it! You write one code, but you can run the app on both the iOS platform and on the Android platform.

The output from the Xamarin SDK is the fully native app.

But wait, it gets even better...

Do you know that you can even speed up your development with Xamarin Forms?

Yes, it's possible. Just use Xamarin Forms Shell.

Shell is a framework you can use to build side menus and tab bar pages quicker in Xamarin Forms.

It provides you with a simple code syntax for building the above-mentioned features. So that you don't waste your time on those features that are so common to mobile apps. And focus instead on app-specific functionality.

In this course, I'm going to show you how to build a crypto wallet mobile app.

I'll also share with you some tips I have learned over the years developing apps:

  • How to use the MVVM with the Shell, to separate the UI from the business logic

  • How to reuse common generic classes across multiple projects

  • How to use resource dictionaries to reuse your design

If you are a beginner developer in Xamarin Forms, then this course is not the right fit for you. But if you are already familiar with the Xamarin platform and want to learn advanced topics, so you can become a better developer, then you are in the right place.

You probably know this, but in order to start with this course, you don't even need a Mac computer. You only need Visual Studio, and it has free community editions. You can test all your code changes on the Android emulator (however, if you want to test the iOS app, you need to have a Mac computer).

After you finish the "Xamarin on Steroids: Xamarin Forms Shell and MVVM" course, you will know how to build beautiful cross-platform Xamarin Forms apps.

Meet Your Teacher

Hello, I'm Kristijan.

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
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.


1. Course Overview: Hi. Let's just quickly go over what you're going to learn throughout this course. We will build the cryptocurrency wallet app where you can enter your transactions and track your crypto asset portfolio value. We start with the basics of the Xamarin Forms shell. And right from the start, you will learn how to build this side menu quickly. This menu is also known as the flyout menu. Then we move on to building the colored top bar page. This is where Xamarin Forms shell really helps you out. You will see how to build charts in Xamarin Forms and reuse different XAML styles to make your development faster. You will learn navigation in shell, how to add custom validations to the text fields and work with the database in a generic way. Finally, you will see how to add onboarding and login flow to your shell App. This is not supported out of the box in the shell itself. So I'm going to teach you how to do that. At the end of this course, you have access to some useful resources. The full source code of the app, reusable code snippets you can copy and paste to your app ebook with C sharp end summary, interview questions and guide on how to accelerate your mobile app development. Okay, we have a lot of work to do. So if you are excited as much as I am, then let's get started. 2. What is Xamarin.Forms Shell: In this lecture, I'm going to give you a quick overview of Xamarin Forms shell. My name is Christian, and this is me. Just chilling on this picture. Let's start by giving an overview of what is a summary forums shell. Xamarin Forms shell is an application template that has just one goal. And that goal is to reduce the complexity and time needed to build the Xamarin Forms mobile apps. What it does, it provides simple way to build common application layouts, such as top bars and side menus. You can get this almost of the box and you also have access to your base navigation. You can override back button behavior you have on integrating, Search, handler, etc. When you rebase negation, this means that you can quickly define routes between different screens and execute that navigation. Here you can see the side menu we are going to build using Xamarin Forms shell. This kind of menu can be built in approximately ten minutes. If you have all the design gray, and you will agree that this is really fast. Similar. You can implement the top bars like on this video in 10 to 15 minutes. When you click on a tab bar item, the tugboat color also changes. You're going to see how to accomplish this in the next section. Let me introduce you the upshot some XAML file. This is the central file in the shell template. Why is this important? Well, I'm glad you asked. This file lets you define your main app layout. Side menu stub bars, navigation routes, and optionally styles for all those components. In your project. You can also have multiple shell files. If your application is bigger and you want to divide it into smaller section on the image here you can see an example of the shell file. We use flyout item to define the side menu item and tub for the bars. Even though the summary form shell has no built-in MVVM support, meaning that there is no way to automatically inject view models into the views. We will still use the combination of shell and MVVM to build the fully functional crypto wallet app. I'm going to guide you step-by-step on how to use the MVVM inside the Xamarin Forms shell. This was an overview of the Xamarin Forms shell. And we best learn new technologies by trying out and coding apps. So let's start with some coding. Shall we? 3. Create New Project: We start by creating a new project. And in our project templates, I'm going to choose the shell Forms app, since this comes with some classes we are going to use throughout the project. Let's click Next. I'm going to name the app cryptoclidids, which is short for crypto wallet. Click Next. I won't use Git for version control, but I encourage you to use good for your projects. The first thing, after I create a new project, I always like to update the NuGet packages. As you can see, both Xamarin Essentials and Xamarin Forms can be updated throughout the solution. So right-click on the solution and Update NuGet packages. If we run this template which will get sample to-do app. And right from the start, you can start exploring the app template. And main file here is obviously up Sheldon XAML. So inside this file, you defined all your, all your styles and all your navigation and the layout of the app. So this is basic to do app. It has two tabs, browse and about. And we can add some items. Now, what I'm going to do is to clean up this template a little bit. Since it contains a lot of files we currently don't need and we won't be using. So let me just start by deleting all this stuff from the app shell. Xaml, also from the cone behind. Okay, this is empty, so nothing to delete here. And let's delete these dependency service. As you can see, the main page of our app is the app shell. We pass the new instance of the app shell to the main page and then App Shell takes over. Also, I'm going to delete all these folders since it contains stuff we won't be, won't be using. And also clear this using. If we now try to run the app, the app itself is empty and is we're just going to show the black screen. So at the moment, we don't present anything, but we are going to change that in the next lecture. 4. Define the Initial Layout of the App: Before we move on and build the side menu, Let's just quickly set up the layout of the app. I'm going to place all these related files into a new folder called application. So let me just quickly do that. Also, what I am going to do is to add two new folders. One is going to be named column. This will contain all Common Files we are going to use throughout the project. So navigation services, database stuff, controls, styles and things like that. And finally, I'm going to have the third folder in route, which I'm going to call modules. And in this module, we are going to put our views and our view models. So this is going to be the MVVM styled app. We are going to use MVVM in this project, since this is really the best architecture for Xamarin Forms. And what we will also be needing is some images and icons. So let me just quickly import that as well to boat cryptoclidid, Android and iOS. I see you soon. How important the icons for the iOS or icons we'll be using throughout the project. And also did the same for the Android version. So you can find these acids attached to this lecture. The final step is to add some views we are going to use in building the side menu. So within the modules folder, I'm going to add three new screens. First one is going to be wallet. So this is going to be wallet view. Next row is for assets. So let's add the Assets folder and the assets view. So right-click, Add new file, content page XAML with code behind glass. And we will call this assets view. So this rule will contain the collection of assets we currently possess in our wallet. And I forgot I mentioned this molecule. This is the main view, the portfolio view, which user sees at the start of the app. And lastly, third module is for our transactions. So we will have overview of all transactions, deposited, rejections, and redrawn transactions that will be placed within the Tab Bar page. So let's add those views as well. New file. First one is just transactions. You next one is for the deposit intersections. So new content page, Let's call it deposited transactions here. And the third one is for redrawn transactions. We are going to call this redrawn transactions you. Okay, we have our views now. Let's see how to build the side menu. 5. Build the Side Menu: Okay, let's build the side menu in Xamarin Forms shell. Side menu is also known as the flyout menu. And we use the shell that XAML to the fine, the flyout menu. Like I mentioned before, up shallow XAML is our central place for defining up wide navigation and general layout. And you can do that, do that stuff pretty, pretty quickly. So let's build the menu. The menu contains items which are known as the flyout items. It has several different properties. One of the most important property is route for navigation through our dApp, and we will see later how to use this. The other important option is flyout display options. So every flyout item can have single or multiple items. If we say that we want to display multiple items, then we will display all items we did not menu item. For now, flyout item takes Shell Content. So this is the view it's going to be presented once we click on the, on the menu item. So let's define title. First. We are going to present port folio. And this is going to take the content template, that is View, which is going to be presented. In our case, this is the wallet view. This swot comes from the namespace I have defined here above. So if we build the app, we should already see this wallet you. So yeah, we can see the wallet view and the side. Side. So this is, well, it comes from the volatile. I have put some dummy label text so that we can see different views as they appear on the screen. Okay, Let's continue to build the side menu. Next. I'm going to add the flyout item for the assets for you. So again, I define the Shell Content title is assets. And content template. That is, the view we want to present in this case is going to be the assets view. And let's build the third item. This is going to be four transactions. So our shell content has title. And content template is the transactions. Transactions if you. We are live reload the app using the hot reload. We can see that we have the side menu and we can access different views within the app. We currently have. One final thing I want to show you is that this fly out menu can have also menu item if we want to perform some custom, some custom action. So this flyout item takes us to a particular view. But Menu item, this performs some, some action. So if we want to have the logout option, because specify the command we want to perform when this menu item is tapped. So for now, we will perform the sign out command. And this sign out command. This Crump comes from the binding context of the shell dot XAML CSS. So what we can do is to define the up shell ViewModel. So and signed binding context to the new app shell model. Let me just change the namespace or the upshot of your model. And like I mentioned, we need our command within the app shell view model to perform the actual Logout. So we can have the command named sign l command. Let's just resolve all missing using. And here we can have some, some custom operation. Let's say we want to display some kind of alert. So Shell dot current dot display alert gives us access to the alert message. So let's say title is going to be to do since we obviously want to change this to perform the actual logout. But we are going to do that later in the course. For now just let's say you have been logged out. Okay? And let's see how this works. So if we click on the Logout, the alert appears. 6. Style the Side Menu: Okay, now let's see how to style the flyout menu. So we can style the flyout menu by changing the background color. So we can use fly-out background color property of the shell to change the background color. But again also change the background and have the image the Flyout, the wrong color. I'm going to select light, slate gray. And let's see how this looks like. As you can see now we have these slightly gray background color. Next, what we can do is to define flyout header, which will move these items down. Let's add the header. We use shell flyout header. To define the header. One thing I am going to do right here is to define our separate control for the flower header so that I don't put everything in one file. Otherwise, this file will get too big and it's easier to have smaller files. So let me just create a new control. We will put that in the controls folder. So let's create a new control called flyout header. So this is our content view with cone behind class. I'm going to name this play out. And this will also have the background color of light, slate gray. And we want to put some height request to 240. And let's add the content. The content is going to be image with aspect, Let's say Aspect Fill. We'll put some margins. And source is going to be grove that PNG. Okay, back to Sheldon XAML and less defined the controls namespace. So this is the controls namespace and add the Flyout killer. And while we have the image as well. One final trick we are going to do is to define some cool effects. To this header. We want to have flyout header behavior set to collapse on scroll. So that we collapse the image when we scroll down to the flyout menu. So fly out vertical scroll, scroll mode is enabled. And you can see if we scroll through the fly out menu, that the image is now collapsed. That's all for this lecture. In the next lecture, Let's see how to build the dubbed Bar page. 7. Build the Tab Bar Using Shell: Okay, Let's continue to build the layout of our app. And now what we're going to do is to build Tab Bar page containing the transactions. So first step page is going to have the old transactions you, the second is only going to contain the positive transactions. And the third one is going to contain the withdrawal transactions. In order to build the Tab Bar page. In our app shell XAML, we will use these flyout item. And inside it built the tub double bars. These all markup we are going to use is the top mark-up. It can have icon. So first, tab is all transactions and Python is going to be all top dot PNG. The title is going to be all transactions. And now this Shell Content is wrapped around top mark-up. Let's add one more tab. The stub is for the posted transactions. So icon is going to be deposited underscore tab not being G. Title of our tab is going to be deposited. We need some Shell Content to present. We are going to present the that posted transactions view. Inside this step 1 error here. I need to close this. And I don't need these transactions. Since I have the old transactions title. Now, Let's see how this looks like. So now we have both all transactions and deposited in our flyout menu. If we click on the old transactions, we navigate to the old transaction step. But we can also click on the deposited and see the stub as well. The flyout menu displays bolt oh, transactions and the posttest. Since we have the flout, these options set to as multiple items. If we want to change these as single item and give it a title, transactions, then we will get only one menu item in our flyout menu. Let's see how this looks like. So I will leave it as this. One other property I didn't mentioned, but might be useful to know about it is the Flyout icon property. So every flyout item can have the icon set. I won't be using that. But if you need to use it in your apps, it's useful to know that it's there. And Let's build the third tab. This is going to be for the withdrawal transactions. So the icon is redrawn, tab dot PNG, title is withdrawn. And Shell content we want to display is the redrawn transactions view. And now we have three tab options. In order to style the double bar page differently based on which tab bar is selected, I need to first set the styles for the TBA bars. So we define shale resources and within Shell resources, I'm going to define first style for the old transaction step. This is going to be named based style. And target type is the element type. And I'm just going to define some properties. So we use shell background color to define the background color. Shell dot foreground color to define the foreground color. Shell that title color to define the title color. And when the element is unselected, is going to have this color. One note here is that these hex values of colors are now harder car coded. But later, I'm going to put these values in the resource dictionary. You're going to see that in the next section. Okay? I have the style for the old transactions. And similarly, I can define the style for both the posted and withdrawal transactions type. So I have defined two new styles. One is called the deposit shell. Target type is also element. This is based on the base style. So I take all these defined properties and only change the background color to slightly green color. Final style is for redrawn transactions tab. The only change is background color as well. And now we can use these styles. So all transactions has base style, deposited, has, as you might guess, the Postgres shell style. And withdrawn has the redrawn shell style. And now the color of the tub changes. Once we change the currently active tab. So as you can see, it was pretty easy to build and style this top bar. And this is one of the biggest advantages of using shell is that you can quickly build and style the types. 8. Tip 1: Use Code Snippets for Faster Development: One tip on how to avoid typing the same boilerplate code over and over is to use code snippets. So you have seen this a few lectures before. I have used the snippets to quickly create a new command. So I have type x f dot cmd, and the code automatically expanded. And then I just typed the command and I got this ready code on Mac. You can create your own snippets by going to the Visual Studio. Then Preferences. Then look for code snippets. And here you see you have the different code snippets. I have created two code snippets. One is for creating our new property with a backing field and the other is the command you have just seen. So you can add a new code snippet that going to the ED. And then you fill out all these fields. So for example, of the XF CMD, you can see this is a shortcut I need to type. This is the file group where the shortcut applies. So in my case, this is C sharp, mime is text x C Sharp, and this is just description. And then here in this template text, we insert the template we want to get once we type the XF CMD. So I get public command name, variable, where name is just a string that it's editable. And rest. And just uses this name property similar with the XF. So if we take a look, we have the type and name variables. Type is default object. This is editable as well. And name is just a regular string I have with some defaults, so this is my property. So let's just quickly see how to use the XF prop. So if I expand this, I get this property that has backing field. And it raises on property change using true this set property method of the base ViewModel. And if I want to change my property, everything else is changing as well. So this is how you can speed up your development. And I'm going to post your link how to do that in Windows as well. 9. Dependency Injection Using Autofac: We will use out-of-stock as our dependency injection library. If you're not familiar with the dependency injection, simply if we have, if you have a class that needs some dependencies, like in this case we have a task controller and tasks controller needs high task repository and I lager than dependency injection is a way of providing those classes to the task controller. Here you can see we provide that through the constructor. This is also known as the constructor injection. And what the fuck does is that without a fuck, you register your classes. So for example, your repository and your logger, and out of luck automatically finds these research classes and initializes this class for you. In the resources section of this course, you can find the Xamarin. Xamarin Forms shell code snippets. And here we had the code for registering all classes within the solution. So these codes goes through the whole assembly to the, to the whole project and then registers automatically all them to the artifact. And then you can simply resolve your views, your view models using the container. So I'm going to copy it, copy and paste this, and use it in the app dot XAML dot CSS. We also need to install the artifact library. So right-click on the cryptoclidid project, manage NuGet packages. And let's search and install ultra FAQ. Let's resolve the missing dependencies. So we need out of whack and this is System.out reflection. The main page is still going to be new shell. Let's just quickly see how to use this container. So I can go to the app shell, the XAML dot cs. Here in the app shell constructor. I can type container that resolve. And I need to resolve up shell ViewModel. So this means that out of luck, we'll automatically provide fresh instance of optional ViewModel for me and resolve any dependencies it has at the moment up shall ViewModel doesn't have any dependency. But that will change later and we won't. And as we change up shell ViewModel, we don't need to change this part of the code, which is nice. 10. Tip 2: Reuse Styles With Resource Dictionaries: Time for another tip. Before we move on to building the chart and the volatile itself, what you can do is to define resource dictionary files and then place in that files all the custom colors you use throughout the app so that you don't repeat the value by instead, you have an identifier for this color. So in my example, primarily primary blue is the blue color of the transactions top. And instead of this hex value, what I really would like to do is to use the color from the resource dictionary. In order to do that, I need to get the static resource. And the key is primary blue. I have the same thing in the deposited shell style. I should really use static resource deposited on top. And this value should be static resource. We drowned. So how did this value end up in the shell view? Well, in the app, does XAML. Once we create our resource dictionaries, we need to create anew merge dictionary from all these dictionaries we have in our app. So I need to get the app colors, does zonal resource dictionary by going to the common styles and then AP course XAML. Let's just quickly go through the true, these two dictionaries. The second dictionary is for cell templates. So these are the common cells that we'll be using through out the app. And I want to define these assets, sell in one place and then reuse it multiple times. Nothing special here we have frame and then in the grid, recreate one image which is bound to the symbol. And we have the greed for the rest of the cell. When new feature in the Xamarin Forms 4.7 is that you can bind our text to multiple properties. So you can bind single text, let's say in this example to boat name and symbol. Maybe to present this cell visually. So this is the cell. And we have the symbol image. Then we have the name and symbol label represented with multi binding. And in the next row, we have another multi binding for binding amount and crypto currency symbol. Lasting what we have is in the third column. This is the value of the asset. So this is the dollar value of the asset. We have string format, which formats this into number with two digits. And then we have, we have two other cells defined. So similar. This transaction cell is for this transaction. So this is pretty similar to what we have with the asset cell. And the last cell is the coin cell. This is the cell when we want to add a new transaction in this collection view. So this cell is pretty simple, just has the frame image. So image is bound to the image URL, and label. Label is bound to the name. As you can see In this second resource dictionary, we also use color from the first resource dictionary. So we are using input text color to get the color for the text in the cell. And lastly, we can have custom styles defined for four types. So I have defined some styles for button. And this is this, this is just setting up background, color, font, text, corner, radius, and similar stuff. And also we will be working with the radio button. So you're going to see how to use visual state manager to style radio button differently based on the state. So I will also attach a link to the MSDN Documentation on how you can rethink how you can create your own resource dictionary files in case you need help with that. If you follow along by coding, then these three resource dictionaries will be available. In the resource section of this lecture. You would just need to add them as the merge dictionary. 11. Working With Charts in Xamarin.Forms: Now let's go and build the chart in the wallet view, we are going to use the open source library called micro charts. This is a library for creating cross-platform simple charts. Even though it says this is simple. You can see the targets which can be built using this library. And I think this is pretty amazing. So let's install and use this chart. The first step is to install this package. We need micro charts, boat micro charts, and micro charts forms. Let's add those packages to all our projects. We are going to put that chart in the wallet viewed, not zonal. First, I'm going to delete this dummy, dummy label and start by wrapping the whole content of this view inside the ScrollView. This will have background color of white. Next, let's add the stack layout. With some padding. 0, 20 000. We need to reference the micro charts namespace. So micro charts. And now let's use it. The most important property of the chart view is the property. And we are going to bind that to the portfolio view. And inside our ViewModel, which we currently don't have, but we'll create it soon. We will build this chart and bind to this chart view. Okay, let's add some height of 200 background color. It's going to be white. And add some margins. We need the real model for this. So let's add a new class and call it wallet ViewModel. And what we also need is our base view model. You can find the Bayesian model class in the code snippets provided in the resources section of the course. This is the Bayesian model class we are going to copy and paste in our project. So inside common, Let's add a new folder called base and add the Bayesian model class. And Bayes model, we're going to use the initialized async method or the base view model to initialize our chart view. So in the ViewModel, I'm going to initialize async. And here I'm going to build the chart view. First. What I need is the property of type chart, and we will call it portfolio view. What we need is some data in order to populate the chart. So first, I need to create a new folder for our models. And inside the models, I'm going to create our new class called coin. We are going to present coins value inside the chart view. I have already prepared the class structure of the coin. So each coin has its unique ID, name, symbol. So let's say for Bitcoin, BTC, its price amount, total dollar value. And this is the image URL, and it's unique color for the chart view. Decent property. This comes from the, from the Newton's old Jason. So later, we will be fetching these coins from the rest API. And each coin in the JSON has ID, name, symbol price, and this will be translated to the price symbol name, end I, end coin ID. So what I need is the new Tucson JSON package. And now I can resolve this. Also. This coin will have a list of available assets. So this presents all available coins we can have in our crypto wallet. So we can have Bitcoin, bitcoin cash, Daesh, Ethereum, coin, Monera, ripple, and stellar. This is the coin symbol, also known as the coin ticker. This is the image from our assets and this is the unique color for every coined for representing it in the chart view. Okay, now that we have our modal class, Let's move on and build the class which will. Which will actually be responsible for getting the coins, for presenting them in the volatile new model. I'm going to call this class wallet controller. So what is our controller? This is a class which will have different dependencies and be responsible for getting the right data for representing it in the chart view. In the colon, I'm going to add a new folder called controllers and add a new class. What controller? I'm going to define a new interface. I will add controller. So this is going to be public interface. I call it the controller. And for now, this will only have one method for getting the coins we currently have in our wallet. This is going to be async method. So I'll be using task, which will return the list of points. And we will call this get coins. For now, this is not important, but we will also have one property of this method called force reload. So we will be storing in cash the coins we get from the API. We will do that all in the later sections. And if we want to get a fresh set of coins with new prices, we are going to pass the force reload as true. Okay? Well, controller needs to implement the controller. And for now we're just going to define some dummy data. We will create three coins and return that in this method. So let's return default, assets, collection. But this has to go inside task from result. Let's add these dependencies to the wallet ViewModel. So we need private wallet controller. We'll call this swallowed controller. And generic constructor with controller. We can use the wall controller now to get our assets. So we will call it with a weights, well a control while controller dot get coins. This has to be async method. And we will pass these assets to our new method called Build chart. The data in the chart is represented by chart entries. So first thing we need is our list of chart entries in order to populate the chart view. And now let's iterate through the list and add to the entries. So we will be adding new chart entry. It takes in constructor one value. This will be the amount. So we have item dot dollar value to present in our label. That is chart, label. Next, what we need is the text color. So text color will be white color, but the stakes skier sharp color. So I'm going to create a new variable called white color and assign it from a sky color. Let's parse the white color. So text color is white color. Next, what we need is where you label. Where you label is just simply name of our coin, that is item.name. And lastly, we need the color in the chart for our coin. This will be obtained through the colors collection. And this, we can get this from coin, gets available assets. And we can get the color by parsing the to the eschar color. So we need to find first coin where the symbol is equal to the item dot symbol and use the hex color property. Okay, now to build the chart itself, we have the data now. So we are going to create new donor, new donut chart with entries that we just made. Background color will be white color. And our portfolio view is now equal to the chart. The last thing, what we need is to assign the mining context of the wallet view does donald dot cs to the wallet ViewModel. So binding contexts is equal. Pop dot container. Resolve our wallet view model. And in the on appearing method, we will call the initialized async method of the wallet ViewModel. So our banding context, we will cast that to the voluntary model and called initialized async parameter. It's going to be null for now. We need to await this and put async here. Now let's see what we got. As you can see, the chart is now here. 12. Build the Assets Collection: Let's continue to build our wallet view. Next up is the section with the top three acids. So this is we, our collection view containing 1, 2, or 3 top acids we currently possess in our wallet. I'm going to put that in the stack layout. Let's define background color, white, and where the co-option, feel and expand. First is label. Text for this label is stop acids. Font. Atreus is going to be bolt and text color. We are going to use the static resource input text. So this is the input text color defined in the resource dictionary. And let's add some margin of 2020 000. So 20 on the left and top. So you can see the top Assets labeled. Okay, let's add the collection view. Next. Item source for this collection view is going to be assets, property, selection modes, none, height requests. So depending on whether we have 12 or three coins, we want to adjust the height of the Collection View. So this will be bound to the coins height. And item template for this is already defined in the cell templates. This is going to be OS itself. So this was already predefined and import it. Finally, we don't want to show the vertical scrollbar. Let's add the missing properties. First one is four points, right? And the second one is the observable collection. Our coin model called assets. Let's just quickly in the center, add the logic for calculating the coins height. So after we set this property, and if the value of the asset is null, then we won't be calculating coins height. Otherwise. Goings height is equal to assets.com times height of each cell is going to be 85. Back to the initialized async. So we have the assets variable from the wallet Controller, and let's populate the assets property for the collection of you. So we are going to create a new observable collection of points. Take our assets, but only take 33 coins. Let's build and see the result. Well, we have the top Assets collection. 13. Build the Latest Transactions Collection: Latest transactions collection is pretty similar to the top Assets collection. So again, we have the label to indicate that we are dealing with the latest transactions. And we have the almost the same collection view, just bomb, bound to different properties. So we are using latest transactions to get the item source. And for height requests, we are using transaction site. Item template is transaction sell. One addition to the collection view is the empty, empty view of this collection view. So if we don't have transaction, which is at the moment the case, then we are showing this empty view image. And also we have the no transactions button. Create one. Now transaction. This is bound to the add new transaction command, sending in the wallet ViewModel. So we define the transaction site and also we defined the latest transactions and use latest transaction to calculate the transaction site. And the command to create a new transaction is here. So this is our add new transaction command. We have to do here. So we will be dealing with the navigation. In the next section. For now, I just left this comment. Also, what is new here is the transaction model. So I have added to the models folder, transaction model. It has civil. So this is going symbol. This is the amount for the transaction. This is the dollar value of the transaction. We have transaction date status, so each transaction can, can have either deposited or withdrawn status. And finally, we have the status image source. So this can be with round dot PNG or deposited dot PNG. Okay? What we can do for now is to use the word controller to populate latest transaction. We saw some dummy data. For now, we will be using some dummy data, but later, we will populate this with the real transaction which will create get transactions method. Method also has the force reload parameter, so transactions will be cached. But if we want to refresh the transactions with the Fresh prices, then we will use force reload set to true. Okay, let's implement this method. I have populated this method with some dummy data, like I mentioned before. Later, we will get the real data, but for now, we will just be focusing on getting some data in order to display it and build the wallet view. Okay, back to the wallet ViewModel and our initialized async method. So we can get the transactions now from the voltage controller. We're going to 08. While the controller yet transactions and populate the latest transaction. With the transactions also will have the limitation of maximum of five liters transaction will be shown on the screen. Okay, we have our transactions now. And we are almost done with the volatile. Just need to put some finishing touches on it. Note here that I have added a new class called constants within the application folder. So this is for transaction status, for deposit withdrawal. And also I have extracted, deposited withdrawn images. Here. These constants are used within the get transaction method. So for getting the status and status image source. 14. Wallet View Final Touches: This is the completed wallet view. So let's just quickly go over the changes. Her med this is our other cosmetic changes. The first thing what I did is to add our Refresh View. So this is just simple refresh Fuel with binding to is refreshing, is bound to is refreshing, and command is refresh assets command. The second thing is this balanced label. You can see this is bound to the portfolio value, and we format this as number with two decimal places. Next, charts, we will be only visible if we have some transactions inside our wallet. If we don't, then it doesn't make too much sense to show this chart view. Let's see the changes in the code to support this. So obviously, we need to initialize acid and latest recession. And I have expanded initialized async. So now we are taking the perimeter, caused that to the reload and pass to boat, gets transactions and get coins. This initialized async is used now in the refresh assets command. So once we want to refresh our assets and get fresh prices, then we call initialized async with true. But on the on appearing, we don't do that. We get the cached values. So this is the new property is refreshing. This is the portfolio value of type decimal and has transaction which determines whether the chart view is visible or not, is defined here and calculated from the latest transaction. So if the count is greater than 0, then this will be equal to true portfolio value is calculated in the initialized async. So we sum all of our assets and we add the BZ and is refreshing flags around all these fetching and calculation. The final thing I'm going to show you is how to change the navigation bar core. So this is done through the app shell. If we go to the portfolio, we can reuse the same base style to our flyout item. So we can say style is the state, the resource based style. We can apply the same style to the assets view. So I can paste this style. And you can see the navigation bar is changed. That's all for this section. And the next section is pretty important since it deals with the navigation using the Xamarin Forms shell. 15. Build the Transactions View: Data section view is rather simple. It only has two elements. So the first one is going to be Refresh View will bind the refreshing to is refreshing and command to the refresh transactions command. So we will have an option to refresh our collection. Let's add the collection. So this is the collection view with item source is bound to the transactions. Selection mode. It's going to be single item template. This is where our resource dictionary come in handy once again. So we can reuse the same transaction data template we already have. From the wallet view selected item. We will bind that to the selected cross-section. And selection change command is going to be bound to the transaction selected command. The final piece we need is the toolbar item. So we will have an option to add a new transaction. Let's add toolbar item. So this toolbar items, it's going to have text at order is primary priority 0. And command is going to bind that to, let's say trait command mode, the intersections you and we'd run transactions and x2 are the same. Only the data is going to be different. So what I can do is to quickly copy and paste the content of the XAML file. The final piece we need is our new view called at transaction view. So let's create a new folder at transaction. And defined new file, which is going to be content page called transactions. Transaction. We'll just put some dummy label so we know that we have ended up in this view. 16. Populate List With Data: The next piece we need for our transactions view is ViewModel. Let's go ahead and create transactions ViewModel. And also we will need, I will add controller in order to display the transactions we have. So now in this case you can see how having special class to, to deal with fetching the data comes in handy. Now we can just call the same controller we have used in the voluntary model to get the transactions. If we have put the logic for getting the transaction in the volatile model, now we would have to duplicate the same code which is bed. This transaction model inherits from base view model and create the constructor. And in our override initialized async, we are going to call the controller to populate the list of transactions. So what we can do is to call war transaction is get me from Walla controller. Get transactions. This has to be async. Okay? We need couple of properties. So let's define all of these properties in the ViewModel. Now we can initialize and populate our transactions. So let's first set transactions to be new observable collection of transactions. Then once we get the transactions, let's populate the property with those transactions. And in our transactions view, we need to set the binding context to be equal to the transactions view model. So let's resolve this two transactions view model. And on appearing, what we want is to call the initialized async method of the transactions ViewModel so that we get the data. So our banding context, we will cause that to the transactions ViewModel and then initialize a sink. For now, let's just have it empty. And let's set is refreshing at the start to be true. And once we get and populate, the transaction, we will set navigate is refreshing to false. Let's see the result. So we have all transactions now, what's left to do is to populate both the positive and withdrawn does actions. The logic for getting deposited and we don't transactions is almost the same. So what we can do, store, reuse the transactions you model and set it to binding contexts to both deposit transactions view and redrawn transactions view. The only change we are going to make is that we will pass different parameters to the initialized async based on whether we are using transactions you model in the transaction or the Poston transactions you or we don't transactions you. And this parameter, we'll determine the filter we are going to apply to the transactions we load from the wallet. The controller indeed has actions fuel. This filter will be empty string, meaning that we don't filter by transaction status. And let's set the binding context for the post and transactions view. So it's the same. The only change is that we will use constants. And say, in the positive transactions view, we only want the posted transactions. And if we go to the width round transactions view, in this case, we only want we don't transactions. So let's store and implement the filtering functionality. I need pass string to store. Filter are the start. This will be just empty string. In initialized async. We get that string for from perimeter, so parameter string. And what we can do is to perform Extract Method refactoring on this block of code. And let's call this new method get transactions and filter out the transactions we get from the wall controller in this method. So if the filter is not empty, meaning that we are in the Post-it or windrow does actions view. Then what we would like to do is to take the transactions. Then what we would like to perform some filtering using where from's system link. And we want to get only the transactions which have stat status equal to our filter. We need to cast this back to list. The reason I have put this new method is that we can now reuse the same code for getting and refreshing the transactions property in the refresh transactions command. So once we pull to refresh, we will also perform the same method. What's missing here is that we need to slightly change the data we are getting from the controller. So we only have at the moment the positive transactions. But let's go and also create one. We don't transaction so that we can see our change. One change I'm missing is for setting mining contexts to boat withdrawn and the posting transactions. And now let's see the change. Okay. All transactions now shows all transactions deposited shows only the postcentral sections and we only shows the redrawn transactions. One other change I have missed is that I need to change the source of my image in the wall controller. So instead of transaction deposited image here, I need to set transaction withdrawn image. Now, this is also fine. 17. Navigation in Xamarin.Forms Shell: Like many other things in Xamarin Forms shell, if we want to perform navigation from one screen to another, we need to rely on the up Sheldon XAML or use the shell dot current to perform navigation. So let's see how to do that. First. What we obviously need is route to connect one view with another. Let's say if we want to click on this Add button and then navigate to the portfolio view, what we need is our way to reach the portfolio view is by specifying a route to this portfolio. So in our flyout item, we will defined, let's say the root called port folio. And now what we can do is to reach the wallet view by using the, this, this route. The intersection of view. We have defined this Add button and it has the tray command. Now what we need to do is to defined this trade command. I will rename this to perform negation. And now if we want to go to the portfolio view, we need to call Shell dot current. And it has the go-to async methods to navigate to the portfolio view. So if I click on the ad, we navigate to the portfolio view, to our wallet view. Same thing. What we can do is to navigate, let's say between different tabs. So if we are on all transactions N1 to navigate to the deposited, we need to specify that route. So again, I'm going to add Sheldon XAML. And for the posited, I can define the root deposited and use that route to go to the deposited tub. So if I want to go from all transaction to the posited through the button. If I click on the ad, I go to the deposited. If I click on the ad while I'm in the deposits tab, obviously nothing happens. If I go to the withdrawn tab and click Add. I go to the deposited ten. Okay? But what if I want to navigate to the screen to give you, which is not part of the shell up layout. In my case, as transactions view is not in the flyout items, it's not contained in the tub. And for it, what I can do is I can also defined route in the optional dot XAML those CS into so I can say routing data register route. I can say that when I type as transactions, I want to navigate to the ED transactions. So let's see how this works. So I want to navigate to the transactions. We are in the intersections and click on the Add crashes the app. The reason for this is that if we register the route like this, then this route cannot be only page on the stack. And we defined that with the double slashes. In that case, we need to remove these double slash. And now we are within the add new transaction. The last thing I'm going to do for the pet transactions view is that we currently show the top tabs, but we don't we don't want to show the tug-of-war. And we can set the bar is visible and top bar is not visible anymore. 18. Generic Shell Navigation: Okay, these strings are pretty fun and routing is really easy to use in Xamarin Forms shell. But the strings are also dangerous. Especially it's easy to mistype route. And then when you want to perform some aggregation, nothing happens. That being said, what I did is that I created shell routing service, which performs navigation by using the view model type where you want to navigate to. So instead of you have to type. In this case, as resection, we will refactor this to use the navigation service and just to pass the view model type. For that, we will be needing new ViewModel so that she can remodel. And we will have to change the route just a little bit to make sure distinct works. So we won't be using this string, but instead, we are going to use ViewModel names before we use this shell routing service. Let's just quickly go over the, the implementation. So this shell routing service implements I navigation service. We have three main methods. We have bush, async with perimeter, pop async, and insert as root. So pop async just performs async. Insert as root, navigates to the page and inserts it as root and push. Async adds another view to the navigation stack. We also have the option to pass the parameter. You will see in the next lecture how to work with these parameters. But let's see how to work with navigation service like this. Back to the transactions, your model. And now I can use this navigation service 90 to resolve it and call this navigation service. I also need to pass this as a parameter. So I navigation service, navigation service, and assign this parameter to my local navigation service. And now I can use it instead of this shell dot current. So it's better to use a class like this because then it's easier to perform unit tests for your, for your methods. It's impossible to write unit tests with Shell, Shell dot current. But instead, if we use the navigation service, not push async and we want to push at transaction model. And now the compiler complaints because I need to set this as inheritance of base view model. So negation to transactions, and if I click on the ad, I am on the add new transaction view. Similar thing we can do with our other routes. So this portfolio then becomes wallet view model. And we can easily navigate to wallet ViewModel from our transactions ViewModel. So we can say what you model. But the shell won't. Let me do push the volatile to the stack. And instead, if I want to navigate to the volatile, I need to insert it as the root. 19. Navigation With Parameters: Now let's see how to pass parameter from one view to another. Let's say that we want to pass the ID of the of the selected transaction to the add transaction ViewModel. So while we are navigating using the navigation service, so we push a sink, our transaction ViewModel, and we have an option to pass parameters. So this is fairly simple to do in Shell, especially if you are using this negation service, you just type your parameter. So let's say we have ID and then the actual value. If we have to pass multiple parameters, we separate them with absolute m percent. So similar to what we have on web, where we are entering some URL, we are separating parameters with ampersand. Let's say if I want to pass some kind of name, I can do that as well. Okay. I will just revert these two Porsche sink at transaction view model. What happens in the background of the navigation service is that we are constructing the whole route. So we are taking the root name. And then after route, like I said, similar to two web URLs. So we are adding a question mark, and after that, we are adding our parameters. Now on the receiving side of the, of the navigation. In our ads transactional view, we need to specify the binding contexts. So let's say dot container that resolve. Using out of luck. Let's resolve. At the transaction ViewModel in red to the sea of the ID, we get from the section view model, what we can do is to at query property. And let's say that we want to store in the ID property the ID parameter. So what we need is defined property called id. And in the center, we would get the actual value of the past ID. So what we can do is backing field name ID and say that based on the URI we get, we want to escape datas for string. That is this value. So the id value will be stored to the ID property. Also is our informs shell. We can, instead of having these query property in the view, if we are using MVVM, it's much more useful to have this in the ViewModel, that is, in the transaction ViewModel. Luckily for us, this query property will also working with the binding context of this view. So in our case this was, this would also work with the viewModel. So instead of having this attribute and property in the view, what we can do is to pass that to the ViewModel and also add this property to the view model. Let's just confirm that this works. So I'll put the break-point here and run the app. And if we select any transaction, we should get the value one, which is the case. 20. Radio Buttons in Xamarin.Forms: Radio button control is our new control introduced at Xamarin Forms 4.7 version. And at the time of recording this, in order to use the reading about control, what I first need to ease to enable it using the experimental flex. So this is still in experimental phase. So I'm going to go to the AppDelegate in the triplet that iOS and set this flag by using the Xamarin Forms set flags method. I need to do the same for the Android version. So I'm going to go to the main activity. And just before Xamarin Forms in it, I will set this flag. Now I can use the radio button and on the transaction view, we are going to use the radio button to distinguish whether we are creating our new deposit or we'd round transactions. So just before radio button, we are going to add a label called that is with text transaction type and add some padding. So let's say then 16, then 0, and the inorder to make further changes to the content of this content page, we will wrap everything inside the stack layout. Now we can use the radio button so we can set the text of the radial button to deposit. And one of the most important properties of the radio button is the checked property. It can be true or false. And instead of typing true or false, we are going to bind that to the deposit property, the transaction ViewModel. Let's just add some left margin. And we have our radio button. The second radio button for withdrawn is almost the same. I just need to change the text for to the withdrawn. And this is going to also be bound to the deposit property, but we need the reverse value of the deposit. So in order to do that, we will need are irreversible converter. Let's go and create that converter. So I'm going to add a new folder just for convertors. And go and create a new class called universe converter. This needs to implement value converter. So let's implement the interface. In our Convert method. We will cost to bowl the value we get. And we are going to reverse that and return that value. Now we can use that in the transactions view. First thing is to add the namespace for converters. Converters from the converters namespace at the resources. And in that resources, I'm going to add the universe bulk converter with Tukey equal to inverse. And I can now use that in the withdrawn radio button. So micro inverter is static resource, universe bull converter. And what's important is to set the binding mode to one way. So we won't be updating the deposit property of the viewModel, true this radio button, but instead of this we'll be using. So this one is enough. Finally, let's see how this looks like. Okay, let's go to the transactions. And if we want to add a new transaction, we now see the transaction type. It can be deposit or withdrawn. One, let's think what we will explore is the styling of those radio buttons. So in the cars, in the control custom styles, dot XAML, we have the style for the radio button. So this style targets the radio button. This style uses visual state manager. So this is our way of grouping properties. By visual state, that the radio button can have, radio button can have normal state. This means that it's not selected, that is, it's not checked. And in that case, we apply two properties to that radio button. So we said text color to the dark gray and set the opacity to the 0.8. So the purpose of visual state manager is two. Set is to say, Okay, when the radio button is not checked, meaning it's in normal state, then apply these styles. And if the visual state of the radio button is checked, meaning that we clicked on the radio button. Then we are changing the text color to the primary blue color and set the opacity back to one. Let's just add the property. So we need the bowl is deposit and preview. This visual changes. If the radio button is checked, then it has this blue color. And if it's not checked, then the color is dark gray and it has opacity 0.8. So that was our introduction to the radio button control. Now let's move on and implement the rest of the screen. 21. Radio Button - Xamarin.Forms 5 Update: One small change. If you are using the latest version of Xamarin, Xamarin Forms five is that text property is not available anymore and instead of text, you need to use content. So we have content that says deposit, and we have other radio button that says content withdrawn. The other change. What we need to do if we are using Xamarin Forms five or later, is that instead of normal and is checked, we have different visual states. So now we have unchecked and we need to set properties for that, for that visual state. And the other thing, what we have is simply checked and we set the properties for that as well. 22. Implement the Add Transactions View: Let's move on to the rest of the screen implementation. Next up is the assets collection. We will have the label stating that we should select acid. So this is one of the cryptocurrencies we can have within the application. So when I said asset, I mean that we can select our cryptocurrency at some padding. So then, then, then, then 0. And now let's add the collection view for our S. So item source is going to come from the property called available assets. I times splay out, we are going to have this horizontal list. Selection mode is single. Height is going to be limited to the 100 selected item. We will bind that to the selected coin property. And the item template that is the look of one item. In our collection view. We will use the static resource itself. So again, this comes from the cell templates. And here we have the coin cell. So we have frame. And within that frame, we put the image of the cryptocurrency and we just state name of the cryptocurrency. Okay, I need to add the properties for this new bindings. First one is property will be observable collection of coins. Like I mentioned, we are going to call this available assets. And next property is quite type. And this will be for the selected. Let's go and in the constructor of the transaction will model, we can initialize the available assets. So for the mobile assets, I will initialize it to the new observable collection. And for the actual source we can use coin, dot-dot-dot get available asset. So in this method, you can see the list of all available assets we can have currently in the wallet. Let's see the changes. So we have our cryptocurrencies now in the horizontal list. Okay, the transaction amount next. So let's add a label for the amount and specify just some margins. And now add a new entry for the amount. So we will define the style of this entry. This is going to be static resource named input. So this also comes from the resource dictionary. And you can see that we defined the style once and use it multiple times. So this is the input style. We set the height place called holder color and background color of our entry. Text. For now, let's leave empty, but we will see how to bind that to the amount which supports validations. You're going to see that keyword is numeric and as well at some margins. So 160160, right beneath the entry, we are going to put the label. And that label, we are going to show all the errors we have for this amount entry. So texts for now, we will leave it empty. Style. It's going to be again from the static resource. And the name of the resource is validation error label. Final step is to add some margins. Finally, we have the transaction date. For that, we will use the date picker. So I will add a new label and change this to the transaction date. And at the date beaker with some margins, 1600, 160, and the date property of the date picker. We are going to bind that to the transaction date. We can also see the transaction date now, okay, and the last control is the button to actually perform the adding new transaction. I have also predefined this style for this button. And the style is named blue button. So the button is going to be blue. Margin plenty. With request 240, text is going to be add. And let's bind this to the command named adds transaction command. Okay, we have the bottom here. We just need to add these two new properties and we are done with implementation of the transaction will. So first property is the datetime for the date picker. We're going to call this transaction date. And less defined new command called add transaction command. That's it for this lecture. And starting from next lecture, you are going to see how to add custom validation to the amount property. 23. Validation Rules: In order to validate the amount field. In the transaction view, we are going to specify the different rules for validating our entries throughout the app. And amount entry is one of them. So every validation rule will be presented through this I validation rule interface. The interface has one property for specifying the validation message. In our case, the amount should be greater than 0 because we all support the negative transactions. And we will specify that in the validation message. The other part of the validation rule is the check message. So array implementation of this I validation rule within this check method will have the costume logic for checking whether or not this rule is satisfied. Maybe the best thing is to show you how to implement this interface. So for amount entry, we will have the non negative rule. So this implements I validation rule and type of our amount is going to be decimal. Let's implement this interface. So validation message, we will provide that in the ads transaction ViewModel. And just simply in our check, we are going to check that the value we provide it is greater than 0. So how to use this and all other rules? So for that, we define the word iterable object. These are bendable object, meaning that it raises on property changed event and our amount property is going to be type of the rotatable object. Let's just quickly go through the properties. This glass have this little object and I validation rule is provided in the code snippets lecture of the resources section. So you can go to the get and copy and paste this and I will additional rule. You just need to change the namespace to match this. But to the world itable object, it has the list of validation. So every object can have one or more validation rules. In our case amount, it's only going to have one rule. But we can also add our rule that the amount can't be greater than, let's say 1000. And then we add all those rules to this list. So we get the list of the errors from this validation rules. Every object has its value and is well that property. So once we are ready to perform some action, meaning when we are ready to add new transaction, what we will do is to call the validate method. And in this method, we go and check all our rules. If we have some errors, we write that to the errors property and the object is valid if there is no errors. But we also returned this is valid property. At first sight, this might be or complication and you might be wondering why we are doing this. We can just set the role in the ViewModel and check the amount entry. This is true, but what we are getting here is the entire logic to have multiple rules against one property and they will be displayed accordingly. But also, what we can do is to reuse some of those rules. You're going to see in the later sections where we need to implement the validation Whether or not the email address is valid or not. For that, we will use the RegEx. And in order to avoid having that RegEx all over the place, we will define the rule whether or not text inserted in the entry is an actual e-mail address or not. And that e-mail address entry is going to have several rules. So we're going to have rule whether or not the entry is empty. And the second rule is to check whether the actual texts is the email address format. 24. Validate Amount Entry: Let's see how to use this auditable object. Back to the transaction ViewModel. And now we can define the property. So let me define the rotatable object of type decimal. Need to resolve this. I can call this simply amount. And let's add some validations for this amount. In our constructor. We need to initialize the amount. So this is the itable object. And to this amount and and validation, we are going to add a new rule. This will be non-negative role with some validation message which will be displayed if the, if the amount is left empty. So let's write, please enter amount greater than 0. In our edit transaction method. The first thing, what we can do is to check whether or not the amount property is valid. I call amount dot validate. And if amount is not valid, we can just returned from the method and don't, don't proceed with saving a new transaction. So to bind this to this entry, are going to bind that to the text. And the binding is performed to the value of the text. So the itable object has the value property and the actual amount is stored to that when mode is two way. As for errors, we will also bind that to the amount, but we have the errors property instead. Since this is a collection of errors, what we want to do is to have some kind of converter to only return the first error. Luckily, I have defined converter. So this, this converter takes the list of errors and just returns the first element. This is also available in the code snippets, so you can just copy and paste this in your projects. And in order to use it, same thing as with the inverse Hubble converter. Just need to register first in the resources with some key. And then I can use that here. We are in our transaction view and we click on the ad and the amount is empty, we get the error we specified. Please enter amount greater than 0. If we enter some value, the error is gone. So this was an introduction to validation, validation rules, like I mentioned before. In the later sections, you will see how to use that to combine multiple rules. And the rules. Those rules. 25. Generic Repository Pattern: Okay, Let's start saving and loading transaction from the database. We will use the SQL SQLite database in order to save data to the local database. And the first step is to go to the triplet project. Right-click management of packages and add SQLite net BCL package. That was the first step. The second step is to add to the common folder, new database folder, and put database constants and repository class to it. You can find these files in the code snippets provided in the resources section, we will be using the repository class in order to have a generic class for performing common database operations. If you are not familiar with the repository pattern. Basically, we define the interface. And to that interface we say we want to have some common operations. So we will have get by ID method, delete async, get all async, forget all elements from the safe, stable and save async method, say facing method will be used for inserting and updating items in the table. Now for the actual implementation, we are using the repository class, which has one generic parameter. And this is type of database item. So what is our database item? Database item is our interface stating that every model, that is every class we want to save to the database, it needs to have the int id does the only criteria in order to simplify things. I have also define the base database item abstract class, which already defines this ID as primary key of the table. And it will be auto incremented every time we save our new item to the table. To the rest of the repository implementation, we use the lazy initializer variable to the find new SQLite async connection. And then in the constructor, we call initialized async to create a new table using the SQL lite async connection. Say far as m forget is an extension coming from the task extension class, the say fire and forget provides us a way to call an async method from the constructor so that we can perform some async operation in the repository constructor and then rest of the implementation get by ID uses database table to get the item based on the ID. Delete async, removes the item from the table, get all async just goes into the database and returns or item as least. And finally, we have saved async solve if item ID is different than 0, meaning that the item has been saved before we perform updates async. Otherwise, we insert this item as a new item in the table. 26. Save Data to the Database: Let's see how to use this repository by saving a new transaction to the database. The first thing we need is to go to the models and make sure the transaction implements base database item. So like I mentioned before, base database item with an ID property that its primary key to the table, and this will be auto incremented the property. Next, we need to register the generic repository. So here is an example of how to register our repository. We need to resolve the repository class. And here instead of user, I will type transaction resolve. And we are good to go. Let's go to the ViewModel private repository. For transaction. We will call this just repository. And we need this dependency. So I repository of transaction repository. And let's assign this to the local variable. We save new transaction after we click on the Add button. And this triggers the at the transaction commit, this in turn calls the transaction method. So Our save logic will be placed here. The first thing we need to make sure is that the selected coin is different than null. That meaning, meaning that we have selected the coin. If we haven't, we need to show to the user message that he needs to select a coin. For that, I will use the dialogue message class. So to the column and new folder for dialogue functionality. And like all other things, we can go to the snippets provided in the resources section. Find the dialogue message implementation, and just copy this into our new class. So I'll right-click Add new class, which we'll call dialogue message. Simply paste this and resolve the missing parts. Go to the transaction. And we also need to inject the dialogue message dependency. So again, we need i dialogue message class and call this dialogue message. Use the dependency injection in order to provide Heidelberg message through the outer Fock. So I dialogue message, dialogue message, and initialize the local field for dialogue message. And now we can use the dialogue message. So dialog message has different actions. It can provide display sheet. You can display it just common alert. And it can display a prompt for user to enter some text. In this case, we will use the display alert. And if the selected coin is 0, we will state error. Please select a coin. And the button on the alert will be okay. This is an async method, so we need to await it. Okay, moving on to the saving to the database, what I will do is to set is BZ of the ViewModel to true. And I need to set it to false once we are done with the logic and here. Okay, and create new transaction, which will, we will store in the database. So no transaction. Just need to fill out the properties. We have the amount. This comes from the amount field. Next, we have the transaction date. This comes from the date picker in the view. Symbol comes from the selected coin. Dot symbol status. So transaction can be of type deposit or withdrawn. And if our is the positive property is equal to true, then the status will be, we'll get from constants that transaction deposited. Otherwise we have constants dot transaction withdrawn status. And we can just use the repository here to save a sink the new transaction we just created. And that's the whole gist of how to save a new transaction to the database. So repository takes this transaction and save that to the database. We don't have to perform any additional queries. And once we are done with the, with the saving, we want to navigate back to the transactions view. So we need to use the navigation service. Let's also add the navigation service and also inject the navigation service through the constructor. So here we can use negation service that async, and this will navigate to the previous view. Lasting I can do here is to perform extract method on this part of code. And it struck that into a separate method just to have the whole transaction methods bit clear. So left-click on the bulb extract method, and we will call this method save new transaction. The reason we're using is busy here and we set it to true and false is that we want to disable the ads. The execution of the transactional meant if we are adding new transaction to the database. So we want to prevent for from inserting the same transaction 2 times. The command can also take one additional parameter, and this is whether or not we can execute this command and we will use the is not busy property of the viewModel decision just reverse of his busy before we preview changes, Let's just add the return here so we don't want to Resume with processing and saying new transactions. And if we don't have the selected coin. So now let's see how this looks like. Another thing I have noticed is thus is that we are missing the exclamation mark here. So now let's preview the changes. Okay? Transactions. Let's add a new one. If we go to the add and we haven't entered the amount, we will get the error if we go to the Add. Now, we will get the error that we need to select a coin, okay? If we select a coin and select transaction date, so the transaction date is currently minimum transaction date. Let's just quickly fix that by adding the default for the transaction date. Transaction date by default is going to be the time now. And also the initial value of the deposit is going to be true. Now let's see how to save our new transaction. New one, Bitcoin amount, one. Today's date. And if we click on the add, the transaction has been saved to the database. But here we are still using the hard-coded data. And let's see how to change this to load the actual transaction saved in the database. 27. Load Data from the Database: Now let's load the saved transaction in the database to the source of our data for our ViewModel. And that's the wall controller. So again, I'm going to use the repository in order to get the transactions. So our repository for transaction, just resolve that called this transaction repository and use the constructor to get the transaction repository. In our transactions method, I will delete all these dummy data we have previously created and get the actual transactions from the database using our transaction repository. And the method is get all async. Since we are using a weight, we need to use Async as well and less sort this transaction by transaction date. So we will show our transactions. First is going to be the latest and the oldest is going to be at the bottom of our list. Okay? And before real return those transactions, two things we need to do. So for each transaction. In our transactions, let's just set the actual image. So status image source will be determined based from the status. So if status is equal to the constant not deposited, then we are using constants. Transaction the positive image. Otherwise, we will be using constants, withdrawn image. And what's also missing in the transaction is the actual calculation of the transaction. In dollar value. We will use our amount times the actual price of the coin at the time of fetching the transaction from the database. For that, we need the rest API. And since we will add the rest API functionality in the next section, for now, just be patient and hear God some fixed price, like I mentioned. We will change that in the next section. Finally, we can return our transactions and see the changes. Immediately. You can see the transaction, we can create it in the last lecture in the latest transaction section of the wallet view. And if we go to the transactions, you can see that we have the same transaction. So again, we, we are reusing the functionality or the word controller to display transactions in both transactions and the wallet view. And the same transaction is visible in the deposited tab. If we go to the withdrawn, this is obviously empty. But what we can do is to create one. We'd run the transaction legit, add that to the database. And now we can also see the second transaction. As you can see, it's pretty straightforward to use the transaction repository to save and load all items from the database. 28. Update Existing Data: At the moment, while we are navigating to the end transaction ViewModel from the transaction ViewModel. After we select an item in the transaction view, we are passing the hard-coded ID of the transaction. Let's change that by using the real data. So let's use the selected transaction property and use the ID to pause dot ID to the add transaction ViewModel. What we can do is to use this ID in the edge transaction ViewModel and pre-populate the data on the view. And after we make some changes to the transaction, we can update that transaction. So let's go to the transaction of your model. We are getting the ID parameter and fill that to the ID property. So this property, what we are going to do is to in the initialized async method. So let's override initialized async method. And here we are going to pre-populate our fields in case we have the ID. I think I'm also missing the own appearing method here. And in this ONE appearing, I'm going to take the binding context to the transaction ViewModel and call the initialized async in order to repopulate the fields. So let's go to the initialized async. First, we need to check we have the ID. So if our ID is null or whitespace or B, we cannot parse that to int. So let's try to parse the ID, the ID to int in transaction ID. So if we cannot parse that, I'm missing the Get in the ID. That's why compiler is complaining. So I can just return the ID here. So if we don't have the ID, we can use these default values. Let's just quickly clean up the constructor a bit by extract method. I'm going to name this method at validations. And just put this method to the end of the file so that we have a better overview of what's happening in the constructor. So if we don't have ID, transaction date is daytime now is deposit is true. But if we have our ID, that means that we can try to load the transaction using the repository. And we have the get by ID method and we just pass the transaction ID. So here we just need to reverse this logic. If we cannot parse the id, then we are using the default values. We have some errors, so let's just quickly fix them. Here. I'm missing async. And here it says Use of unassigned local variable. That's okay. We don't have the transaction ID and then just returned from the initialized async. Otherwise, get me the drown section and populate deposit. So is the positive, we will get that from the transaction status. The status is equal to constants get transaction deposited. Then we have the positive set to true amount dot, where you will get that from the transaction count. And transaction date is equal of the transaction, transaction date. Lastly, let's just set the selected coin. So we will use the coin, gets available assets to get all available assets. And then find the first one, which has the symbol same as our loaded transaction. Let's just make sure the updating of an existing transaction works properly. By passing the ID of the transaction we have selected in the transaction view. So if our ID that we passed IS null or empty, then we will pause 0 to as the ID, meaning that we will insert a new transaction. Otherwise, let's just go and parse dot ID. Let's select the transaction and try to update the amount. If we update the amount, the transaction has been updated successfully. 29. Override Back Button Behavior Using Shell: Another cool feature that, sorry, forums shell has ability to override the back button behavior. So let's say that the user is on the screen and you want to display some message when the user clicks on the back button, we can override that back button behavior and display the message easily. Let me show you these Editors section view example. So we are going to override the back button behavior and we are going to present the message to the user asking if he's sure that he wants to navigate back, since he may lose any unsaved changes. For that, we will use shell dot back button behavior. And what we need to do is to define back button behavior with some command. Let's bind that to the go back command. Optionally, you can also override the default icon, so you can provide different image for your icon. Going to the transaction ViewModel, let's define new command, which we will name go back command. Here. We will ask the user if his shirt to wants to go back. So let's use dialogue message to display all or which two options, okay, and Kelso title, Let's just say confirm. The text of the actual alert is going to be are you sure you want to navigate back? Any unsaved changes will be lost. And let's add two buttons. First these are k, and the second one is cancel. This method returns bowl and we need to await this. And depending on if she should go back is true, then we just use navigation service and Gaga go back async. I don't think I have shown you the go back async. So in shell, you can easily go back by stating go to async and two dots, and you will navigate to the previous view. Okay, let's see the change. So now if we click on the back button, we will get the confirm message. Are you sure you want to navigate back? If we click on Cancel, we stay on the current view. If you click Okay, then we navigate to the previous view. 30. Generic Network Service: In this lecture, I'm going to show you another generic component you can use in your projects. Also, you can find this in the code snippets. And this is the network service. So you can use the network service class to perform common network operations. So this is a GET, post, PUT, and delete based on the URI you have, that is on the URL. And this is a generic method, meaning that these methods will automatically convert the resulting JSON string to result type you provide. So let's go through the implementation. We are using the HTTP client to perform all our requests. So we are calling the get async, get async of the HTTP client. And what we're using is the Newton solved the JSON class to convert the JSON we got into resulting class or other methods are implemented in the same way. So for post, you have the option to post the JSON data. And we are also calling post async. We are getting the result as strings. And in the last step when convert that to a resulting type. Same thing for put. Just the only changes that instead of post, we are using put here. And delete async calls the URL with the delete HTTP method. And we just return from this method. 31. Get Data From the Crypto API: The API we are going to use to get the cryptocurrency prices is going to be going gecko. It has free API to use, and it's relatively simple. I also search through the internet for other APIs, but most of them are fairly limited in what they can do or they are pretty expensive. So we will use the completely free coin Gekko. One other service that I originally planned to use is dropped. Example, Data Service. So this provides you with some dummy data for your application. So if you need some common endpoints, such as crypto or list or media or real estate stocks. You can use drug bit to get the data. So here you can see the list of all available resources, for example, to the list. So you can see id, name and stuff like that. So really useful API at your disposal if you need to build ups around these sources. Okay, but back to the coin Gekko, we are going to use the simple slash price endpoint to get the list of prices for our available coins. And this will be indicated in US dollars. If we execute that, we see the actual result. So this is a dictionary containing all the available cryptocurrencies we support in our crypto wallet. One other thing we have to have in mind is that in our app, we are using Bitcoin space cash. But here we will have to change the space to dash, okay, back to the app. The first thing I need to do is to remove some of those properties from the coin since these were meant to be used with the job it. But like I mentioned, in the meantime, I found the coin Gekko, which is much more accurate. And the next thing we have to do is to define new constant string for the api dot echo.com. Now we can actually go to the network folder and create a new class called Crypto Service. The interface for this Crypto Service is going to be rather simple. It's going to have only one method. And this is going to be async method, which will return a list of coins. And this list of coins will have latest prices. Okay? There is resolve the missing using And implement this interface. We also need to define the actual prices endpoint. So this is the simple slash price endpoint you have seen few moments ago. What I will also need is the network service. So let's create a variable for network service. And inject dot to the constructor. Okay, now to the implementation of the latest prices, obviously this is going to be async method. Now first thing we need to do is to define the URL of the endpoint we are going to reach. So we will use constants, got crypto API. We will concatenate that with the prices endpoint and store the actual result in the result variable. Let's use the network service to call get a sink with URL. The resulting type, it's going to be dictionary. And that dictionary, the key is going to be crypto name. So this is string. And the value is going to be another dictionary. And this is the list of prices. So we only, we will only have one price and that's in US dollars. But if we want, we could also specify price, let's say against Bitcoin, but we will just use the US dollar. Okay? And now let's use the available assets to get the list of coins we are going to return. And just before that, let's iterate or the coins and set the price of the coin. So coin prices are coming from the dictionary that takes a string and double, optional double. So this, Let's name this coin prices. So from our result, we will take item name and what we have to do in case of Bitcoin cash is to replace the whitespace with dash and use to lower the actual coin price comes from this dictionary. So we will use corn prices and from the key USD, we will try to get the optional double. And finally, our item dot price is equal to the coin price. That is, if we have value on this coin price, then we will pass the value. Otherwise, let's just passed 0 and we return. So now that we have the latest prices for every coin, we can go and calculate the value of each asset we have in our wallet. 32. Calculate Data for the Assets View: In order to save us some time, I have already implemented necessary changes in the wall controller and included clipped Crypto Service in order to calculate coin prices. So let's go over the changes. I have added Crypto Service and also added cached coins. So we will be getting the coin prices through the Crypto Service and then catch them in the cached coined least. Defaults assets. I have made some changes, so amount is 0 for all three coins, and this will be our default coins. We, we don't have any transactions in the crypto wallet. We are going to return this list. Now for the actual implementation of the get-go, the first step, what we are doing is we are loading transactions from the database. So using low the transaction method and the first step is to get the latest prices for the coins. Next, we get the transactions from the database using transaction repository and order by descending by transaction date. If we don't have any transactions, then what we are doing is returning the default three coins with 0 values. In order to calculate the amount we have for every coin, that is for every asset, we need to first group the transactions by the symbol and then go to the grouped transaction. And to get the amount, we need to sum all the positive transactions and subtract all withdrawal transaction from that amount. Then we create a new coin assigned the amount and our dollar value of the asset. What we have is the amount times cached coin price. I also made some smaller changes to the get transactions. We are using the same method, low transactions to get the transaction from the database. If we don't have transactions or if our list of coins is 0, then we just return the transactions. The other change of I made is that now we are updating the dollar value and getting the cached coins and the cash price and multiply that with the transaction amount. Let's see how this looks like now in the wallet view. So now in the quality view, we have the actual prices for the Bitcoin and Ethereum. And also if we would add any other asset, that is any other coin, we will get the accurate prices as well. 33. Implement the Assets View: We will conclude this section by implementing the assets view. So what we'll assets few contain. Well, if we go to the portfolio, we can see our top Assets. And here you can see top three acids. The similar logic will be in the 30, but here you will see all assets you have, not just the first tree. Let's start by adding some title, assets title. And also to the content page. We will add the collection view and define some properties. The first property is item source. We are going to bind that to the assets collection. We're going to define shortly. Next, selection mode will be none. So we won't be supporting selection mode, selection of any asset on the screen. And item template. This again comes from the resource dictionary, and this is static resource asset cell. We also have an option to create a new transaction from the screen. So we will also add Tool, toolbar item to the screen. Let's add toolbar items section and just add one toolbar item. Text of the toolbar item is going to be at order, primary priority. And we are going to bind that to the transaction command. The next piece we need is the assets ViewModel. And this will inherit from base ViewModel. Let's bind that to the binding context of the passage 30. So binding context of the assets view is the container. Resolve, resolve, assets, ViewModel. And on the on appearing method. We are going to take our binding context. Let's cause that to the view model and perform initialized async method so that we can actually load data in this method. We are missing a sink here. Okay, Here we will override initialized async. And what we will be needing is to dependencies. The first one dependency is going to be I will add controller to get the coins. That is the assets we currently have in our wallet. And the next dependency we need is I navigation service, so that we can navigate to the transaction of you and create another transaction. Let's create our new constructor. And we will initialize both the dependencies. We will also need the observable collection named assets. This will be our coins. Also resolve collection and rename this to assets. The final piece we need is the add transaction command. So let's define that as well at transaction command. And we are also missing some musings. Okay, let's implement the add transaction, since it's pretty straightforward. So we will just call navigation service. And to the current stack, we will push the transaction ViewModel. Also one other place when we need to define those same logic is in the wallet ViewModel. We have left the todo here to navigate to the transaction view. So let's define that here as well. I need to resolve at transaction ViewModel. And here as well. I need to inject the navigation service. And let's provide that to the constructor. Our navigation service is equal to the navigation service. Okay? Final piece is the initialized async method. This is very simple. So we will use our wallet controller to get the list of coins. And once we have that, we will create a new observable collection from that list and just give it to the assets property. And that's it. I missing anything here. And just in case I can initialize this to the new collection just to not get some null reference exceptions. And we have our assets here and click on the Add, navigates to the transaction view. 34. Implement the Loading View: We'll start this section by implementing the loading view. But before we start implementing anything, let's just take a step back and see bigger picture. In order to understand why are we doing something, we will have two flows. Two main parts of the app will have the login flow and the main flow, and have the loading view as a place to put the logic for deciding which view to show first. If the user hasn't seen the onboarding view yet. We will show that to the user first. If he has seen the onboarding view, he'll be presented with the login view. These views will be in the login flow together with the register screen. If the user has been logged in the last time he has used the app, then the first few here we'll see is the Wallace fuel. And here the rest of the screens, on the screens we have implemented already main flow is the flow. We have defined ED app shell, the XAML, so all that structure we have already defined, that's the main flow of the app. And for the login flow will create completely new shell file. So let's start with creating the loading view. First. I'm going to create our loading folder. And here I need to add 4 two files. The first file is the loading view, and the second file is loading ViewModel. While we're here, let's just bind these two components together. So binding context of the loading view is the loading real model. And in the own appearing method, which will override, we will take the binding contexts. We have. Let's cast that to the loading view model and perform initialized async. But in order to be able to perform initialized async, we need to inherit the Bayesian model. And now we can call the initialized async parameter is going to be null. This is an async method, so we need to await it. The actual implementation of the loading view is going to be fairly simple sold the only thing we need to have on this view is the activity indicator. And I'll put some label stating that we are loading the app. So let's run these two components. Stick layout. We will just set the vertical options. To center and horizontal option to the center as well. So that we present our activity indicator at the center of the screen. Core is going to be excellent, is running, is true and is visible. Also true. Let's just add labels simple with text loading. And now what we have to do is to change the initial view of our app. It's not going to be App Shell anymore, but instead, we are going to resolve the loading view. And now we can see our activity indicator. Okay, let's implement the decision making logic in the initialized async methods. What we will need is the navigation service. Let's call this navigation service. And we need to inject that to the constructor. I have also defined two new constants in the constants glass. So I have defined show onboarding flag named shown on boarding. And the other one is string, is user logged in? User logged string. And we will use this drink to determine the initial view of the app. We will also use Xamarin Essentials to help us with storing some data related to the flow. And we will use preferences from the Xamarin Essentials 2 to store some data if you're not familiar with the Xamarin Essentials. Basically, Xamarin Essentials is our collection of useful libraries to help you Dealing with different cross-platform operations, such as permissions, files, photos. And in this case, we will use Xamarin Essentials to store some smaller pieces of the data to the user preferences. So let's start with our logic. The first thing, I will make sure if that our preferences doesn't contain the key constants shown. Onboarding. What we need to do is to navigate to the onboarding screen. And also what we need to do is to store to the preferences actual value of the short onboarding and set it to true. From this, we will just return task completed dusk. I'm missing the exclamation mark here. So next, if the preferences already contain the key shown on boarding, then we need to check whether or not the user has been logged in. So if our preferences contains key, which comes from constants, is user logged in. And if the value of that key is equal to true. So if this value is equal to true, then what we want to do is to go to the wallet. So we will navigate to the wallet view. And from here we can return task, completed task. Finally, we have shown to the user the onboarding, but the user is not logged in in the application. In this case, we will navigate to the login screen. Okay, we have some missing pieces. So let's go ahead and create the missing views and files. 35. Introduce the Login Flow: Okay, what we are missing are three additional US. This is the view from the onboarding screen for the login screen and for the register screen. First, I just need to resolve the error I have here by stating that I want to return task, that completed task. And now I can go to modules and create three additional modules. So the first one is for onboarding. Here I need onboarding ViewModel. And also I need onboarding view. Next, let's go ahead and set the binding contexts all the onboarding viewed to be a morning ViewModel. So I need to repeat the same thing for register and login views. Okay, we have all the missing pieces. And now what I will do is to create a completely new shell file. So our app shell that Zama, we are using this for the main part of the app, for the main flow. And we'll create a new shell file and use that file only for the login part, that is only for the onboarding login and register use. This is our new file. And the simplest way is to do this is by creating new content page, which we will create to the Shell file. So I'm going to call this login shell. Then instead of contact page here, I'm going to say this is Shell class, that is the subclass of the shell. And here I'm not dealing with the content page, but instead I'm dealing with the cell and contemplate is illegal in the shell class. Let me just quickly define the namespaces we need. I'm going to show content in order to put these new views inside the lowest shell. So I'm going to also state the route. The first one is the 40 onboarding, and the route name is onboarding ViewModel content template. This is the data template from the onboarding view. The second content is the login content. So the route is the name of the view model. This is the login view model and the content template. You're already guessed. We are using login view for this. The third one, Shell Content, so broad for this is the register, your model. And in the content template, we are going to put the register view. So register view. Now we have our login shell already. And what we need to do is to update the navigation service in order to work with both flows. So this means that it needs to have two additional methods. One for changing to the main flow and second one to change the flow to the login flow. 36. Update Navigation Service to Change Between Flows: Like I mentioned at the end of the last lecture, we need to update the navigation service in order to switch between our two forms, between login flow and the main flow. So what we need a new method, the one method is to go to main flow. Second one is similar. Go to login flow. Let's implement these two methods. The easiest way to go from one floor to another is to set the application current main page. To be, in this case, new options. Similar logic is for going to the login flow. So instead of going to the app shell, we will go to the login shell. And now the compiler is complaining because we are losing our application as the namespace name. We need to quickly remove application from the namespace. And now this should be fine. So let's just resolve login shell. Finally, we can go back to the loading real and as the missing logic. So if we haven't shown The onboarding screen to the user, we will set the flag shown on warning to true. And what we are going to do is to use the navigation service to go to the login flow. This will show the first view in the longest shell and that's the onboarding ViewModel. The next thing we need to do is if the user has been logged in, then we need to go to the volatile. That is, we will use the navigation service to go to the main flow. And this all again. So the first view in the main flow in the app shell, and that's the volatile. And finally, if the user is not logged in, then what we need to do is to go to the login flow. But also make sure that we navigate to the login view model. And we will set that as a route to you. So our Login view model, okay, compiler is complaining again, meaning that I have forgot to set this to Bayesian model, which I also probably need to do for the register remodel. And let me just check the onboarding ViewModel. Yep, that's right. I need to set the ViewModel here as well. In order to see the changes. We don't have any content here. So let's say text is login. And also we can go to the onboarding view and set some texts so you can see the changes. So let's set the text to the Onboarding. Okay, at the first part of the app, we show the onboarding view. If we try to run the app the second time. Now we see dogging you. So the next step, what we need to do is to actually implement the onboarding register and login view. 37. Implement the Onboarding View: At the moment, the onboarding view looks pretty empty and really said, so let's change that. We are going to use the carousel view in order to show the onboarding steps. So let's first start with adding some additional properties to the content page. The first thing we need to do is to make sure that the navbar is not visible. And second, what we need to do is to disabled the Flyout behavior. Okay? Now we can actually implement our on-boarding view. We will put everything inside the stack layout. And for vertical option, we will have start and expand. Also. Let's add some background color to the stack layout. We will use static, resource. Light-blue, break ground. Now let's define the grid component. And inside green component, we will add the carousel view. If you're not familiar with the carousel view. This is our view for presenting data in our scrollable layout, where users can swipe to move through the collection of items. So the most important property is probably item source. And we will bind that to the onboarding steps. We all just make sure that horizontal scroll bar with ability is set to never. And what we will also do, we will add the indicator view to our carousel view. For this, we will define the indicator view. So in our own morning, we will have three different steps. And Indicator View will indicate on which step are we currently. Okay, we actually need to define here item template. For that. I'm going to use Carl Silvio Python template. And we will use data template inside. In order to save us some time. I have provided the data template. This is stay Cloud layout that has three different items. So it has the image URL, it has the title of the onboarding step and also has some explanation. This is bind to the details property. The next thing we need is our button int, an option to keep the onboarding steps. So text is going to be skipped. Let's just quickly style this. I'm going to add some font, set text color to the primary blue. Let's just add vertical option. Start. Horizontal option, and background color. This is going to be transparent at some margins. So 050, 2000. And at the actual command, we are going to bind this to the skip command. What we are going to do when we execute this command, we are going to navigate to the login view. And the last thing we need is the indicator view in order to show in which step we are currently on. So this is the name indicator, real pleasure to find some properties to the indicator view. So indicator size is going to be ten. Indicator color. We are going to use static resource. Cell, background, selected indicator color. It's going to be primary blue. Horizontal option. We want to present it in center. And for vertical option, we want to present that at the end of our screen. Let's just add some margins. So 000 and bottom margin, we will add some value. Okay, the next thing we need is our new modal class for presenting the onboarding step. And we'll call this class on boarding item. So this onboarding item, it's going to have three properties. Image, URL, title, and details. Let's just go ahead and create the constructor to populate these two properties. Okay, and now we are ready to get to the onboarding ViewModel and pre-populate the onboarding steps collection. So how alcohol already defined the necessary text and images. So we are going to have three steps. First one is welcome. Second one is information that you can store many tokens. And the third step is the security. Okay? And we also need to define the skip command. And for the skip command, like we said, we need to navigate to the login view model. So let's resolve missing dependencies. And we will need negation service. So our navigation service. And let's initialize that to the constructor. And here the actual implementation is simple. So we'll just call navigation service and insert our Login view model as root. Okay, just need to rename the command. And now let's see what we get. You can see the onboarding view and the carousel view. Here is the indicator. If we navigate to the second step, the indicator of Europe has changed. And if we tap on the Skip button, we navigate to the login view. So everything works correctly. Now. 38. Navigate to the Register View: The next screen we see in our journey through the cryptology app is the login screen. But we really cannot login the users unless we register them previously. So what I will do is to create a button on the login screen to navigate to the register screen. And then we'll start with the register view first. So let's go ahead and clean this. I'm going to add a steak layout and another stack layout to place the button. The button is going to position at the bottom of the login view. So we need to set horizontal options center, but vertical option, we will set and expand for the stack layout so that we can place our button here to navigate to the register screen. Let's add this button. So this is a button which cause custom style, and that style has been predefined. And it's named no background small button. As you can see, the name is pretty descriptive. So this will be a small button with no background text. It's going to be, Hey, don't have an account. Sign up. Let's just close this. And we're, the last thing we need is the command to bind. This button, will bind this to register command. And while we're here, let's just add some bottom margin to the stack layout so that the button is not the complete bottom, but it stands. It's slightly positioned up. Okay, Let's go to the login view model and implement the button. So what we need is a button name, register. And what we need to do is to navigate to the register. You again, I need navigation service to define this negation service. So variable and initialize this to constructor. Okay? And now I can simply go to the register view and insert that view as root. If we click on the button now, we are on the register view. 39. Implement the Register View: Register real implementation is next. So I will start by hiding boat navigation bars and fly out menus using shell Navarro is reusable and shell flyout behavior, and this removes navbar and flyout menu. After that, I'll go ahead and implement the actual body of the register view. So I start with those, take layout and just define some background color. Also, this will come from start decreasing and the color is light blue background. After that, I will define some bedding so that the content is not at the top of the view, but slightly lower than the status bar. Okay, we'll start with the label. And text is going to be create account style. It's going to be vital label. But you need to use the static resource for this. Next, we will display an image. Source is going to be register that B and G. Let's add some margin. So 0, 30, 000. And height request is 200. Okay? After the image, we will place the name, email address, and password fields. So let's go ahead and create another stickler layout for this. Background color is going to be white. Vertical options, feel and expand. Now we can define our first entry. This is going to be for the FirstName. So FirstName. I also have the predefined style for this kind of entries. And this is going to be input style. Text is going to be bound to the name that value. And mode is doorway. So name is going to be well datable object. If you remember, the multilevel logic has two main properties. One is to store the actual value of the object, and the second one is going to be errors for displaying errors. So after the entry, we need a label for errors. So text for this is going to be bound to the. Name dot errors. And what we also need is to convert the collection of errors to a single error. So again, I'm going to use our converters. And similar to what we had in the transaction, I need to define resources page. So let's add those resources. And now I can use here the converter. So static resource, first, validation error style for the label. It's also going to be static resource validation error label. And we just need to add some margin to these fields. So to the entry, I'm going to add margin of, let's say 242404 label. I'm going to add margin 26, 0. For that, we need to repeat the same process for two more entries. So the first one is going to be for the email address, and the second is going to be for password. The easiest way is to copy and paste this and just make some changes. So here, placeholder is e-mail address and instead of name that YOU, we are going to use email that value. Same thing here. We will use email Dot Earth. And here I will add the keyboard type e-mail. And we don't need this kind of margin here. Okay? Lastly, so for password, placeholder is going to be password. Instead of keyboard type. We are going to define is password equal to true? And instead of binding to the e-mail, we are going to bind that to the password property. Same thing here. We will bind this to the password. So we have our fields. Now, the last thing I'm going to add is the option to register and also an option to go to the login view. So let's see these changes. After we enter first name, email, and address, we will get the button that says, let's get started. The style is blue button. And if we already have an account, we have an option to go to the Login and we will use the login command for that. 40. Register Functionality: Now for the register ViewModel implementation, I have went ahead a bit and pre-populate the things you have already seen me typing 100 times throughout this course. So mainly that's the navigation service. I inject that to the constructor. And then I have also added three new holiday table objects. One for email, one for password, and worn for first name. I also added two new commands we will need in the register view. The first one is loading command, and that command just goes to the login view. The second command is to register user. This is at the moment empty. And in this lecture we are going to implement this method. Register user command can be executed only if the ViewModel is not busy. If the is busy is equal to true, then the command won't be triggered for the second time in a row. What you need to do is store tasks. So first one is to validate entered values. The second one is to perform the user registration for validating entered values. I have created our method in the constructor add validations, and we will define all the validations we want to have for our tree entries. So first one is e-mail. So the first step is to actually define these three objects. So we will just set that to the new validation bubble object. Also password. And next, let's add the rules we want to have for email. We want to have two rules. So the first rule we are going to add, this is the rule that the entry shouldn't be null or empty. So I'll add new IS NOT null or empty rule for string. And validation message is going to be e-mail is empty. The second rule we are going to add to the e-mail is the e-mail rule. So I'll defined a rule for string. And if the e-mail is not in the correct format, we will show the error message that e-mail is not in the correct format. These tutorials are available in the code snippets. But what they do is essentially that IS NOT null or empty row takes the string, that it's not null or whitespace. The second roll is e-mail rule. So this e-mail has the regular check that the email is correct format. So the good thing is that we can reuse these RegEx drew out the application. So since we will be having email entry, Humboldt register, and login views, we can reuse this role and this logic. Okay, the next thing we are going to validate is name. Let's add validation. This IS NOT null or empty. And if it is, we need to write the error message, that name is empty. So similar to the password. We will add new validation. So this is new validation. Same thing. We will check that this is not null or empty. And if it is, we are going to say, Hey man, password is empty. Okay, we have our validations ready. And here, now we can go ahead and define the logic for validating entered values. We are going to define new method which will be named. Entries are correctly populated. And this will return bool whether or not all entries are in are correct format. So in this method, we are going to call validate, e-mail, validate name, and validate password. And the result of this method is going to be if the email as well it and if the name is valid, and if the password is well it, then the method is going to return true. If any of these fields is not valid, the method will return false. So let's go ahead and use the method. So here we are going to say if entries are not correctly populated, we are going to return immediately. If this is valid, then what we can do is to create and save user details. For that, we need a new model class and we will name this class simply user. So let's go ahead and create a new user class. The user class has three properties. It has firstName, email, and for storing password, we are going to store that to the hashed password property. This means we are not going to store password as plain text. So if a user types in password 123456, then we are not going to store it as that, but instead, we are going to hash, hash it, meaning that we will convert it to unrecognizable string. So. It's not possible to get the password from that string. For password hashing, we are going to use the secure password casher. This is our class that uses Erin G Crypto Service Provider. In order to hash the password. We are not going to go to the implementation since this is not too important. But I will attach this class to this lecture so you can copy and paste it and use it in your projects. The other piece we need is the user repository. So the same way we register the repository for the transaction, we are going to store the repository for user. So let's go ahead and define this repository. And I have here one error stating that the user is not. Notice the user doesn't inherit from the base database item. Okay? And now the error should be gone. Yeah, it is. So you can see if you use these generic repository, that it's relatively simple to create a new class which will entirely handle new, new table. In this case, this is user. Let's also defined this repository here. So this is our repository of user. We need to resolve these two classes. So this is going to be named user repository. And we need another ten dependency here. This is going to be repository for our user. Let's call this repository and initialize our users repository with this repository. So now we can use the user repository. But first, let's just create a new user. So let's say var, new user is equal to the new user. And fill out the produce. So email is equal to the e-mail dot value. Firstname is equal to the name, that value. And lastly, hashed password. So we are going to use secure password Hampshire to hash our password. So this is just to increase the security of our app. And finally, what we can do is to use the user repository to save this new user. Okay? What we can do once we save our user, we can set the preferences for is user logged in. So let's set for key. Is user logged in? We will set that to true. And we can use the navigation service to go to the main flow. So let's see the whole registered user in action. Okay, we need to sign up and I will enter some firstname, email address, and password. Let's get started. And now I am in the main app, but the app is empty. 41. Login View Implementation: Here you can see the implementation of the login view, as you may notice, is like 90 percent similar to the register screen. So let's just quickly go over to the actual implementation. Again, similar. We define the label. So this is Welcome back. Also after that comes image. And here, as in the register view, we have our entry for email address and entry for password. Beneath those both entries are a label for Earth. So if we click on the login, you will see the errors. One extra thing added to the login view is the image that has gif animation. So in process of logging, you will see the loading here, the loading spinner. So this is just to show you that the image can also take the GIF image. Let's quickly go over to the login view model. Again, similar to the register ViewModel. We have our navigation service, I repository for user. And here we have some dialogue message for presenting some messages to the user. Again, while the itable object for email, for password, we have the register command. This goes to the register view. And the actual implementation is in the login user. So again, we have added the validations to the add validation method. So for email, we again have two rules that it shouldn't be empty and it should be incorrect format. And for password, we just state that it shouldn't be empty. If it's empty, then the user gets passwords is empty. Let's go over to the login user method. Again. If entries are not correctly populated, then we return from this method. Otherwise, what we do in this case, we are trying to get the user with the same email as this e-mail entered. So if I have our user that does not exist, I'll get the error that credentials are wrong. If the user was found. Then we are going to step further. And using the secure possible Hampshire to check the password value against the hashed password. If that's fine, then we are going to the main flow and set preferences that the user has been logged in. If the passwords don't match, then again, we are displaying the same error that credentials are wrong. And we return from the execution. So I will enter my user, enter wrong password. So we are getting that the credentials are wrong. If I enter the correct password, then I'm going to the main flow. And now what I can do is to add new transactions. Let's just quickly add a new transaction. And the new transactions appears in the wallet view. One other thing I have implemented is the logout functionality. This is done in app shell ViewModel. So here what we are doing is removing from the preferences that the user is logged in. And we are going to the login flow. And we are inserting login view model as our root view. 42. Update to Xamarin.Forms 5: When you are working on our long-term goals are informed project, it is advised to update your Xamarin Forms version once in a while so that you can get access to the latest Xamarin Forms, fixes, enhancements, and new features. So in our case, crystal at app is now in the version of 4.8. And what I would like to do is to update it to the Xamarin Forms five. So there are a couple of steps you need to do before you update to the summary forms. Five, the first step is to have backup of your whole solution. I advice to you that you use good for storing your code. So if anything gets wrong during these Xamarin Forms update, you can quickly revert back to the previous version, which was working fine. The other thing, if you are not using source control, then what you can do is to take the whole solution project and copy and paste that and just write that. This is our backup that you have. Next, what you also need to have in mind is that if you are using some third-party libraries, you need to make sure that they work with the latest version of Xamarin Forms. Because if they are not working, then after you update your summary forms version, you may get issues with those third-party libraries and then you need to make workarounds. So you need to check pros and cons when updating Xamarin Forms compared to your third party libraries. So like I mentioned, I have Xamarin Forms born 4.8 band. What I would like to do is to update all these NuGet packages so I can right-click on Cryptoclidus solution and 43. Course Recap: And this concludes our crypto let, crypto wallet application. Well done for sticking all the way to the end. I'm sure you have learned many great things you can use in your own projects to make them awesome. If you have enjoyed in this course, you can show your support by leaving a review. Your reviews helps me a lot to continue to build this course is for you and continue to help him you in that way. Let's just go over quickly through the application we made. So we started with this fly-out menu. And you have seen how to use the flyout menu to reach different screens within your app. Then we moved to the top bar paged. And you have seen how easily it was to create these scholars top bar page. Then we move out to the volatile view, implemented the chart to you, top assets and the list of latest collection. Next, me, focused on the transactions and you have seen how to use the radio button is our informs. How to build these horizontal list collection view and also how to add the custom validations for your entries. You have also seen how to override the back button behavior easily using shell. We then focused on getting the actual prices from the rest API using the coin Gekko. And after that, we move out to the second part, which was the whole login section. So you can see how to implement both login view and register view. And thus before that, you have seen how to implement this onboarding view using the carousel view and the indicated real. So that's all for now. If you have any questions, then please go ahead and ask them by either pressing question to the QA section of the course, or you can also send me a direct message. I'm here to help you.