.NET MAUI - Building a cross-platform app from scratch in 35 minutes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone amikai here in today's video we're going to take a look at net Maui specifically what we're going to do is we're going to create this application over here completely from scratch using mvvm data binding we're going to use the.net Community toolkit we're going to create a custom converter there's going to be a lot going on and we're going to write a lot of code a lot of c-sharp code a lot of xaml code so hopefully by the end of this video you'll have a good intuition to what it's like developing in.net Maui and you'll be able to take the concepts that you learned today and apply them in something completely different okay now what we have on the screen is basically a project that's created from the template in Visual Studio the only thing I changed is in the resources I replaced the default open stands font with Roboto font that's the only difference other than that it's exactly the same now I don't want you to be intimidated by all these folders and what's going on over here because when we get to it then I think you'll understand it a bit better when we break it down chunk by chance okay so what we have currently is I click play and we're running on some Android emulator and what we have over here is basically the main page is displayed now what we have what we see here is a vertical stack layout so the items are stacked vertically then in the top we have this image right that's where it comes from and in the bottom then we have this button that simply says click me right that that's the text over here when we click it then it invokes the on counter clicked method which is implemented over here and we can see the actual implementation so when we click it then it displays the text right and every time we click it then it's invoked again and that's what we see over here okay now what we have over here is an application in which you can create breakfast so you have your rate button you click it you put the breakfast details once you complete it then you have one of these on the screen so let's go ahead and model one of these so for that let's stop application let's minimize this for now and over here let's create a new folder let's call it models and inside let's model our breakfast so let's say breakfast.cs let's make this a bit more concise let's say public record breakfast and let's model one of them so string name string description we have the start and end date time right so start daytime and end daytime we have also a list of savory items and a list of sweet items as well right the only thing we're missing is a the image right so we also have your the image great let's get rid of these redundant using statements and go ahead and create the view model so over here let's create a new folder it's called view models and inside let's create this page let's call it my breakfasts view model so my breakfasts review model and again let's make this a bit more concise changes to public class my breakfast view model and the breakfast view model is going to hold the list of breakfast that the UI is going to bind this list to this list of breakfast to present it on the screen right so a list of breakfast like so right let's just add the using statement okay now what we want to have over here basically this thing over here is going to be some collection View and the source for these items is going to be this field but in Dot and now we every time you make a change in the view model and you want it to be displayed in the view again this is the main view the one that we're going to manipulate so every time we want it to be reflected over there you need to notify that a change happened okay now to do this what we're going to do is we're going to use the.net Community toolkit which does a lot of the magic and the heavy lifting for us so the way this looks let's go to the nougat package manager and let's look for the community toolkit Dot mvvm this should be enough yes this one over here let's choose our project and let's click install then what we can do is we can implement the observable object and let's edit again this comes from the community toolkit and what this does is a lot of the heavy lifting for us so what we can do is simply say over here that this is an observable property and behind the scenes it'll Auto generate there's a source generator that builds the public property for us that's every time we make changes to that public property then it knows to notify that there are changes and the way this works is that if you would want to implement it yourself then you would have to implement the inordify property change and then every time that you update that property then you would have to notify basically the view that it changed but what we can do is we can simply add this and the source generator will do everything for us we're going to take a look into it a bit deeper in a few minutes the only thing we need to do for now is say partial right that's what it's complaining about because the public property is going to be in the other partial part of the class okay let's add here a Constructor so let's say my breakfast view model and here let's populate this list a breakfast with some mock data so I'd say load breakfasts and let's generate this method and for now let's simply say breakfasts equals new and over here let's put some fake data now notice that what we're updating is breakfast with a capital B now we didn't Define it it was defined by this attribute over here and if we look at the implementation then like we said this is in the other partial part of this class and we can see that the get is simply getting this thing over here but when we set it then we need to do what we talked about before call on property changing on property changed which is how the view knows that the value changed and what we care about happens over here where we actually set the backing field to the value that we defined okay every time we want our changes to notify the view then we want to update the public auto generated property okay I'm pasting in some mock information which corresponds to the UI we have over here right so vegan Sunshine vegan sunshine or I don't know the list of sweet items corresponds to this and so on this is just so the UI that we're working on will look exactly like the mock okay what we want to do is we want to put a semicolon over here and that's it for this file again let's just get rid of the redundant using statements and the next thing we want to do is we want to go to the main page and we want to Define The Binding context okay so soon we're going to look into Data binding and we're going to see what it looks like from the view point of view and what we're going to do is we're going to take many of the properties and we're going to bind them to some data that sits in the view model but for this connection to exist we need to Define in the main page what The Binding context is so in our case what we can do there are multiple ways to do this this is just one example is to say that over here The Binding context is our view model so let's say my breakfasts view model let's just include the namespace and that's it so let's run the application and we're going to see how fun it is with hot reload to Simply write what we want and see the changes reflected in real time okay so the application launched and we still have the exact same thing like before that's because we didn't change anything yet now what we want to do is we want to actually do the data binding start working on The View to make it look like the mock that we have so the first thing I want to do is basically get rid of this entire thing so let's delete it and you can see that right away it disappears that's because we have hot reload so we can see what this actually looks like okay so now after we deleted this then we can also delete this method we don't need it anymore and now let's start modeling what we have over here so basically what we have is the following this top part this is probably something that should sit over here right so let's ignore it as part of this page because this is something Global for the entire application what we have over here we can look at it as a grid that has four rows right so this is the first row this is the second row this entire thing is the third row and this part over here is the fourth row so for that let's go ahead and create a grid and let's define how each one of these rows is going to look so the way you do that is you create a row definitions property which inside will have the row definitions and here we can Define the height of each one of them okay so putting over here Auto basically means however much space the line needs it'll get so for example if this is this font size is 16 then it'll get some out of space but if it's a hundred then you'll need more space okay that's Auto and we can see that basically these two need as much space as they need same goes for the button but for our scrollable list of dinners we want to catch all the rest of the screen right so what we can do is we can create here four row definitions and for the third one let's put a star now something cool that you can do is also say over here two stars for example and then the remaining space will be divided added between these two lines in the ratio that you define okay now what we have over here so the first line is your breakfast right the next line is breakfasts you have created the third one is a scrollable list of breakfast right so scrollable list of breakfasts and the last one is the create new breakfast button right okay let's start with your breakfast so what we have over here is actually two items so let's create over here a horizontal stack layout and inside let's create our two labels where the text on the first one is your and the text on the second one is breakfast now it's pretty cool that we have hot reload we can see the changes be reflected immediately now the font size is a bit bigger if I remember correctly it's 24. let's see if that looks right yeah that's about right the font family is Roberto bold and what else do we have here maybe the padding of the entire thing is something like this yeah this seems about right and the last thing you want to do is we want to update the color right so let's define the text color to be this thing over here so let's pick this color it's the same color for both of them and let's paste it over here great that looks better what we might want to do if this color appears in any places in our application is to Define it as a static resource over here so we can go to the colors xaml and what this is is a resource dictionary and we can Define here a new resource call it let's say Uber blue and paste the color that we want over there right so let's try picking it again pasting it over here and I think I missed before so the new one seems a bit better that's a static resource and blueber blue okay so that looks right let's move on to breakfast you have created so let's say over here label the text of this thing is breakfast you have created okay now by default it goes to row 0 and column zero in the grid but we want it in row number one so let's do grid dot Row one we can say that the text color is gray let's say something like this see that looks right yeah that's about right the last thing we want to do is create the create new breakfast button before we move on to that scrollable list of dinners so let's create here a button let's say that the text is create new breakfast we want the background color to be black this thing yes we want the padding to be a bit more right let's say 16 and maybe the corner radius is a bit less round let's say two see what that looks like great and let's put on the correct column so grid dot row number three and just post it in the bottom now like we said before if we put on number two then it'll catch all the space that it can but for our case we want it to be in row number three okay now let's move on to this part over here what we want to do is that we want to bind the information that we have in the view model to this scrollable list of breakfast so what we want to do is create over here a collection View and Define what the source of the items is so what we want to do is we want to say item source and bind it to the list of breakfast okay now it would be great if I would write your breakfast and I would have autocomplete so what we want to do is we want to go up here and Excel XL admin xmlns stands for XML namespace so I simply copy this entire thing and let's give it a name let's call it view models and if we write viewmodel then for you I'm guessing it's too small to see but it's the namespace of the view models so if we click it then it fills it with the correct information and now what we can do is we can say that the data type is the my breakfast view model okay so again this thing over here is the namespace that we defined and we're saying that the hint for the data type comes from the my breakfast view model class okay so what we can do now is we can go back to here and we should have intellisense so I say breakfast and we can see that we have your intellisense for the property okay great so we binded it and we can see that it already appears so this is the information that we put in the view model I think it's simply to string on the values so let's put first in the right grid row so that's a grid.row two that takes it to the second row of the grid okay the next thing we want to do is we want to fix the spacing So currently the two items are one next to each other but we can see that over here there's a bit of spacing so to find out what the spacing is if you're working with figma then all you need to do is hold down alt and see what its distances from the different item now for you it's probably too small to see but it says 19.98 that's because I'm not a designer this was supposed to be 20. so let's add that spacing let's say collection view dot items layout and over here let's Define a linear item layout and let's say that the orientation is vertical and that the item spacing is 20. okay the next thing we want to do is Define each one of the items what its layout is so the way we can do that is we can say collection view dot item template and over here Define how each one of them is going to look but because we have data binding then we need to put this inside a data template and now we can see that for each one of these items then it has a little border so for that let's create here border and let's say that the minimum size of it is we can see that even though it's not filling all the information it still has some minimum height so around 315 so let's say here minimum height is 300 and 15. like so that looks a bit better also maybe the line isn't as thick so let's say that the stroke is I don't know it's a dark gray again see what it looks like I know that doesn't look good let's say light gray yeah that seems about right okay the next thing we want to do is Define each one of the items inside so basically what we have here are two columns right where this column is about twice the width of this column so we already know how to do that what we want to do over here is create a grid and inside here let's define our column definitions so for the First Column the width is simply star and for the second one it's two stars now let's define the image so the image sits on the First Column so let's say that the source of this image is binding to the image property in the breakfast now we don't have intellisense and that's because we haven't defined what type we're using over here in the data template so what we want to do is we want to save data type and put here the breakfast but breakfast isn't recognized and that's because we only put the namespace of the view model and not of the models so for that all we need to do is duplicate this line change these two models and over here put the correct namespace for the models and now we should have intellisense so let's try writing breakfast and it autocompletes and again it comes from the model's name space now it knows that each one of the items here is from The Breakfast type so we can even navigate to definition and it takes us to the correct property okay so we put the image let's put a closing tag so it appears in the UI great looks better we want to fix the aspect let's say aspect is aspect fill and feels about right okay for the next one what we want to do is we want to have the breakfast details right so let's make this a bit more readable let's put this on top so we can look at this as a grid where we basically have five rows one two three four five where the third row basically catches as much space as it can so we know how to do that already so let's say grid and this grid sits in the First Column right this part over here and what we have inside are five rows so I'll say row definition and let's say that the height is Auto for all of them other than the third one which is the description and it's basically as much space as it can catch okay so again just to recap we have over here a grid this grid has two columns the First Column has the image which is this and the second column over here has this grid which is these details over here okay now for the breakfast details the first thing we have is the name then we have the start and end daytime the third thing we have is the description and then we have two lists the list of savory items and the list of sweet items so for the name this is simple we already know how to do it so the text is simply binding to the name great and again we have here some padding right let's see how much it is around 16 yeah again I'm not a designer so that's how much it came out to be so let's say a padding of around 16 let's say that the font is a bit bigger say the font size is 24. the font family is robotable and yeah that's it okay for the story and time for now let's just put your placeholder okay we're going to update it soon using a converter this is if we notice the only property that's not a one-to-one mapping between the information to what's displayed on the screen so for now let's simply say I don't know this string over here let's let's copy it and paste it over here just a placeholder for now let's hit that the font is 16. it sits on the second row right so grid dot Row one the font is not robotobald okay next we have the description so over here we have a label The Binding is to the description and this sits in the third row so two and it has a bit of a padding on top right so let's say padding let's say eight to the top the text is a bit lighter let's say that the text color is again dark gray so like so okay so it's starting to look better and it's really cool to be developing something like this so fluently without reload especially when we're building it for Android but with some tweaks it'll look very similar on iOS as well okay the next thing we have are the Savory items and the sweet items so what we want to do is we have a list of strings we want to display it like so and if it is too long that we want it to be wrapped and move to the next line so for that we can use a flex layout so let's say here a flex layout where we want to Define that the item source is the Savory list right so let's put this on a little line so we have you can see what it says and let's say binding to the Savory let's make your bit more room Also let's move it to the correct row so let's say that the row is number three and for us to be able to see something let's say that align items to the start right also let's say wrap is wrap by default it's no wrap and that's why we can't see what's off the screen great now we want to Define each one of them what it looks like so again we're familiar with something similar to this so bindable layout dot item template and because we have data binding then again this sits inside a data template and what we want to Define is each one of these so let's say label and the text is binding to Simply our information which is simply dot right now we want to define the color but if you look then you can see that there's a bit of a radius and labels don't have a corner radius property so what we want to do is we want to put this entire thing inside a frame so let's say frame and let's put the label inside and now let's define this so let's say that the padding inside is less let's say six and see what it looks like yes it looks good great for the margin let's say two or one yeah it looks better for the Border let's say that it's transparent and for the background this is the reason why we did this entire thing let's say that the color is this thing let's see if I can catch it and great that looks good now what we need to do is take this entire thing paste it over here in the suite let's change the row to four let's say that the background color is this pink pinkish color and let's bind it to the Sweet items great that looks about right let's put one next to each other and see what it looks like yes so this looks pretty good right maybe the only thing that we're missing is that here there's padding and here there isn't so let's go up here and let's add here some margin let's say that the margin on the top and the bottom is eight right something like this see what it looks like maybe even more let's say 16. yes that looks better and what else yeah that looks good okay we said that we want to to pull for refresh so what we can do is we can take this entire thing minimize it and then we can let's get rid of this for now and we can put this into our thing inside a refresh View and let's move this inside fix the indentation and let's move these properties to the refresh view now great let's just fix the indentation Okay so we did this and now when we pull it down then we can see that we have the refresh now again this is for Android so this is the widget that is used but we expect the correct widget to be used depending on the platform okay but we installed it forever and that's because we need to set some other things as well so if we look at the property is refreshed and we change it to false then we can see that it disappears right and true makes it appear again so what we want to have over here is basically a binding to some is refreshing property that we're going to Define soon when when we're finished refreshing then we'll set it to false and it'll disappear and the last thing we want to do is to Define some command that when we pull it down like this then it invokes this command and we can act right so what we want to do over here is binding to some let's call it load breakfasts come on right okay now let's go ahead and Define these two things and I'm reminding you that we still have the time hard coded we want to replace this with Dynamic text okay so that's what we have left let's go ahead and implement it so back in the view model we already have our load breakfast what we can do is we can change this to public and we can put on this entire thing the relay command attribute and what this does let me stop the application because Hot Wheel doesn't work in this case what this is going to do is it's going to Auto generate the code needed to basically wire the things together so we're going to take a look at the generated code in a few minutes but for now let's simply have this let's say load breakfasts async and let's make this awesome task and just to feel like something a secret is happening let's say oh wait task dot delay and let's say for example two seconds right something like this okay the last thing we still need to do is put this entire thing inside a try finally block where in the finally what we'll do is we'll set that is refreshing to false right so that's two things that we still need to do so let's go to the top over here and let's say try and in the end let's say finally and here we'll have the is refreshing false right where we still need to Define this let's just move this entire thing inside the block and fix the indentation great and to create this property then we already know how to do that all we need to do is go over here and Define here is refreshing field and it will auto-generate the public property that will notify the view for us okay let's rerun the application hope we didn't make any mistakes and let's recap in the meantime so what we have is we have the breakfast Which models one of the items on the breakfast list then we have our view model the viewmodel simply has two properties one is the list of breakfasts that the view is using to create this scrollable list over here then we have the is refreshing property this is the property that we want to change to control whether or not the the loading widget will appear or not and what we have over here is the load broadcast async where we're simply putting static information and we're waiting two seconds to simulate as if something a synchronous is happening then in our xaml then we defined everything we have over here at the refresh view which which wraps this entire list and now if this worked so when we pull it down then it invokes the load breakfast command it waits two seconds it changes the is refreshing to false and then it disappears okay the last thing we still need to do is we need to change this start and end date time to be dynamic based on the information right so if it's today then I'll say today if it's tomorrow we'll say tomorrow but if it's a different date altogether then according to our mock then it will simply show the the day of the week and then the date right so we need to do that depending on the information so we want to use a converter for that so the first thing we want to do let's stop the application is add another nougat package so the package we want to add is the community toolkit dot Maui so simply click it and select install we can move this for now okay now that we have that let's go ahead and create our two converters so back in the solution Explorer let's create here the converters folder which inside will have two converters the first one is we want to convert the start date time to the breakfast day right today tomorrow or some date so let's call it daytime two breakfast day converter right let's say something like that okay and what we have over here is we're inheriting from the base converter and we're converting from an object to a string okay implementing the abstract class then we have the following okay so basically what we have is a converter that we can now use in our xaml code and when we pass any value then this method over here is invoked and whatever we pass in the value will be for us to manipulate and whatever we return from this method is the string that the view is actually going to get and be able to use so in our case over here this is going to be the start date time and what we're going to want to return is today tomorrow or some date so for that let's do something simple for now let's say daytime daytime equals and let's convert the value to a daytime so yes then what we want to do is we want to see how many days away it is from today all right so for that what we can do is the following we can say daytime dot date this Returns the date part of the daytime and we can do minus daytime dot today which is today and then we can say how many days do we have here in total and we can switch on this value and we can say okay if it's zero days then simply return today if it's one day then return tomorrow okay and for the last one then what we want is this format where we basically have the day of the week and then a comma and then the day in the month and then the dot and then the month right not the best decision but again I'm not a designer so let's say we have something like this here we have a comma then a space then a DOT and what we have is the daytime dot Dev week right then over here we have the daytime dot day in month and the last one is the month okay and that's it okay so this converter that we now defined gives us only this section right up until this comma but we still have this part where basically we have the time part of the starting time and the time part of the end date time with a dash between them so to do that let's go to our converters folder and let's create here a new converter let's call it daytime to let's say I don't know time converter right something like this then what we want is going to be similar so again we need to inherit from the base converter this receives an object and returns a string let's implement it so what we can do is we can say that the daytime daytime again let's cast the value to a daytime and then we can say return and then we can say time only from daytime pass it duh date time and take only the short time string which will give us what we want and that should be it okay so we have our two converters defined right over here what we want to do now is add them to the static resource dictionary and then invoke them on the correct parameters in the view and manipulate the UI to look like in our mock so the first thing we want to do is go to the Styles and Define it over here in the resource dictionary so let's add the namespace of the converters we already know the drill let's give it the name converters and over here let's say converters and let's add our entry so we have converters and the name of our converter and let's give it a name let's say this thing then let's do the same thing for the second converter and let's give it also the same name now there's one more thing that we want to do because we're using the.net Maui Community toolkit we want to go to the Maui program and if you worked with asp.net then this looks familiar if not then don't worry all you need to do is add over here the use Maui Community toolkit and that's it now what we can do back in our main page xaml let's click play and use hot reload to manipulate the view to look like in the UI okay so I opened our Mac UI over here on the right this over here is what we care about and this is our actual application with the hard-coded property at the moment let's go ahead and use our converters so this entire thing is like a horizontal stack layout right but because if it's too long we wanted to wrap let's use a flex layout like we already familiar are with let's say that rep is rep this also sits on row number one and again let's say here are line items to the start okay now inside here what we want to do is we want to have a few labels the first label is going to be this section over here or until here depending on the value so the text is binding to the start date time and we want to use your converter so the converter we want to use is a static resource and it's this one that we defined over here like simply copy this value and paste it over here and let's put a closing bracket so we can see something and we can see already that it is dynamically populated with the right value using our converter maybe this is a bit small let me try to make this a bit bigger okay the next thing we want to do is we want to put a comma so we can simply say label and the text is a comma great then we want to use the second converter that we created twice one time for the start date time and one time for the end date time so let's simply copy this entire thing and instead of this converter let's use our second converter so I pasted the value of the second converter we see we're missing here a space and the next thing we want is to put a dash maybe a space between them and then use the converter again this time on the end date time okay and great that's it it looks good in my opinion very similar to the mock that we wanted to have the only thing we didn't do is update this part to be like in our mock but that's something that I'm leaving for you as homework so that's it for this video I really hope you enjoyed it and you learned some new tricks and you got a feeling of what it's like to develop in Maui if you like this video make sure to smash that like button and I'll see you in the next one
Info
Channel: Amichai Mantinband
Views: 36,912
Rating: undefined out of 5
Keywords:
Id: wMn1tuMfZ-0
Channel Id: undefined
Length: 37min 48sec (2268 seconds)
Published: Sun Sep 25 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.