.NET MAUI Course for Beginners – Create Cross-Platform Apps with C#

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
learn a native cross-platform desktop and mobile development with.net Maui join senior software developer and expert course creator Frank Leo as he takes you on a fast-paced journey through the fundamentalsof.net Maui in this exciting course Frank will guide you through the essentials of building mobile applications with net Maui while creating a contacts app you'll learn all the key Concepts and techniques you need to get started with this powerful platform so whether you're a senior developer looking to explore a new technology or a newcomer to.net Maui this course is the perfect jumping off point for your journey welcome to this course where are you going to learn about.net Maui while creating a context application in Dona 7. now let's take a look at the mobile application that we are going to create this is a context application we can add a contact enter the name email phone number and so on we can also delete the contact we can edit contact update it and also we can search contacts and you can see that we actually have field validation functionalities so this is not just a crowd application what is.net mode and what is difference between Dane Maui and darmin Forbes so if we look at this dynamite documentation from Microsoft you can see that it's basically allows you to create one code base but Target different type of platforms so in most cases you don't have to write different codes for different platforms you only need to write your code in one place and that one place can be deployed to different platforms you don't have to make specific changes for the specific Target platform but isn't that the same as subwin forms no it's not really the same once you create the donai Maui project you see in Visual Studio there's only one project that one project allows you to Target different platforms whereas in xamarin forms okay so this is the xamarin forms documentation from Microsoft you can see that for different platforms right this is for Android and this is for iOS researchers examples you have different projects right so there's there's going to be one project for Android and then another project for iOS and there could be other projects for Windows phones uwps but xamarin forms also has a shared code base here right that is itself another project okay so when you create xamarin forms application you will see different projects right many projects one of them is the most important one which is this shared application code it contains all of the logic and it forms but then you will see also another project for Android another project for iOS another project for uwp another project for Windows Phone for example so they're kind of similar but very different right practically very different so let's actually take a look at the uh in the major Studio how it looks like this is uh xamarin forms Hollow World application right you can see that it contains many many projects right and this the first one the portable one this is the uh project that contains the shared application code right most of your logic most of your activities your coding activities will go here right and then you have different projects you have to run them differently if you want to Target Android you know you set this one this project as the startup project right and then you run the application from here right if you want to Target iOS then you have to set iOS project that's the startup project and then you start your project from there here's the dynamoy application you only actually have one project and this one project allows you to Target different platforms so practically they're very very different okay so this is what I want to point out in this video and starting from next one we're going to set up the visual studio environment in order to allow us to create the Dynamo application in this video we're gonna try to go through the steps of setting up the environment in Visual Studio 2022 in order to make your video Studio ready for creating dynamoe applications right so this is the video Studio installer right you can find it in the search area once you find it go to your video Studio 2022 right in my case I have the Community Edition for 2022. once you update to the latest click on the modify button and then you will need to find the desktop and mobile application part right this part and it says.net multi-platform application UI development and you need to check it and then you just need to install it right in my case I have already done it and once you've done it you will be able to create a dynamite application so once you updated your video Studio 2022 and then you install.net Molly now you can create the project right so let's go through the process creating a new project and then these are my recent project templates but if you just installed online Maui for the first time then you wouldn't be able to see these so what you can do is you can go to the search bar and then you can type money and then you'll be able to see a list of applications we're going to select the first one which is a.net Maui app right and then click on the next one and we are going to name the solution contacts because we're going to create a contacts application and I like to name the solution after the purpose of the application so in this case it's a contacts app so I'm just going to call it contacts and then the project I'm going to have the purpose and then the type of project in this case it's a Maui app and then I'm going to click on the next one I'm going to select.net 7 I'm going to click on create here you have it this is the only project you see in this solution right for now later we're going to add different projects which mainly a dynamoe class libraries to support us to create applications in different layers right we can't just put everything in one project no companies does that so you will have to learn to separate different things in different layers which will reside in different projects different class libraries so in this case uh what you can do is first you can run it in Windows machine right but in this course we're gonna mainly Target Android but if you do prefer to run it in Windows then you may encounter kind of like a error like this right so it says Windows Defender Firewall blocked the broker.ex so you will need to allow access right you need to collect click on the allow access in order to be able to deploy your application to Windows environment very likely it will prompt you to say that you know you have to enable developer mode for Windows right and then you just click on the settings for developers right you will see the screen and then you just click on this button to turn on the developer mode this will enable you to deploy and run applications in Windows mode that's how you set tap the environment for Windows machine but what I would try to do is to go to the Android device manager right and then you will need to add a emulator in my case I'm using pixel 5. by API 3031 you just need to install the same thing you can you can use different mobile phone emulators but I chose this one and it's possible that you will have to turn on hyper-v right in order to accelerate the emulator so that it runs faster okay so this is the uh the options that you need to choose when you go to Windows features you turn on these features in order to enable typer V to accelerate your Android emulator so once you're all done then you would be able to go to Android emulator and then you can change this to Target you are selected Android mobile emulator right so in this case if we run the application it's going to take a while for the first time and then it will be way faster because after build it will identify the differences between the this build and next build and it will only deploy the differences instead instead of the whole thing right for the first time it's going to compile and then it's going to deploy everything into the uh the emulator that's going to take a few minutes depending on how fast your machine runs you know finally it deploys to the application and next time it's going to take shorter time but you can see that the application is deployed to my pixel 5 emulator and then everything runs you know normally and in the next video we're gonna go inside the solution of individual studio and see the project structure in this video let's take a look at the project structure of a donut my application okay so this is the application that we just created when you look at this application it seems like my program.cs is the start point of the application right and it does look like it's trying to create an app but let's think about this this application can be deployed to different devices different type of devices includes Android iOS and whatnot so how can this one program.cs be used in different platforms they must have their specific way to launch a application right so this is not actually the starting point the starting point is in the platforms folder so if you look at the Android folder you would have a main application.cs and then you can see that the main application.cs actually uses the my program so if we right click and go to definition we can see that this goes back to the Maui program.cis file and this is the create Maui app static method okay static function let's go back and take a look at iOS right OS is a different way to launch the app that's a main app uh but then it uses the app delegate and if you go into the app delegate a similar way of launching the program is being used right you can see that it also caused the same static method of course if you go into other devices where this one would be similar to iOS it uses the app delegate and then when you go to app delegate it uses the method right you can see that every single platform points to this my program.cs so our work mostly are not in here okay so we can just uh kind of ignore this for now right so if you have any uh specific platform code that you want to write then you can go over here but in Dynamite you don't usually encounter that situation very often so most of your code starting up code will be here and mainly about dependency injection which we'll cover later practically everything would be starting from here right we don't have to worry about the platforms further practically everything starts from this static method which will be invoked from different platforms right it starts from here and then you can see that it's trying to create a application I've done in my application right so we can go to this app this is the next place where we need to look at right so this app from the front end which is the demo and it doesn't have much it has a bunch of resources we don't have to focus on but let's go back we can see that it has a main page right every single dynamoy application has a main page and and it's just similar to xamarin forms it has a main page but we have a special type of main page which is called appshop so for donating a shell application is created by default right which uses this shell page you don't have to do it this way but this is provided to you as a default option which I I actually like it very much the shell becomes the main page and when you go to the Shell you can see it has the shell content right and then when you go go to the back end and there's nothing on it so the show itself is a opinionated way for organizing all of your pages in this case it points to the main page route to the main page which is just just a page you don't have to call it main page it's just a page one thing may be confusing and you have to understand that this main page is just referring to this one main page right this main page and then if you go to the code behind you can see that this main page is a Content page right the type is content page whereas if you go to the app go behind here this main page is the applications main page right it's a member of the application and the type of that is a page they are completely different object objects they are completely different objects so don't get confused this main page is not referring to this main page so we have IOS we have Android and we have Windows for example and of course we can have more but everything actually goes into this my program.cs we don't have to even worry about the the different platforms but kind of ignore this layer what really matters is that our Codes start from Maui program.cs and then this goes to app this app represents our application and every application needs to have a main page and in donat Maui the default main page is the shell page which is the app shell you don't have to do it this way but this is the default structure that is provided what's this app shell it organizes all of the other Pages for example we may have page one page two page three page four and no matter what type of hierarchy you actually have let's for example page one has two child Pages like two children and page two and page one are on the same level each single one of these pages will need to register to app Shell at least for routing purpose so this is the project structure of the.net Maui application that is provided out of the box again app shell and the way that it organizes the pages is a opinionated way for organizing the application and all of the pages you don't have to do it this way you can create your own page and make that page as the main page but in this course we are going to utilize the different functionalities that is provided by a shell page so let's look at the documentation from Microsoft right a shell page provides four different features right fundamental features but for me and mainly focus on this one right because the other three different features there are kind of implemented through this fly out and tabs right this this is the fly out and then you have different tabs and then you have your search bar here if you don't like this kind of UI structure you can still use shop application for at least registering different routes for different pages and then navigate to those pages with the URL based navigation scheme which we'll cover later okay so this is everything for this video the project structure of a.net my application I'll see you in the next one application is a stateful application that has a user interface what is a stateful application it just means that it needs to maintain a state in a state it just represents the data right it's just the data so in this type of application we have three basic elements that all developers need to deal with while we are creating the application so of course the first one is the state which is the data and then the view which represents the user interface the state will need to be displayed in The View let's put a user here and then user will then interact with the view and then that generates the events and then developers will handle the event which will in turn change the state and then this cycle goes on which means when the data is changed the view gets updated again and then the user plays with the user interface and triggers the event and then the state is updated again so Seiko goes on and on okay let's take a look at the application ourselves and see where are these three different elements in the main page so this is the main page we can see that we have this data here right which is the state and then the state is not initially displayed on the user interface where's the user interface it's represented by the xaml file so this is the xaml file we have this initial state that is not actually displayed here it just says click me right once the user clicks on the button which triggers the event then the events is handled by this uncounter clicked event handler then the state is changed and the state is manually assigned to the text property of the button so that displays the state on the user interface and completes the cycle right and the user can choose to interact with the user interface which means that the user can click on the button again and then this whole cycle goes on and on but this particular way of handling the events is called event driven development whereas in dollar Maui we have another way which is mvvm these two different ways handles all three different aspects of a development cycle right the state The View and the event handling in this particular case the event driven mode each event will have an event handler in the code behind of the user interface okay so this is the code behind and this is the user interface file right the event handlers are all in here and then we just make the logic Happening Here in the manually update the user interface mvvm will be covered later which is more organized but I just want to cover all these three different elements today so that we have a a map for our learning process in the previous video we talked about the download Maui application has three Essential Elements and in this video let's focus our attention on The View which is the UI element so a dynami application may have different pages in this video let's focus our rotation on a page right what is really on a page so let's take a look at this main page we have the Zumo bio and azamo.cs file the demo file represents the UI and the zamod.cs file is the code behind which provides logic and feeds data to be presented in the UI focus our attention on the UI part we can see that it's a page it's a Content page right essentially it's just a page so what is a page application may have different pages it's basically just referring to that area that occupies the whole user interface so this is a page and then inside the page there could be different UI elements like buttons images list views and whatnot so if we put them in a diagram to express this more clearly we have a page right and then the inside page we may have different UI elements under other development Frameworks like web development Frameworks we call this UI elements controls right but inside.net Maui we call this UI elements views this view is different from what we mentioned last time this View and last time the diagram is a generic term that refers to UI here these elements are called views each one of them is a view this is specific to the night Maui therefore in Donna Maui we have a page and inside the page we can have one or more views however if you put these views directly under a page you will get a error right for example we come over here we look at our main page we can see we have image we have labels right we have buttons these views the each one of them is a view is actually under a layout well this scroll view is also a layout the layout is directly under a page so therefore we cannot put multiple view views under a page we have to put them under a layout and then put that layout under a page in this case it's scroll View and then inside the scroll view it has another layout right it doesn't have to have another layout but in this case it has another layout so you have to remember that directly under a page there can be only one layout under that layout there can be more layouts views in fact a layout itself is also a view so let's actually go to the definition of this vertical stack layout you can see that it's derived from stack paste and then stack base direct from layout and if you go to layout it's actually derived from View right and if you go to uh for example the image we go to the definition you can see it is derived from The View so a layout is actually a view you can't see the layout but it's used for organizing the individual views group them together provide layout to them so therefore which you really have is inside a page there is a layout right so this is a layout and then inside the layout you can have multiple views and also remember that a layout is also a view so therefore inside a layout you can have multiple layout and then inside those layout you can have multiple views so the structure is therefore like this you have a page one page right and then a page can have single layout right and then inside the layout you can have multiple views if we remove this layout okay let's try to remove this layout you can actually see compile time error here is that the property content is not set more than it's set more than once right so what we are we're trying to play the elements inside a Content page which is actually trying to set the content property but it's complaining that it's set more than once that means that actually inside a Content like inside the page the content element can only contain one View right this is what it's trying to complain so therefore you can only put a layout here you don't have to have the scroll view any layout will do so if we delayed the scroll View it still works right at least it doesn't complain anymore uh but in this case it's just it just want to let it scroll as well that's why it added a scroll view so that's the first concept I want you to remember right which is this a page contains layout and then layout contain views the second concept I want you to know is the namespaces okay so we have these namespaces what what does it what does it mean you can see these are xmos right XML elements but why scroll view is uh recognized but if I put scroll view one then it's not right so automatically the the closing element becomes scroll view one but it's complaining that scroll V1 was not found so these namespaces um are provided here it's exactly like the namespaces that are provided in C sharp right so for example namespace.net if we don't have namespaces even um so so let's delete this you can see even the button doesn't even recognize right so we put namespaces so that we provide definition for our uh keyword that we use inside a programming language right so in xamo it's a it's another programming programming language that is created for Donna Maui right but where does these keywords uh where do these keywords come from they come from namespaces in this particular case it it came from the Steve file namespace right that's XML namespace which is uh microsoft.nemon and then you have uh extension right so for example if you want want to give it a name uh you can say x dot name and then you can say image one right so you give it a name but the name itself it doesn't come from the default namespace this is default namespace you see if I remove X then the name is not actually recognized right that means that this name property doesn't come from the default namespace it comes from uh this Microsoft zamo namespace so therefore if you want to give it a name you have to use x dot X call it sorry and then if you want to refer to anything that is within the main page uh for example this uh button click event which you can actually go to definition and then that immediately jumped over to encounter clicked so it knows this encounter clicked method in the code behind just because we're referencing the class if we remove this we will see that if we right click here and then go to definition it doesn't know where to go right and so if we put it back now if we go down and try to do the same thing we go to definition it will be able to jump over to the code behind so that's namespace and it's a very important concept that you would want to know because later when you code you thought that this is going to work but it's not being recognized that's just because you may need to add some namespaces okay that's everything I want to cover in this video I'll see you in the next one in this video let's talk about URL based navigation we are going to have three pages in this context application right we're going to have a main context page that is going to show a list of contacts and then we'll be able to navigate to edit contact page where we can edit page or even just view the contact details and then navigate back right and then we have another page add contact page where we navigate to add a new contact and then navigate back so let's jump into video studio and create these three pages so that I can demonstrate you how to do how to do the URL based navigation we can just start with adding these three different empty pages so let's go to create a folder let's call it views right and then we are going to have to add a new atom and here we're just type in page then you can see contact page let's select the xaml page c-sharp H that means that you are not going to have a zamo representation as a friend front end everything has to be added a c-sharp class so I would personally prefer to use symbol so that the front end and the back end are nicely separated right decoupled so let's select this and let's call it contacts page so this is the main page and then you can see that it has a title here and let's just delete the page and then we're going to add another one so we can add another one we can call it added compact page and then here we can just add a space and a delete page again and then last but not least we're gonna add another one and this is going to be called add contact page and again we're going to add a space here and then delete the page now we have these three different pages but if we run the application we're now going to see these three different pages so let's um start running it so just hit F5 right to run the application in the back mode run the application on debug mode um it triggers the hot reload for data Maui so that any changes you make in the xaml file will be reloaded and redisplayed in the application immediately you can see the application runs but no matter where I go right uh like it doesn't show those three different pages so before we implement the URL based on navigation let's try the how to reload so let's go to the main page because this is actually just displaying the main page right and if we change anything for example we change uh hello world to hello.net Maui and then if we save it and come back over here you can see that immediately the change is reflected let's stop debugging because we are going to make some call behind changes the code behind changes will not be reflected immediately so it needs a recompower and redeployment oh so let's go to the app shell like we mentioned before the shell provides URL based navigation and inside the Constructor is a perfect place for us to register the routes in order to jump to any pages with URL base navigation we first need to let the system know that we have these routes that points to these pages so one of the way to do it is to say rotting right there is this routing and then uh we can say register route and then here you can see that the first parameter is a string and that represents the key of the route or the name of the route but it has to be unique right for that we can say name of the class name so name of the contacts page right so context page we can do a control Dot to import the namespace and then here we need to provide the type okay so let's go to the second signature so the second parameter is the type we can use type of context page so basically now the inside.nymali the system it has a key and value pair so the name of the page is the key it doesn't have to be the name of the page you can call it anything but it's easier if we just use name of the uh the page right because that's usually unique and then the type so later when you navigate to this page it knows the type of the page and then it will be able to construct dynamically on demand in the memory and then show you the page that's just because it knows the key value pair it knows which type to instantiate right so we have another two routes so we're going to register the other two routes the name of edit contact page and then last one is I'm going to have name off and then add contact page and then they suggest me to to have the rest so I don't have to type everything okay now I register these three different routes right so let's demonstrate how we can navigate to these three different first of all I don't want the main page to be the home page I want the context page to be the the main page to do that we can go to the friend hand of that the show right here it registered the route in a different way so now I can say contacts page and then here it has this local and then you can see that this logo is a namespace right extended namespace where I can say local and then I can see uh what's defined under that namespace but our context page is not under the local namespace our namespace the context page is under contacts.my.views views so for that we can say views equals CLR namespace right and then here we're going to say contacts dot my dot views so it shows this directly here right so now we can use views to provide the type information right views colon then you can see those three different pages that we added earlier so we're going to use context page so basically this is the same thing as rotting.register route this route is the key provides the name if we navigate to definition you can see this is a string right for the shell content and then here is the type of that so we provide a name and we provide the type now if we run application we will be able to see the context page but there's nothing on it what we can do is we are going to add two buttons just for demonstration purpose later we're going to remove it so here there's a label already but we're going to add a button and then the button text is to say go to just call it at or added contact and then we are going to have another button and we're going to call it at contact and when we click on the added contact we want to go to edit contact page for that we will need to have an event handler to handle the click event to distinguish between this button and this button we will need to provide a name first like I mentioned last time you you need to use the X X extension to give it a name because the name property is not in the default namespace so here I can call it BTN add it contact right and then here I can call it BTN at contact now if I go to clicked I can tap to edit event handler and that will have our name in it right and this what it does is that is not only just created this uh it just assigned this string to this property but also create it a event handler in the code behind it's empty of course for now in here we're going to say new event handler instead of selecting existing one we're going to say new event handler and then now it has our name in it and then created another event handler here like I mentioned before we are going to create this a context application twice the first time we're going to create it with event driven development the second time we're going to use mvvm pattern the event driven development is easier to to learn so it gives us a lot of opportunity to understand Maui and then we're going to move on to mbvm which is usually used in different companies for mobile development so that's why we have these two different ways of creating the same application so let's continue here we're going to demonstrate how to do the URL based navigation we are going to say show dot current right so this is the current shell which is let's go to definition you can see that this current shell is a static member of the shell class right but it refers to the Shell that we have in here right so therefore it knows all of the registered routes so we are going to say go to async right and where are we going to go so here you can see that the first parameter is shell navigation state but but it's really just the string but it's not any string it is the key of a particular route so we can just say uh name off okay add it contact page then it's very simple it's just that we are navigating to this added page and then we can do the same thing here you can say shell right current we find the current shell and then that current shell knows our registered out so we need to provide a key here in this case it's contact page and that's it let's see whether it works or not okay now we can see that the page is displayed right instead of the original main page we're displaying the contacts page right we can see that two buttons are connected to each other so we will need to fix that first so let's go to the context zamo and then this is vertical stack layout what it means is that all of the views inside the layout will be vertically stacked on top of each other right but it has a spacing it has a spacing property here so let's put five here right it's a unit it's not pixels or anything it's just a special unit um and then let's go here you can see that it's nicely separated now now we can click on the edit contact button you can see that it navigated to the add contact page right and if we click on the back button it will navigate back and then we go to add contact you can see it it went to the uh at conic page click on the back arrow it goes back another thing we can do is for practice purpose we can add another button here and we can give it a name and we can call it vtn cancel right and the text is cancel this will take us back to the contacts page so we don't have to use the back arrow we are going to add a clicked event handler right and then I'm going to do the same thing on the edit page I'm gonna add a button I'm gonna give it a name I'm going to call it BTN edit com uh sorry ptn cancel and then we are going to create a text and call it cancel and now we're going to create the event handler you can see that it automatically knows that this has to be rebuilt so actually let's stop debugging then create the event handler right and now we can go to the call behind here and then here we can do it a little bit differently we can do shell current and then go to async this is the same but here we can use dot dot so dot dot you know in photo structure dot dot means the parent so can you start.t here to say that we're going to navigate back to the parent page okay which is the context page so we can use that you can copy this and go to over here and and we can say shocker and go to async.au it's the same thing now let's run the application so let's go to edit contact right we can see we are on add a contact page click on cancel this takes us back to contacts go to add contact click on cancel also takes us back to contacts right another thing that I want to point out is that if you want to use the actual name instead of the dot to go to the contacts page you can't just use the name of contacts page why is that that's because uh if we go to the Shell page you can see that uh the contacts page is the first page which is basically the main page right for main page shell navigation when you use URL based navigation you have to provide the absolute path right so the way that we are navigating uh in context page here we are just using relative path right the absolute pass it starts with slash slash so let's go to the documentation you can see that this is the documentation of shell navigation right you can see that the first level is the root right and it starts with slash slash so if you want to go to the the main page you have to specify the slash slash so let's go here right if you do this it's not going to work so how it's going to work you can use string interpolation here so we're going to say slash slash and then curly braces so this provides the absolute pass and this is going to work okay so let's run the application and then let's go to add contact right so now we are on the add contact page right here and then clicking on the cancel button this will take us back to the contacts page so again to navigate back to the main page you have to provide the absolute pass or you can use dot dot that's everything for this video I'll see you in the next one we are going to start creating a contact list on the context page and what we are going to use is list view so in this video Let's Start Learning the basics of using list View so a few videos ago I mentioned that there can be only one view on the top level inside a page so in this case you can see that on the top level is the vertical stack layout and everything is inside it we don't need the buttons we don't need the labels we will talk about the layout later today we are going to use list view so we can say list review and if we run it you can see that there's there's nothing on the screen but listview has background so turn on the background like we give the background some color for example Quran color it goes blue we can see that everything become blue right that means that list view occupies the whole page you need to know that list view is it's not like there's when there's nothing in the list it's not occupying the whole screen I need to know that it always occupies the whole screen uh and uh I'd like to give it a transparent background because in different devices for example another device is a different type of operating systems like Android or iOS the backgrounds color sometimes um is slightly different so to make it consistent just make it transparent also that you need to know that list View it automatically has the the scroll functionality so later when you know that there's some such a thing that called scroll view okay so you can actually see a scroll view is a layout scroll View is a type of layout of course there can be only one root view in here so scroll view a list view of the kind of uh conflicting with each other you can only have one top level so if you put less view inside a scroll wheel is going to work but but it doesn't make sense because list view itself already has the functionality of a scrolling uh if you add another scroll scrolling functionality on top of it it's going to affect each other so when you have a list view don't add scroll view if you go to definition a scroll view is a type of layout right so we don't need scroll view I just want to mention that when you have a list View don't add scroll View okay so we have a scroll view but there's nothing in it the first thing we need to do is to make scroll view display something so when we come to the code behind we can see that we still have the event handlers but we don't have the buttons anymore so we can delete the event handlers so now in order to show something in the list View right we need to have an array of something to display right so let's say we have a list of a list of strings and this strings we call it let's say contacts right and then we are going to have this and what's going to be inside it is just a list of and let's say there's Zhang and dough and so we have these names and then we will need to provide this data to the list so how do we do that we need to first of all have a name so that at the core behind we can have a reference reference the list View so we have list contacts and then we can say item source item Source the type of item source is I enumerable so we can put contacts over here and now let's run the application and see whether there are any changes now you can see that we have these contacts nicely displayed in the list View so this is a very very basic data binding when I display this list view in here you can see there's separators rather separators and if you click on it right basically when an item is selected there's a default color highlighting which item you selected so if we go over here and let's format it nicely different properties in here more attributes and then there's a there's a separator right they're separated color uh they're separator visibility if you don't like it you can turn it off okay if you want to change the color for example I want to change it to let's say agua just for demonstration purpose I don't like the the color but you see the color has changed right and if you don't like the separator at all then you can use visibility you can set it to none and then coming over here you can see that there's no separator anymore I do like the default one which is showing the separator but maybe we can change it to Silver all right change it to Silver and then uh the color becomes simmer which is very similar to the default the next thing I want to show you is to actually bind it to a class right we can't always have data in in a stream because contacts has like names phone numbers uh maybe emails maybe addresses so it's better to use a class to do that so let's stop debugging and let's create a contact class over here uh later we're gonna separate that kind of class in the different class Library which is the correct way to do things when you go to a company you will never see people have the class defined in in the same file right there are two different classes in the different seminal sometimes it happens but most most of the time you have your core objects right so core classes the business core classes in a different class Library which we're going to do later we're going to follow the clean architecture or the clean code approach right for now for demonstration purpose I'm going to have a class over here which is going to be called Contact right and then we are going to have just some simple properties for example maybe you will have a name maybe maybe email instead of a list of strings we are going to have a list of contacts list of contact over here change to contact and then we're going to initialize uh this contact so I have a list of contacts and now I don't have to change this and let's let's run it and see what's going to happen okay so let's speed it and run it again all right so we have something displayed but this time unfortunately these people are not being displayed but class names are being displayed right the class names along with namespaces being displayed why is that so the default behavior of assigning a list to the item source is that the list view will take each one of these object and run at two strings when you run a two string whatever it gets it will be displayed right so for example if I set a breakpoint over here right and then I'm gonna stop it and run it again and let's trigger the breakpoint and you will see what I mean okay so we have this contacts so let's actually do a quick watch and then if I do like take the first one which is zero in the index we can see that we have the first one which is strong though and then if I do a two string let's see what is the value you can see that the value is exactly the one that is being displayed in that list right so this is what I mean when you just bind when you just assign the context to the item Source it's going to take each one of those contacts and run a two string it's going to just display that the result of two string inside the list so in this case it's just the namespace plus the class name so that's not really what we want right of course to fix this problem you can come over here and override the two string method so that you can display whatever you want but that's not really the proper way to do it in Dynamic mode a correct way to do it is to use data binding which means that we assign this the item source that is actually okay well we need to tell the list view what to display and how to display it and the way to do that is to go to the front end in the demo file and then over here we need to give it a template right so because we are trying to tell a list view exactly how to display the item so we need to specify that in in the template and we can use we can say less view dot item template okay this item template because each item in the list is an item right that's why it's called item template and then we have data template so the data template is basically just just the item template and inside it we can have a different type of cells we can have view cell which is the most flexible approach uh there's uh there's this image cell right and there's the basic one is taxa so we can try to use textile for now the tax of that is the one that I want to show for now so what is the tax of that we can see binding finding and name all right so basically with the curly braces we are just saying that we are targeting a object right so if you have worked with JavaScript before a credit brace refers to a object so what is the object we are referring to it is the one that is is being bound to the item so what is being bound to the item you can see that we have context as the item source so of course each item is a one of these contact right so this without specifying The Source by default it refers to the contact object right which is bound to the item to the item we're specifying an item template of course this is referring to the object that is bound to the item which is a contact so that's why in here this binding just means that we are referring to the object that is being bound to the item and then here we're just saying what is the pass we can say pass equals to the property of that object which is name all right we can see that you won't get any intelligence over here it doesn't really know it's just a string right this this is just a string so it doesn't really know but uh you you just have to type it directly so so here the path is a default property of The Binding class and you can just put name directly over here because of the default property so you can omit the pass so you can put name of here it just tells that name Maui that we are trying to display the name property of the contact class right the context object so what's this change if we run the application [Music] now you can see that the names are being displayed again right another property of the text cell is called detail so I'm going to show you what it is now this detail is also a string but again you can use binding okay so we're binding to the property another property of the context class and of course the only other property we have is the email so we can use email now let's see what it looks like let me come over here you can see that we have the names and then the detail at the bottom the names are highlighted it's pretty nice but if you think that everything is kind of squeezed together so it can change the the height of the Rope right or to hide them the item but it's called row height okay so for example if we say 100 and then let's take a look at what it looks like each one of those pretty tall so maybe change that to 80. and that looks much better uh it's still too much maybe 70 yeah 70 looks much better say let's say 65. so now it looks much better so these are all the things I want to cover for today we basically cover some basics of list view right how to data bind to it how to adjust the appearance and in the next few videos we are going to use list view for our Connex application I'll see you in the next one do you still remember this map that we mentioned a few videos ago so in the previous video when we cover the basics of list view we covered the view which is the UI and the state which is the data and also how we map the state to the view right which is a basic data binding that we covered in the previous video in this video we are going to cover basic events for list of view so that we can actually do something with studies let's come to our solution and let's go to the context page when you have a phone and has a list you really use a finger to tap on item of a list so there are a couple of events that we are interested in one of them is called item selected so let's actually try to handle that event and see what happens okay so this generated a new event handler which automatically showed up here let's actually set up breakpoint and run our applicant see whether it's triggered or not okay so I'm going to run the application okay so I'm going to click on one of the item and you can see that it's triggered this breakpoint right so let's continue and if I click on the next item it trigger the breakpoint again so we're going to continue but this time we're going to click on the same item so I clicked on it so I'm going to click down a few times you can see that this breakpoint is not being triggered so what does that mean it means that this event handler item selected is only triggered when item selection has changed right at the beginning there's nothing selected so you click if you click on any item the selection changed from nothing to one of the item right the item that you clicked on and then when you click on something else another item then of course it's going to trigger the event but if you click on the same item it's not going to trigger the event right so if you are going to use this event handler to do things then you have to face this problem so there are a couple of ways to fix this problem one of the ways is to deselect the selected item right inside this event we can just use list contact dot selected item so we can set it to now so basically you do your logic here right your own logic and then at the end you can deselect it okay so let's run the application again and to see the behavior so now if I click on item but you can see that the event is triggered right and if I run the application again you now notice that the item is not being selected right because we deselected it again so this event is going to happen over and over again just because we deselected the item one thing we can use to test the application to is to use the built-in display alert right so we can display a message so this is going to be for example test and then the message is test and cancel is let's just say okay right and we run the application again now we don't have the breakpoint but we have a message you can see the message and we click on the OK button the message disappears and I can click on the same item and Trigger the alert let's take a look at another event let's go to the demo file and another one is called item tapped right so let's create a new event handler and then let's go to the code behind again you can see a new event handler is generated so again let's set some breakpoint and then let's run the application again to see the behavior to see whether there are any differences between the two okay so the application runs and we click on the item you can see the first event is triggered is the item selected and then if we continue then the second event is triggered again right so this item tab is triggered afterwards one of the more reliable way to just select item is to actually do the deflection inside here inside the tapped event I'm going to do it here and then you handle your logic inside item selected why is that why is that it's because this item tab event is always happening right whether you're selecting an item or not selecting an item whether you tap on the same items or type on a different item right therefore the this event is triggered way more times than the item selected event right so to handle your logic you don't want to put your logic inside here if user use their fingers to tap on the item like very very quickly this event handler is going to be triggered many many times right where this one is triggered less so therefore we want to do our deselection here and we want to do upper logic here because you don't want your logic to run inside here because it's going to run for many many times right so this is a more reliable way to put our deselection over here and putting our logic inside item selected is better so to give it a test make sure that it actually works we can whatever display alert inside here okay so we're gonna do test and then I'm gonna say okay and we're going to run the application again so when I click on an item and we see this alert click on OK click on another one we see the alert and you can see that that this selection is happening right nothing is being selected so this is the exact Behavior we are expecting here you will notice there is actually a bug I think it's a bug for item selection right for this item selected event this event is going to be triggered twice if we use we try to deselect right so let's take a look at the behavior I click on this and then we have actually let's disable let's remove the breakpoint so I click on that already and then now I click on the OK button but you see that I clicked um the okay button already but this alert dialog is not disappearing I'll have to click on the OK button again right so it appears that I click on the same button again but it's not the case it's actually what uh what's actually happening is that this event handler is triggered twice so let's put the breakpoint back again okay and then let's click on any of the item and run it again and you see that it happens twice right so now there's actually two dialogues that's why we need to click on twice um I think the logic here is that this is this shouldn't be called item selected it should be called unchanged right item selection changed what is happening is that first time you click on the item the selection the item selected changed from now to something and then because we deselected here so the item selected is changed from something to know and that triggers the event again right so I think it's a bug but we always have a workaround to solve this problem we can just say if list contacts dot selected is not now and and then we put our logic inside here right so our logic should be inside here we only deal with anything if there is actually a selected item right if there's no select item we don't need to do anything so if we run the application again now you should see that the alert only triggered once so let's run application okay so let's try that click on this we have this alert click on OK button it disappears right away right so upper work round works so now let's actually put our logic here so what do we want to do we want to when we click on a contact we want to go to that contact right so uh which means that we want to go to the added contact page so for that if you remember our logic is to use shell dot current dot go to async we can directly call it this way or we can use our weight and async and then we can go to the page so for that we're going to say added contact page and then later probably in the next video we're going to talk about how to pass information when we navigate to another page today we're just going to navigate to the page because we mainly want to focus on the event handling of the list view okay so let's click on any of the item and we're looking at the added contact page now cancel button going back click on it again I'm going to add a contact page okay so that's everything I want to cover in this video I'll see you in the next one we already have a contacts page the next step is to create an added contact page to be able to see the details of the contact and be able to add it to contact before we do anything if we look at the context page we can see that we have the hard-coded list here right and then we have the contact class the core class that is defined right on this page uh the code behind of the page so that's something we have to fix before we can continue so I know that I've mentioned eventually we're going to have a clean architecture but for now for the purpose of learning we are not going into the proper architecture right now we are going to create a folder right in the same project and we're going to call it models so we are going to have our contact class defined inside the models folder okay so I'm gonna cut this piece of code here and then I'm going to create a contact class here inside the models folder is going to call it contact all right so this is going to be a public class and then actually I'm just going to replace this with this and to Define this class properly at least we're going to add another property is there's going to be more properties later but for now we're going to have a contact ID right so when that is done when we come back to our contacts page we can still see we have this list color coded here how do we deal with this now let's look at this width this is data right so I know that we are hard coding that data but whether we're dealing with the in-memory to the storage or we're dealing with a file to store the data and then later we'll retrieve the data from the file or we're dealing with a database and we retrieve the data from database into our application we need to have a central place to encapsulate data operations meaning insert data update data retrieve data and delete data okay we need to have a central place to encapsulate those upper operations we can't let those Logics scattered in our application everywhere for that we can use repository right a repository is a central place where those operations are encapsulated right a shield of replication from doing those operations so that when we replace the repository with another one then we can do with data from different sources right we can never repository for a memory we can have a repository for file and we can have a repository for database right for in memories databases are pretty good for quality assurance right to fake some data from files we don't use that often from database is very good for enterprise level development for now we're going to have a simple static repository and later we're going to create proper repositories and then we use dependency injection to inject the repository into our replication and to do that we're just going to create a repository class enter enter the models folder and we are just going to call it compact Repository and this is going to be a static class this is a repository which serves the purpose of doing all of those data operations within the memory right of course later when we use clean architecture we are going to have different repositories to deal with databases for example and then we we're going to use dependency injection to inject those repositories into our application logic layer but for now we are going to only have this to deal with in memory now it's going to be a static class and then we are going to have a static list okay so let's go back and just uh basically I'm just going to cut this part and then we're going to replace this so we initialize this data with four contacts so that at least we have something to see before we add a contact right so we have this and of course we need to have a method for get all of the contacts so we are going to have a list of contact right and then we can have get contacts and this is just going to give us all of the contacts and this has to be a static method perhaps we are going to add another one okay and this is one single contact so we're going to say can't get contact by ID right and then we're gonna put in contact ID and then we are going to say return Dash contacts um should use Dash well it doesn't matter we don't have to use stash but I'm choosing to use stats in dash in this course I mean not Dash underscore so any score contacts underscore contacts and then over here I'm just going to say first or default we use Lambda expression and contact ID equals to contact ID here this contact is from within this namespace which is this particular contact right so so now we have get contacts we have get contact by ID and I think those methods are good enough for now let's go back to our class here we have the contacts so we are just going to use our contact Repository inside this class and then we're going to say get contacts and if we run the application again we should have everything that we have seen before now you can see that it complains about the contact inside the contact context page it says contact is a Amigos reference between our own contact and there is actually a contact inside the communication name space so in order to refer to our contact we're going to use something like this I'm going to say using contact equals contacts dot my DOT models dot contact so this right tells our code that when we refer to contact inside this file we're referring to our own contact instead of the contact under the communication namespace okay so let's try to run the application again now you can see that all of the contacts are listed in the list view that means our static repository is working for us so now we are ready to go to the next step which is to create the edit contact page currently we do have an added connect page if we click on it we go to the add iconic page but there's there's nothing in it right we need to view the video's information on the connect page first of all right and then we can deal with the update uh to in order to see the iconic information on the ad iconic page we need to know which one we're looking at right which contact we're looking at or basically we're we're saying that we need to know which contact the user clicked on in the contact list page right so to know that we will need to pass information from the contacts page to the edit contact page and how do we do that so if we look at our contacts page when the user clicked on a contact item we are using URL based navigation to navigate to the added contact page and if you have done any uh web application development or if you just go online you have seen those patterns that uh in the URL we have a question mark and then there's equal sign and afterwards there's some strings after that um so that is called a query stream right so here because we have the URL based navigation in Dynamite it actually borrows the same concept so we can pass those information from a page to another page when we use URL based navigation in Dynamite so let's see how we do that here here we can pass different things not only just streams but for Simplicity we're going to learn with strings first right so um basically here we are just going to say something like you know which page are we going to right and then we can use the question mark and say you know contact ID equals to whatever and then on the ideaconic page we can receive this contact ID so in order to do that we are going to let's roll back you can see we're using name off but let's see use a string interpolation here right with Kerdi braces and then here we can just say let's let's use ID so just for Simplicity right ID and what is the ID uh it's the selected item this list contacts dot selected item and then this selected item is a object but we can cast that into a contact object right so let's do that once we cast it into contact object then we can know the contact ID so here this is the query string parameter and this is the value right we can receive that information on this page which is the add edit connect page so let's go to edit connect page so this is the code behind of the ataconic page here in the edit connect page in order to receive the parameter value that it passed from the context page we will need to have a property and that property should correspond to that parameter value in this case we're receiving a contact ID so it's a property and we only need to have a Setter so this Setter will be triggered when the information is passed over to the added contact page right so then how do we know that this is the property that should be triggered right this is the setter of the property distribute trigger on the class we can use a property and we're going to say query property right query property and the correct property has has two parameters the first parameter well let's talk about the second parameter the second parameter is actually the query ID and what is the query ID it's basically this parameter this the name of this parameter so in here it's just called ID which is the second one I'm tapping the second one right and what is the first one the first one is the name of the property right so here we can say name of contact ID right so name of the property so basically this query let's stop this right so basically this query property is telling us that whenever we receive the parameter value from the previous page which is the context page we will map that parameter value to this property okay and this property is right here and then when that happens the setter will be set and the value of that property is within the value right within the value uh you know in the center we can call Value is within here so now we actually have the the value of the contact ID right inside the center what should we do here we need to call the contact Repository right dot get contact by ID which we just created right and here we have the value that we need to pass in and of course we can use anti-parse parse that into an integer uh if the value is inappropriate that means we need to throw exception we should let that exception draw because that's a coding error right so we get the contact and then we can store that contact in in a private variable here and this private variable we can Define it inside a co-behind class and it's going to be of of course a contact and contact uh that's it so here which contact class are we are we referring to we can use the same remember we are using the same approach that we'll use last time so we need to specify that we are referring to our own contact class that we Define in the models namespace in dot contact and in the setter we basically set the contact so now we have the contact in order to prove that we actually received contact let's go to the front end of the ad iconic page and we see a label so let's give this enable label a name right and so let's call it lbl interesting name and then once we receive the contact we're going to assign that contact right to the label so that we can actually see it and let's run the application and let's see whether we can see the contact name or not okay so let's click on Tom Hanks if for whatever reason we're seeing John Doe and that's pretty weird I don't know what's happening so let's actually debug let's go to the contact first let's go to the contacts page right and let's see whether the selected item is actually correct let's actually go back and then I'm clicking on Tom Hanks so the selected item let's check what it is it's id0 of course it's ID 0 because we didn't actually provide ID Let's uh that's my fault let's go back to contact repository I didn't provide ID so everything is zero so that's why it's John though because strando is the first item so let's um give the ID over here provide the ID for each one of those item of course we need to change them to one two three four and let's run the application again okay let's try myself let's remove the breakpoint I think it's gonna work okay so I can see my name go back Tom Hanks um I thought I removed the breakpoint but anyways I've tap Tom Hanks so that's correct let's try one more which is John Doe so I have John Doe so everything looks correct so in this lesson first we learned about creating a stacking repository this is mainly for teaching purpose creating a static repository for you is mainly for let's say you're creating a mock-up right or uh you're faking the repository so this static repository will provide you with a convenient way a quick way to mock the data right and the later you can use cling architecture the plugin based clean architecture to plug in a different Repository okay so or you can use the static repository to provide you of the fake data for testing purpose let's say you're in the QA team and then you want to use a different data than the real data then you can create a simple static repository to provide the data but anyhow I don't prefer the static repository like I said the static repository is mainly for teaching so that we can quickly have data and we can uh still use the concept of repository to encapsulate all of the data operations within a central place so that we don't have all of the data operations scattered everywhere in our application right I wanted it to be encapsulated in a central place so we learned about this concept we created this static repository and then we learn about passing information from one place to another right one page to another here we're passing through the query parameter right and then this is the value and then inside the place where we receive the information right we use we first create a write only right a right only or set only property to receive that and of course the the type of that should be the type of the parameter that is passed in from the other page and then over here we use a attribute okay and this is the query property attribute the first parameter is the name of the property and the second one is the name of the parameter right the query string parameter right and then you're going to receive this and that's everything I want to cover in this video I'll see you in the next one in the next a couple of videos we are going to work on the edit contact page and for that we need to familiarize ourselves with stack layout right currently if we go to the added contact page we can see that there's the vertical stack layout actually there's a stack layout and the orientation can be either vertical or horizontal in Dynamite there's actually for convenience purpose there's a vertical stack layout and a horizontal stack layout the default orientation of a stack layout is a vertical stack layout okay so if we do it this way then it would be the same as uh the vertical stack layout before we change it right so if we let it run and then we use hot reload to see what's happening when we make changes then we can see that they are the same okay the application is running let's click on one of the contact to go to the added connect page right right now we have the stack layout and it looks exactly the same as the vertical stack layout right because the default orientation is vertical okay let's learn about several things about a stack layout first we have this orientation which I mentioned so let's actually put it on the left side and then over application on the right hand side so I'm going to put it over here and then I'm going to drag this over to here and then let me minimize solution Explorer so let me actually uh comment out look actually let's comment out the whole thing okay to make it clearer coming out the whole thing and then let's go to the code behind and let's comment out uh this and we don't have the cancel button so let's come and not this all right so let's just focus on how stack layout works for now okay so let's add a empty stack layout right so what we need to know is first of all we need to know some important properties of Stack layout so let's put something put box view right box view is basically a view that looks like a box so it's very good for placeholders and it's very good for us to understand how layout works we can specify the color of a box view so that we can see the size of the size and position of the Box view right so if we just do it this way you can see that there's nothing on it right that's because we didn't specify the size so let's specify the size and we can use box view to understand how the fuse in stack layout position how the size and position worked I'm going to add another one and we're gonna make this one let's say it's going to be blue right and another one maybe red and another one maybe yellow right so if I save it you can see there are different things so this tells us that in the stack layout each one of the child views are stacked together right up and down because the orientation is vertical right because the default orientation is vertical so each one of the child views are stacked together right so agua is the top one at the blue red and yellow so you can see agua blue red yellow so if we change the stack layout to horizontal stack layout and then if I save it now we see nothing why is that to answer that question let's change the height request to West request and then click on the save button you can see that everything is showing up and agua is on the left obviously everything's stacked together again but it's stacked from left to the right right the vertical layout stack views top to bottom and horizontal stack layout stack views from left to right right and there's an important property that we need to understand which is the spacing right now you can see that each one of the Box views are connected together right so if we specify a spacing here then you can see that there's a space in between right so if we change this back to vertical then of course we have to change this to height then you can also see the gaps another thing that is very important is for a vertical layout a control like a box view button for example by default it fills the entire screen from left to right right and if it's a horizontal stack layout by default the Box view or buttons those controls or views will fill the screen from top to bottom right that's the default Behavior but you can modify that by specifying the with request so let's say the width is 100. right so if I do that notice that the agua box view is changed right and then this is only 100 from left to right right that's the width right so if I specify all of them all right they look like that then the question comes like how do we configure the position of the Box view it's always in the middle if there is horizontal options right and by default the horizontal option for a box viewer or a button um is Center but we specify start then now you can see the Box view move to the left and we specify this as a center and then specify this as right sorry and then you can see that Center is Center start is Left End Is Right right and deep default the yellow one stays as default default is also Center so for a vertical stack layout you cannot position child views vertically because they just stack on top of each other well there's nothing to control okay but you can configure the height whereas for a vertical stack layout you are able to configure the horizontal positionings right and you have three options Start Center and end now when it comes to a horizontal stack layout so let's comment out this copy make a copy and then come down this and then let's change this vertical stack layout to hurry horizontal stack layout of course now the Western height kind of flips so we're going to change this to 100 and with 250 otherwise it will look very very weird because we don't have enough space from left to right now you can see that everything is in the middle the horizontal options is not going to work because for a horizontal stack layout we can only control the positioning of the child views on the vertical level right on opposite level so what we can do is we can specify the vertical options for vertical options then we can specify start Center and end so when we do that you can see the start goes to the top right because that's the agua and then blue is in the center and red is at the bottom by default we don't specify anything a state at the center right so now you can see that for a horizontal layout you can specify the position vertically whereas for a vertical layout you can specify the position horizontally right using the horizontal options whereas when it's a horizontal layout you can use it vertical options right so that's the takeaway and other than that the spacing is very very important of course again for vertical stack layout you use the height request to specify the size and then you use the width request to specify the size for a horizontal stack layout now let's comment out the horizontal stack layout and then we go back and use the vertical stack layout well let's add a label actually because label behaves differently uh from box view or a button so we're going to say text test label now you can see that it appears at this position so what is this position this is horizontal position and that's the start horizontal position right so if we were to say horizontal options start and it's not going to change anything right so let's also add a background color to say this is let's say gray and now now you can see that the label it's not like if we don't specify the West request of the Box view the whole thing is going to fill the entire screen right on The Wiz whereas for a label it does not fill the entire width but we can use the horizontal options to say fill and when we do that you can see that the entire width is occupied by the label right because the background actually tells us how big it is and again we can use the horizontal options to specify where the text is positioned now you can see that they are positioned differently according to start Center and end right so left middle and right another thing you also want to understand is that layout not only a stack layout all of the layout can be nested right so for example if we put another horizontal stack layout inside the vertical select layout so this is going to appear at the bottom because it's the stack layout right it's a vertical stack layout uh and then we are going to put a label and we're going to say text equals name right and then we are going to say entry so this entry is basically an input field right entry over here and now if I save it what does it look like well you can see that this there's entry field here you can see the the keyboard is showing up so this is a entry but you can actually notice that there is a kind of a misalignment remember that for horizontal stack layout we can actually use vertical options to specify the alignment vertically right so let's actually use vertical options here let's say Center right so that we can align them together vertical options in the center so I'm going to save now you can see that they are aligned together beautifully right so let me remove these squares and if we even put words here you can see that words is aligned with the label name so everything looks perfect and then of course if you want to add a spacing between the label and the entry view that you can use spacing over here and let's say we put five there then added a space here nicely right a gap okay that's everything we want to mention about stack layouts right whether it's a vertical or horizontal let's go ahead and actually work on this this page but remember that we only have two views two meaningful views right a name and email maybe let's add a phone number right and perhaps also a address let's actually uh stop this so we have a few other views and then we can come over here to our contact page and let's delete these experimental layout here and let us add the actual fuse so here I want to use a horizontal stack layout to add the child views right so we are going to have a label just like what we did just now and then this is going to be um the name of the person right and then we are going to have a entry field for it for now there's no data binding yet and of course we're going to add vertical options Center and then another vertical options Center over here now we're going to copy this and we're gonna repeat this a few times all right because the first one is for name the second one let's for email second one the third one is for phone number and maybe the last one is the address okay now you can see we have our name email phone number and address right uh things are not actually aligned properly so for vertical layout we want to add a margin and we are going to say 10 0 0 0 then when we do that you can see that the left changed so this is the margin left this is the margin top so let's say I'm going to put 10 on the top as well then you can see that it actually moved down a little bit right so maybe uh the margin 10 is not enough so let's specify 20. right so that's better and then you can see that uh the entry fields are not aligned to the left so then how do we fix that problem we can specify the wish request for each one of the labels all right let's say each one of them is 80 and then you can see that they are aligned together but it seems that 80 is too much so maybe uh let's say 60. now that looks much better but if you want to make a little bit better we can add a frame around the horizontal layout okay so when we do that you can see that name field becomes like this so why this side the right hand side is sticking to the Border that's because we didn't add a margin here so uh we so this is remember this is left and this is top and this is right so we need to add the same margin as the the left margin so the right margin now becomes 20 and now you can see that the frame basically provides a border and it has a radius so that looks pretty good but then it's too big right it's too big so but we can specify the padding all right the padding is the inner side right margin is the the outside and the padding is inside if we specify zero to all of them then it becomes like this it doesn't looks really good so let's specify the left hand side to be 10 and the the right hand side to be 10 as well then now it looks pretty good so maybe we can add top padding to be two and bottom to be two and make it look a little bit better right so now we can put frame on each one of those horizontal layout and now we have all of the views beautifully displayed on the screen perhaps I want to see a bigger gap on the top so maybe uh 20s the top margin so now everything looks much better so that's what I want to cover for this video and I'll see you in the next one in this video we are going to continue working on the edit connect page okay so we had this these fields displayed but one of the things that the added contact page needs to do is to display the contact information so we're going to work on that first in this video let's review we added the phone and address views in the connect class so now we go to the contact repository maybe we should you know initialize them maybe we don't have to right we don't have to initialize them so let's review that we do have this get contact by ID method already so this will help us to pull the information right and then let's go to the edit contact page and let's review that we already have this uh parameter that is passed in right and this property receive the ID parameter from the URL and that retrieve uh the contact object from our Repository and here we're supposed to assign the information of the contact to our views right here we have this these entries later we're going to use data binding but for now we're just going to use name right we're using the event-driven approach first and then followed by mvpm so now we're going to use names to reference so here this is this is entry name and this one would be entry email phone number last but not least address okay so let's go to the code behind and let's assign those values over here so Ng name Dot text equal to well first of all this get contact by ID matter May return nothing right if the ID is incorrect that shouldn't happen but just to be safe we are going to say if contact is not now then we are going to assign values to these views right so this is name and then we have entry dot address TX text equals contact dot address email all right so we have all four views in here while we are here we're gonna put this cancel button back okay so let's go to the front end also put our cancel button at the bottom okay and let's delete the original stack layout let's put it over here at the bottom and let's run the application to see whether we can see the information of the contact all right okay it's running so let's go to one of the contact now you can see it's pulling the information in we can see the name we can see the email we don't have the phone number and we don't have the address click on the cancel button to make sure that we can go back to our contacts page all right let's go to another one make sure it's polling the correct information all the time right all right it's doing pretty good and we're going to try all of our contacts and this time it's Jane Doe so that's pretty good so that's pretty good now we should work on our updates for that let's go to our repository first and let's create a update method again it's going to be a static method and it's going to be a void function and I'm going to call it optic contact and first of all we're going to have the ID to specify which contact we want to update and then we're going to pass in the the information that contains the information that needs to be used to update existing records right so first of all we will need to make sure that the ID that is passed in is the same as the IDS in the contact object right so if they're not the same I'm just I'm just going to return right and at this point they're the same so because we're using a memory database so we may encounter a problem here but we will try to fix that problem when we encounter that for now let's just code normally right so what are we going to do we are going to um use the get config by ID right first of all we're going to get our Target contact to be updated right so contact to update equals get contact by ID and we just provide the ID here and we need to make sure that contact is in the data store right so if it's not now then we start updating eventually when we use a database for example we're not going to do this but for now we will need to update a few manually of course we're not going to update the ID but we are going to update all of the other views so we have email name and phone number if you want to use automaper for example you can use that but I think we don't have a lot of views so I'm just manually populating them again if you're interested you can check out Auto mapper right but I'm not going to use Auto mapper in this course so now we have the update contact method right and let's go back to our front end and we need to add a button and that button is going to be the contact button right do we have a spacing here we do have a 10 spacing so that's pretty good we don't have to adjust positioning so this is going to be called BTN update and of course the text is going to be update and we're going to generate a new event handler here by doing this right and let's just click right click on it and then go to view then we can see we have our new method here so this is the event handler and here we can use the category repository to do the update right we have the update method already remember we are not using data binding so we will need to get information from each one of these fields right so what should we do we can say contact remember we have a contact already right defined over here and it's populated with the contact ID method the setter the contact ID property right with the setter here so we can say that contact dot name equals entry name.txt contact Dot address equals entry address dot text so one of the reasons to use mvvm is to eliminate the process of autumn manually populating the fuse right that's one of the reasons imagine you have a lot of fields and you have to do this many many times that's that's definitely a pain okay so I have all of the views populated now I can say contact dot contact ID right and then here I'm just passing in the contact object okay so after I update the contact what do I do of course I'm going to just navigate back to the previous page which is the contacts page so that's the same effect of clicking on the cancel button okay so let's give it a try and see whether it works or not all right so let's go to any of the contact and let's for example add a phone number is putting a random number here and then I'm going to click on the update button but before I do that let's go to the configure repository and then let's set a breakpoint here right I'm expecting a problem but let's see whether we have that problem or not okay so I have the counter id4 which is correct right and then I have the phone number in here but let's take a look at this contact object and let's find the last one which is number four right and you can see that there is already a full number you don't even need to update why is that like I mentioned just now this is a in-memory data store and when we call the get contact by ID we're returning the object inside this list so basically this reference is returned back so therefore when we are um in the added contact page when we when we handle the update event we already updated that object in the list directly then we don't even need to do the update here because it's already updated so that is incorrect because in the actual data store we don't return a reference of the object in the in the server right so so for example if there's a SQL Server there is an instance of the server that's running that's true but we don't return that we return a copy of that value right so therefore we will have to stop debugging and we have to fix the problem so how do we fix that problem we have to return a copy here so this is the contact that we found right and uh we're gonna say if contact is not now then we're gonna make a copy right we're gonna make a copy of the contact if the contact is now and then of course we're just returning now here okay and also most importantly the contact ID has to be populated as well okay so we fixed this problem here but remember that we actually use the get contact ID get contact by ID method down in here and then we updating this contact to update but however because we created a copy of the contact so we cannot use the get contact by ID anymore because this is a copy we Our intention is to actually update the object in that list right in which list in this list so what we can do is we can actually just copy this right we use Lambda expression to actually find the uh the contact to update so we change this variable to contact to update and change this variable to contact to update and then we close our if statement and then we put our uh logic inside this particular if statement okay so you can see that we use we directly looks for the contact object whose ID is the same as the ID that is passed in and then we if we can find the contact to update object then we update it so this time it should fix our problem and then let's run the application again okay let's choose one of them for example if I choose myself and then let's actually make a change in the email as well so I'm gonna put a dot between Frank and you so instead of frankly it becomes frank.lu and then I'm just going to put a a random phone number here if I click on the update button it's going to take me to the contact list right let's uh set up breakpoints do setup breakpoint and make sure that everything is updated properly right so let's go over here we have the contact ID that is passed in and we are able to find the contact to update and then we are updating them updating the the information so let's actually look into our list and let's see that you see that email is updated and the phone number is populated okay so let's continue and remember that we provided we we changed our email address we added a dot in here so let's continue in and watch right now you can see that this frankly you at email address did not change right but watch carefully if I click on this contact list item again going back over here you can see that the dot is here right the dot is here click on the cancel button go back dot is gone so that's a problem and we are going to work on fixing that problem in the next video in the previous video we're having problems of updating the contacts page so let's go to contacts page and see what's happening so we have this Constructor here where we actually use the iconic repository in the Constructor and we get the contacts and we assign the contacts to the item source so you may be thinking that this is the reason because the contacts page once it's activated once it's created it lives there in the memory and when we are back like when we never get back from the added contact page to the contacts page uh this will not be executed so if we can find a place to activate uh to call those two lines of code again we might be able to solve this problem so let's actually do that okay so I'm cutting those two lines and we're trying to override one of the event in the event cycle which is uh on appearing okay so this online appearing is going to be called every time the page regains the focus for example if another page is on top and then when we navigate back to this page then the unappearing will be called of course when the page is just created and the first time it appears the element appearing is going to be called it seems to be the perfect place to um to call these two lines of code and let's actually try that okay let's run the application yeah okay I'm going to go to Tom Hanks and I'm going to make a change right had a thought again and then I don't know his phone number I'm just going to use Toronto's phone number for example random phone number uh clicking on the update button I'm gonna remove this breakpoint continue and you can see we're still having the same problem right still having the same problem if we click on it again you can see it is actually already updated Tom dot X right and we have the phone number but going back it's not showing so what is actually happening what is actually happening you may be thinking oh maybe the unappearing is not being called when we go back let's set a breakpoint and see uh what's actually happening there so I'm appearing I'm going to set a breakpoint here right so let's click on this Tom Hanks go to Tom Hanks and then come back whether we click on cancel or update it's going to navigate back you can see that is actually being called right it's being called and if we look at the contacts I think that's number three right you can see that it's actually have the correct data with the phone number but the problem is with this line so it's it looks like this line is not working and then that's that's true it's not actually not working so let's go do the uh diagram let's draw something so that hopefully I can make you understand what is actually happening so for example we have a page here so this is a page and then this page actually displays some data right so let's make it um vertical so it looks like a cell phone right and then we have some data that is loaded in the in the memory so I'm using a circle to represent that a data is loaded in the memory right but remember that we have a a view a view in here in this case we have a list View and when the list view is populated with the data the list view stores a copy of that data in a different format of course uh in in the memory we have another copy of that data which is in the in the contact Repository these two copies are not the same copy so in dynamoi if you don't notify the list view or any of you there's a change in the data the data in the list View or any other views will not actually update right you have to actually tell it to notify the view that there is a change in the data and then the view will do the update so that's more or less like a unique thing that you have to do in Dynamite if you came from a web application background you may be thinking that's pretty weird but this is this is what's happening in Maui you have to notify it and the way to notify it is to use observable data so it's like observe pattern where you have the data here and then you have the subscribers so you have subscriber one subscriber two you know you have different number of subscribers let's say we only have two and then the subscriber is actually subscribing to the observable data and when the observable data changes it's going to actually send a notification and because both subscriber one and subscriber 2 subscribe to the observable data then it actually receives that notification and then the subscriber can do whatever it wants right so in Dynamite this is already built in okay in the in the views so in our case we have the list view in here and this list view is actually uh when you bind the data to the list view the list view tries to subscribe but because you can see that we are not using observable data so this is just a list list of contacts right it's a regular list so that's why it's not actually working because a regular list cannot send notification to the.net Molly views right in this case is list view so how do we solve this problem let's go back to our code and then in here let's remove the breakpoint instead of just call the repository get contacts we can use observable collection right so a new observable collection you're gonna do control dot to import namespace it's from system.collections.optic model so when we do that and we can provide the type of the element and then in here we can call the repository to provide the data and of course here this is going to be a observable so we can use VAR and now let's rebuild the application and redeploy to our emulator our application is running let's click on one of the contact and let's make the same change I'm going to add actually I'm going to add a dash here and then whatever the phone number is doesn't matter we're going to work on the validation later so clicking on update go back over here you can see that Tom Dash Hanks gmail.com is being displayed so that solves our problem right because we are using observable collection so when the observable collection changes it actually notify the list view so the list view then is able to update itself with the new data otherwise just keep the data in the memory without updating which actually saves the resources right so that's what I want to cover in this video and I'll see you in the next one in the previous videos we have added these fuse in the added connect page in this video we are going to work on validations right for example the name should be required email address should be a valid email address to do that we are going to go to the solution and then we click on manage new get package let's search community toolkit and when we do that we can see we have this community toolkit dot Maui and let's just select our project and click on install and I accept so the toolkit is installed as a nuget package right but then here it's reminding us that we need to add this line to our Maui program.cs so let's go over here and then let's add this line here and then this actually resolved the problem we have this using Community toolkit dot Mali this is automatically added for us so we just added this line which is indicated in the redmi file so we initialized our toolkit in there right so this is for initializing the toolkit let's close the Remy file coming back to the added conic page so how do we use the toolkit in the toolkit they're different of course they're different things the ones that we are interested in are the validation behaviors so for example the name should be a required field right meaning that it cannot be empty so for that we can come over here under the entry like within the entry we can say entry dot behaviors right so this is this is part of the community toolkit that we just installed and then we can then use toolkit this namespace does not exist right so we can create that namespace here just like we created this extension name space so we need to do a XM XML namespace colon toolkit you don't have the color toolkit you can call it whatever you want but here we need to refer to the toolkit right the Maui took it that we just added and then here we can use toolkit colon and you can see there's different behaviors right there's even the animation Behavior you can use for animation but today we're going to cover some of the validation behaviors like first of all four required field we can use the text Behavior which is at the bottom right text Behavior and then you can close it don't have to close it this like this we can close it just like this there are several properties in here to make this text validation Behavior work like a required field validation Behavior we can just set the minimum lens to be one right so at least there has to be one character right another important property here is the flex so this configures the behavior of the text validation so do we validate on attaching do we validate on focusing of the entry field or do we validate on value change I would suggest to validate on a combination of both attaching right so you can do a comma and then validate on value change so this guarantees that in any scenario it's going to work for example let's say this is a add contact page so when you come to the ad connect page all of the views are empty so you're looking at the name field and if you don't even touch it if you only specify the validate on value change flag here then when you click on the add button or submit button it's not even going to trigger the validation because you didn't even change anything you didn't even touch the field so the field is not dirty it's not going to actually trigger the validation at all that's why we also need the validate on attaching that means that when the validation behavior is is attached to the entry field it does the validation already right which it will see that the field is empty and then it will know that it's invalid so we need a combination of this right and then in order to reference the validation field we need to give it a name so we can call it name validator another important property I want to mention but I'm not going to use today is the regular expression pattern property right so you can use this to limit the format of the text in the entry field so let's delete this okay so we're saying that name is a required field right so so then how do we spit out the error message so for that we can go to the code behind let's go to the code behind and just before everything in the update clicked event handler we can then say if if name validator is valid there is it is valid or is not valid so if it's not valid then we're gonna just return right but before we return we can split up the error message by saying display alert and then the title is error the message is name is required right and then you say okay so this will help us to validate the name so let's give it a try okay the application is running and let's go to one of the contact and of course you know we only apply the validator on the name field and there is a value in here so it definitely is valid so let's actually give it a try click on update nothing's happening it's valid so let's go back and then let's try to delete this field delete the name fill and click on the update now the area is showing it's complaining that name is required so now let's go back and let's put some name over here let's just say whatever name and then click on the update button again now it's updated we can see the updated name over here and then let's go back and fix the name okay that's a simple validation so let's add another one which is for email validation so let's go to email so when we look at the email address of course we may think we need multiple validation behaviors because the email address may be required right for a contact application maybe email address is not actually required but for demonstration purpose I want to make it a little bit complex than the name right let's say that email address is required and of course email address format has to be correct email address format right so for that we actually have a thing in the toolkit that is called multi-validation Behavior so let's use that right because that one um within the multi-validation behavior you can combine different validation behaviors so in here again we're going to say entry dot behaviors right and then within that we're gonna have toolkit and then we're gonna have a multi-validation behavior okay and of course we are going to give it a name we need to reference that I'm going to call it email validator and the flags will be the same so let's copy these two and then within the multi-validation behavior we can have multiple validation behaviors so the first one would be the text validation so let's copy the previous tax validation Behavior over here and then let's remove the name because we don't need a name for this right so this validation Behavior provides us the required field validation secondly we will need the email validation behavior and our same Flags inside multi-validation Behavior there's a way to provide error messages so to do that we're going to say toolkit dot multi-validation Behavior dot error message right and then here uh in the text validation Behavior we can just say email is required right and then let's copy this over to the email Edition and the message would be different email format is invalid and now we're ready to go back to our code behind to trigger the validation for the multi-validation behavior and for that we are just going to use the same way I'm going to say email validator if it's invalid then of course going to return first and then before that we are going to Loop through the error messages off the Modi validation Behavior so for each error in email validator Dot errors you see it's a list of objects but it's actually a list of string so for that we can just display the alert and we can just play multiple alert or you can bind them together in a string builder for example and just display everything in one display alert in one alert but to simplify this I'm just going to show all of them one by one so error and then we can say to string so this is the message and then the cancel button is okay all right so let's give it a try okay let's go to one of them so of course I have a valid email address already so let's test this let's delete the field and then click on the update button this is the email format is invalid and then also says email is required right so it spit out all of the error messages that we are expecting so let's say I'm going to put a invalid email address a b c so click on the update now I see email format is invalid click on OK you can see that the required field validation is not triggered anymore so I can just provide a email address click on update button going back you can see that my email address is changed validation behavior is not triggered so everything works correctly so this is what I want to show in this video I'll see you in the next one so we have created the added connect page we have done the view validations so there's a lot of work if we are going to create a add contact page the two pages look very very similar right the functionalities are different one of um add a page is to update contact the add page is to add a new contact so because of the similarities we need to think about create a reusable control so that we can share that control between these two pages so today in this video we are going to work on creating a reusable control okay let's go to the Views folder and let's right click and create a new folder and let's call it controls and to create a reusable control we are going to create a new item and we're going to search content view okay and then we're going to select the demo version and we can call it just contact control right within the contact control we can see there are some placeholders and this is content view this is not content page anymore so what we can do is that we can go to edit contact page and then we can basically select everything and cut it over okay let's cut it over to the content control here right replace this vertical layout and you can see that we only have one problem which is this toolkit namespace problem so for that we can just fix that very easily and call it toolkit just like before referring to this toolkit now you can see that we don't have any problems in here now let's look at this contact control what do we have here we have these fields the name email red phone and address and these fuse needs to be shared out right currently it's within the entry email and entry name all of these entry views okay so we will need to share that out through a property so let's create the first property which is going to be the name and we're just going to call it name right because this is a Content control name reverse name of the contact of course here we cannot use a regular empty Getters and Setters so for getter we will just return the entry name dot text right and as you guessed the setter will just set the entry name dot text equals to the value right now I'll do that the the rest and then I'll come back okay so I've created all of them I have email address and phone number for sharing properties values uh we're good now we go back to the front end we can see we have taken care of these properties what about the buttons down below right we have update button we have a cancel button I think we should change the name from update to save right and then here it's called save just so that it can be reused in both ad and edit page and here we are going to create a new event handler and for this one as well create a new event handler going back to the code behind and we have these two event handler here we don't need to take care of the routing right the navigation but we do need to validate okay so let's go back to the edit contact page and let's think about how we can implement the validation here you can just cut this code and go back to the connect control and then we can do our validation inside here but the problem is that display alert is not available display alert is only available in in the page right it's basically a Content page so let's actually actually let's go back to our uh add a contact page if I do a control Z to undo the change and then if I right click if I actually hover my mouse over it you can see it's the display alert is from page right and our content page is a page but the content view is not a page so display alert is not available here but that's fine that's fine we are going to delete it or both of them but here we will need to spit out the error so how do we speed up error we need to create a event uh it's like a delegate in C sharp so here we can create an event uh it's going to be an event handler and then the the parameter is going to be a string which will be the error message itself and then the event itself is going to be called on error okay so we can then scroll down to the bottom and then here if we encounter a problem right then we will need to speed up that error message we're going to say on error right and we need to use a question mark so basically if the event handler is registered right from outside then we're going to invoke the event otherwise we don't right that's the purpose of this question mark here I'm going to type Dot and then invoke right and then who is the sender so we can just pass the center from the event The Click event and then what is the error message so that would be the same error message that we had before I wish I didn't delete them and just comment them out so that I don't have to type this but its name is required right and then I'm going to copy this and put it over here uh the only difference here is that the error message is different so it's going to be error.2 string and that's it right that's it but how does the parent control knows that the save button is actually clicked on for that we actually need to create another event and type is event handler this time we can just use event arguments and this is on Save right and since we are here we're going to also um react to the cancel button click right so then here when everything is validated then we can tell our parent page whichever page that uses this control that the user clicked on the save button it's actually validated already right so whenever this event on Save is triggered is revoked we have already validated right so here we can just invoke and then we use the sender and also the event argument from the clicked event okay and then of course on cancel uh we can just say on cancel and then we invoke that event with the sender and the event argument that's basically it that's our reusable contact control so now now let's try to use it go back to the added contact page and then let's see how we can use the reusable control first of all to use this new control we need to provide the namespace because if we just type the control name right contact control it's not defined here so let's go to here and then we're gonna say controls again whatever name you choose I'm choosing controls and then it's under controls so we can find it right here then we can say controls providing the namespace well it's already showing up right all of them already showing up there's only one uh and then we can give it a name and we can call it contact control and then we're going to register a unsafe event handler here and we're going to create a new one actually um we're not going to create a new one we're going to create we're going to reuse one because there's already one so it's this update right and then here on cancel again we're going to reuse this one but on error we don't have it we can create a new event handler right and that's it you can see it is very very simple on the front end go back to the back end uh it's even simpler because we are reusing these event handlers this unsafe we don't use it anymore we don't use it we can delete it uh the only thing that needs to be changed is here we don't have the the entry views anymore so the what we can do is we can say contact control contract I use the wrong names it should be contact instead of contract right contact control so go back here and we need to fix this as well contact control on error okay so here we're going to say contact control dot name right and then this is going to be contact control dot address and contact control dot email last but not least contact control.phone number okay and then here the validations don't need to be happening here anymore because this event handler will only be invoked or triggered when validation has finished right has passed what we do need to change is these assignments so I can just delete all of them and then I'm going to copy from here and paste it over here okay and then just fix the problems okay so now on error what do we need to do when we encounter an error this is a string which contains the error message so of course we just use the display alert from the page class and then title is going to be error as Euro message is just the message and then cancel is ok button so that's it that's how we use our reusable contact control let's let's give it a test okay you can see the applications running let's click on any one of them and now we see the add a contact page no difference let's try to see whether we can update I put a dot there but let me actually delete the add sign just try to trigger the validation problem right so email format is invalid so that's validation is going on properly let's also try to delete the whole thing and then click on save this time it tells us not only the format is invalid but also it's required so let's put back the email address so John dot doe gmail.com and then click on the save button now I have John Doe gmail.com going back phone number is whatever right address is one let's say Toronto Street click on save button and everything is basically still working right but this time we're using our reusable contact control in the next video we're gonna use the control the contact control in the add contact page and we're going to work on adding contact I'll see you in the next one in this video we're going to work on the add contact page but first of all going to the add contact page is triggered from the contacts page right so this is the contacts page I'm looking at right now and it has a list View and a list view is just a single view so we really need to have a list view in a layout so we have talked about the stack layout before today instead of using stack layout I would like to use the grid so that we can learn more things so a grade is basically like a table it has columns and rows right so if I put a grate here so if I don't specify columns or rows then you can basically just put a list view here right one view is going to still work you're not actually using a grade as a grade right to use it properly we need to Define like how many columns and how many rows and how big each column or rows are right for that we need two properties one is called row definition so you can see role definitions and for this particular page we are going to have the list view in the first row and then a button which is the add button in the second row so we have two rows so here we basically in the row definition we just specify the height like x y z so in this case we have uh three rows and the first Row's height is X the second Row's height is y and of course the last Row's height is z but what about you don't want to actually specify a specific number you just want to say the last row is for example 50 and then the first row takes the rest of the space then you can just say start right star means it takes as much as it can and then we can specify the column definition how many columns do I do we have and how big is each column right so it's the same format x y z each one of them has to be a number you can see that is complaining you cannot use x by Z because it doesn't really know how big what H1 column is so in this case we actually only have one column right and then in the list viewer in in The Insider grade we need to specify which row and column each view is within so the list view is in row number one and column number one so we can just say Great Dot row number one this is the index starting from zero so basically when we refer to the first row we're going to say zero right and then and then of course the column is also zero now when it comes to the second one which is going to be a button and we'll give it a name first this is going to be a add button and the text is add contact for example and we are going to add a collect event handler since we're here already okay but this button needs to be in the second row and First Column so we're going to say grade dot row second second row is number one and grade dot column and it's going to be zero the first call all right let's run the application and see whether we have a correct page we can't see anything in the application but I noticed that I made a mistake here it's not this is not number of columns this is how big the column is because we only have one so we can use star because this column should expand to as much as it should right so now we can see all of the data in the back end let's go to the view code we have this at event handler here we want to navigate to our ad contact page okay so let's continue working on coding the added the add contact page so let's go to add contact page there's basically this welcome page right so there's basically nothing in it it does have a a cancel button so we don't need any of this because the contact control already has a cancel button and it has everything else that we need so basically we can go to the added contact page and we can just copy this and go back to add contact page and then we just replace this replace everything of course the namespace also needs to be added so we can go to the top and then we can specify the controls come from the controls which is right here and now the problem is fixed so um on Save needs to be recreated the event handler new Handler on cancel new Handler and on error also needs to be create a new event handler that's it at the front end very simple as the beauty of creating a reusable control we don't do a lot of work because all of the work already been done right going back to the back end save so what should we do on unsafe we need to call the repository to add the new contact but do we already have a add method here we don't so first of all we need to create a add contact method okay so here we create a static method and then we're gonna it's gonna be void and I'm gonna call it add contact and of course uh the parameter is a contact and then we are going to first of all we need to get a maximum ID right remember this is a memory so in memory data store so we need to manually get the the ID so we need to get the contact ID the maximum contact ID right and then we can say contact dot contact ID so we assign the ID to it so it's maximum ID plus one right and after that we can just add this contact into the contacts list okay so that's it that's our method very simple method without much validation you know if we add a duplicate contact we can always try to delete it which we're going to work on later so coming back to the add contact page inside save event handler we can use the contact Repository and then we can call the add contact of course here we need to create a new contact okay just like this and then we can specify the name equals to contact control dot name right remember that we exposed we expose all of the property out and then Visual Studio is suggesting email equals to email I hope it actually suggests the next one but it doesn't it doesn't always help but it's already helping a little bit then we just specify address is address and phone is phone and then we close with a semicolon so that's our ad contact remember here when it comes to this method everything's already validated right it's a valid contact and then if there is an error then this on error event handler will be triggered and the only thing we need to do here is just to display the error message right so we can say this play alert and the title is error message is from the event argument and the cancel button is okay so this e is the error message that comes from the parameter here which is the event argument of that event handler and then of course the shell um the on cancel event handler just basically you know go back you can just uh shell.current Dot go to async and where are we going we are going back to the contact page we can use dot dot but if not then we can use um specify the root right and then we can say name of I think we already have a yeah we already have a console so in here we created a new event handler that's fine we can just copy this over okay so when we go to the root we always try to specify slash slash or if we don't then we can use dot dot to navigate back to the to the previous page right to the parent page so I think that's everything let's give it a try I know there's a problem here that after this add contact we need to navigate back to the contacts page so I just duplicated this line here okay now let's give it a try okay so we have this list of contacts and then we can click on any of them going to the added contact page still working now let's test the add contact page so I think we're having some problems here with the layout okay so let's try to fix the layout problem first because the hot reload actually works for the front end so we don't have to stop so we can fix that very quickly go to the contacts page here uh I think we need to add some paddings for the great because you can see the button is not positioned properly so let's add some some padding so let's add maybe five let's see how it looks like now now looks much better you can see that everything is positioned correctly so clicking on on the add contact button this should take us to the ad contact page now you can see we have all of this clicking on the save button this should trigger the validations and we should be able to see all of the validation errors so name is required right so then I'm going to add I don't know this person's name is Monday Smith and then clicking on the save button again to trigger the email validation email is required and format has to be correct so let's call it just submiss gmail.com in the spirit of testing and providing a wrong format so then it's actually validating it um and then phone number is optional address is optional so I'm just going to provide something clicking on the save button going back we can see Monday Smith okay so it's working beautifully so again let's take a look what we have done go to the add contact page you can see that we basically did almost nothing right just reusing the functionality that we already created so this is the beauty of using a reusable control okay so that's everything I want to cover in this video I'll see you in the next one foreign text application the next step is to be able to delete a contact within a contact list right so let's go to the contacts page and we can see that we have this list View and then within the list view we have this item template which is basically a text so we can kind of add a button there by using view cell instead of text cell because within the view cell you can place a whatever view you want even a stack layout right we can use a horizontal stack layer and put a button there but list view has a context action and within context actions you can put one or more menu items so instead of using buttons I think we should learn about using context actions so let's do that first of all so we have this text cell right so within this element let's actually format it a little bit better scroll up a little and then minimize solution Explorer so here within the text so we can say text cell Dot dot context actions right and then within this context action then we can add menu items and for example we can have a delete which is exactly the functionality we want right we can have multiple ones let's say text maybe let's say instead of using tap uh to edit or view the contact item we can have the edit button right here for example well I'm just showing there's possibility of having multiple menu items and then if we run our application let's see how it looks like like how the context manual looks like okay you can see our application is running if we want to trigger the context menu what we need to do is long press long price and you can see the context menu is showing up on the top on different devices it may look different um Windows the context menu is actually showing right here just like a regular Windows application right um Android is showing on the top for other application contents application we are going to delete this added we're only going to have this uh Delete right here and you can see immediately the added contacts menu is gone and delete is here so when I click on it nothing is happening that's because nothing is implemented for delete before I go ahead and Implement delete functionality there's one more thing I want to point out which is for the menu items there is a property here and it says is destructive so if we set this to True uh you analysis actually see on Android nothing is special so delete is delete but um other devices like iOS I believe uh thus delete many item will be displayed in red right because this is destructive here nothing is happening in Android okay to react to this delete event what we can do is we can add a event handler to The Click event right so clicked event and then we can just say new event handler okay all right so then at the back end you can see a new event is added but how do we know which which contact triggered the context menu so we will need to use a data binding as we mentioned before the data binding in list view is by binding context so for each item see here is item template so for each item The Binding context is the contact itself so go back to the backend let's review that we have a list of contact here right it's observation list but it's still a list right so we have a list of contact and each item within that list is a contact object right so here The Binding context for this for the entire item template is the contact object itself so therefore what we can do here is to say command parameter commit sorry not command but command parameter and then we are going to use binding again but this time we're going to use a little bit differently we're going to say dot what does that mean the start refers to the object that is bound to this current item right so instead of going like drilling down into which property we're binding to we're actually just binding to the entire object which is the contact object right and after that we can go to our backend go to our backend and go here now we can retrieve the contact object directly from here by saying VAR menu item right and sender so who sent it it's a menu item right we because we clicked on the menu item menu item is the sender and then we can cast a menu item dot command parameter to contact object all right so now we have a connect object and then we are going to run the delete functionality so but we don't have a delete functionality yet so let's go to our models and contact repository and then let's add our delete functionality in here okay so it's going to be pretty simple uh we are going to say delete contact and then here instead of passing the entire iconic object we don't actually need it we can just pass the contact ID of course in the data binding we don't have to use binding dot we can just say binding contact ID right but I want to show you there's actually this way of binding the current object right so here we're trying to get the the contact by ID and to do that we can just use Lambda expression just like before we can say contact ID equals contact ID and if the contact is not now then we are going to actually remove this okay we're going to remove this contact object okay so that's uh the functionality in here so we did that and then let's go back to our code behind and let's look at this menu item click so we have this contact now we can use our contact repository and then we can call the delete contact method that we just added and no one can say contact.contact ID and that's good enough right that's good enough but if we run it guess what's going to happen contact will be deleted from the connect list however you won't see a change in the list View why is that because um because we didn't actually refresh the list view remember the contact list in memory and the contact list in the list view are two different things and we have to notify the list view that we have a change that's why we need to do something like uh let's go up here in the unappearing uh we have this uh these two lines of code here right which will kind of force a refreshing so we will need to extract this out to in a different method in the private helper method and we're going to call it load contacts okay so here we're just uh going to paste these two lines in here and then go up go up over here uh we're gonna call the contacts a load contacts and of course inside the delete functionality here we're going to also call the load context here I don't like calling it menu item clicked right because it's not actually clear what is actually happening let's actually call it uh Delete delete clicked okay so let's go back and then here let's change that to delete clicked maybe we can just delete the whole thing and then here we can select or delete clicked uh I don't know why it's complaining uh it's saying that delete click that's not found that's pretty weird so we have this delete clicked right here I think it's just um oh because we are still running the application okay so let's stop it and then that should resolve the problem okay so let's uh we completed our recording for delete contact let's run the application again to see whether it works all right so let's try to delete let's say the first one so long click and then click on delete and then you can see that it's gone right so delete that's what I want to cover in this video in this video we're going to work on search context functionality because we already implemented a view contact add contact delete contacts and update contact so now we just need the final functionality which is to search contacts because we may have lots of contacts and it would be nice to be able to search and find the contacts that we're looking for right so for that let's go into the contacts page right so contacts page right now you can see that we have a grade and then inside the grid we have a list View and a button right so a search bar should be put on the top right so we can have a search bar here and in dynamoe there is actually a search bar already you can actually you can already see it right here right so in order to display the search bar we have to change our grade so that instead of having two rows now we need three rows so we can put like 50. right so the first row is for the search bar which the height of that is about 50. and then the second one is going to be as big as it can get to and then the last one is where the add contact button is located so that one also has 50. right so we can do that and then we need to change um actually let's copy these two properties here or attributes and then put it inside here on the search bar that would be good and then we need to change the row for the list View and as well as the row for the button which is number two okay now we should be able to display the search bar and we need to let the user know that this is actually a search bar for that the placeholder attribute is is the best attribute to use and we can say something like search contact right so the user know that this bar is for searching contacts and in order to react to the search there are a couple of events we can take advantage of one of them is text changed right so this event so let's let's actually have this one as well as uh there is a search button pressed so there are two events that it's uh that can be used right I would prefer to use the text changed because the text change the event is triggered whenever you actually type anything right so this is different from a for example a web application where you try to trigger a text change so the text is only changed when the cursor leaves the the input box right here while you're typing the event is actually triggered uh whereas the search button pressed usually it's going to show for example magnify glass in the search bar and then when you press on that or tap on that magnify glass then this event is triggered so I don't like it because it's not very intuitive so let's actually uh delete this one okay and then let's go back to the front end and also delete this one but if that's your requirement that you have to press on the the magnify glass then yeah you can feel free to use that but for us we're going to use the text changed event and then uh in that exchange event so let's go back to the code behind we will have to use the context repository right this is temporary repository we're using to load in memory data right so we can use contact repository but we don't actually have a search functionality yet right we don't have that yet but we don't have it but we can code it here so uh what needs to be inside the search contact functionality actually let's call it call it search contact so this has to be uh whatever that is this the user typed in the search bar for for that we can get it from the sender because the sender is actually the search bar so we can say search bar sender so this is casting this the sender to the search bar and then the text is what the user entered so this is good enough and this should return us the the list of contacts right so we will have the contacts here and then look at the load contacts right so we have this contacts here but then this context is different so we will need to use the observable collection and then we can wrap around like this so then this context is a observable contact right and then you can just copy this line and put it over here and that's it that's uh that's it and the rest of the work is just implement the search context uh method or actually a function okay so let's copy the search contacts and go to the contact repository go down to the bottom and then we're going to create another public static uh public static function which is going to return a list of contacts and that would be similar to this one right so it's going to be list of contact and then here we're going to call it search contacts and this is basically filter text you call it whatever and then here inside the contacts we can just basically say where X name start with filter text and then we can say string comparison we already know you can lowercase okay so we want to ignore case I wanted to we we want it to be case insensitive right and this is going to return as a ineurable and we can cast it into a list like that so we can do two lists contacts so here we're only looking at the name but we actually should enable the user to search by anything right the name phone number address or email address so we uh we actually need to Let's actually copy and paste this slide and then we can test the other three Fields here so what we need to say here is that if the contacts sorry not contact but contact if it's not now and also if contacts dot count is uh actually it if it's null or contacts.com last or equal to zero that means we didn't find anything so in in this case we'll have to find we'll have to look for the filter tax in some other fields right so let's say the second one we're looking at is email right and if otherwise if we did find something from the first query then we just return right and we are going to do the same thing over and over again for another two times right so here we are going to say this is uh a phone number maybe and last but not least we're looking at address so we can see that if we ever run to this line then the the result is not returned so therefore we will have to at the end return the contacts just like this and this contacts at the end can be a empty list another thing we need to pay attention to is that one of these ones can be null right name email phone number or addresses can be known so in order to solve that problem we actually have to add some condition over here otherwise it's going to throw like object reference like null reference problem we can use a condition over here say is now or empty or y space okay so the X um name here has to be not empty and it has to start with the filter tax okay and then we're going to apply the same condition to the other ones I'm going to put over here of course this has to be changed to email and this is phone number and this one is address okay so the condition is it's not now or empty and it starts with the contacts the filter text then that satisfastic criteria and we'll get our contact back the correct context back uh here where we have our search tax change the search bar text changed um and you can see that the problem is gone and we should be able to just use this so let's run our application and see whether it works or not foreign okay so now we can see our search contacts bar is right here so let's type in the first character J actually let's put a breakpoint over here and just make make sure that the event is actually triggered while we're typing right so I'm gonna use the uh the soft keyboard like the virtual one so I'm putting J here and you can see this is immediately trigger right it doesn't actually need the cursor to to to actually leave but you may think that I press here so the cursor actually left well it's actually not the case so so actually let's uh continue so I'm going to press on F5 so let's continue right uh let's actually delete this right basically clear the the box and you can see it's also triggered right away okay and then now it's cleared so instead of using the soft keyboard I'm just going to type the letter J right inside like with my keyboard so I tap J and now you can see that the breakpoint triggered that's just proves that the tax change event is not triggered when the customer leaves the search bar right so I'm I press on F5 so continue right so I type in j a now I can see Jane though so the search actually works right and then I can type in Jane tab on Jane though and go to see the details of Jane Doe right go cancel button takes us back to here unfortunately uh the search bar didn't actually clear and everything is um is still showing right so for that purpose what we can do is that only appearing here we can do some house cleaning here we can say that search bar actually we didn't give it a name yet did we go back to contact so let's stop this and go back to contacts we didn't give it a name yet so we can say name he codes just just call it search bar okay so here we can say search bar dot text equals string dot empty okay so with this change let's give it a test again all right so now let's go to I should go to myself Frank and then click on my contact and click on cancel button now you can see that the search bar is cleared okay so that's the functionality I want to cover today I'll see you in the next one foreign
Info
Channel: freeCodeCamp.org
Views: 122,844
Rating: undefined out of 5
Keywords:
Id: n3tA3Ku65_8
Channel Id: undefined
Length: 194min 15sec (11655 seconds)
Published: Thu May 04 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.