Accidentally Building the Greatest .NET MAUI Meta-Framework

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right Maui demo I'm building a counter so let's create a counter component we'll add a new item we'll create a Content View and we'll call this counter and o wait a second this is not what I wanted to do this is not zaml this is C so I guess I have to build my UI with C now instead of zaml that's all right let's do it you know what zaml is kind of quirky anyways let's try building our UI in C all right so we're building a counter so we're going to have this label be our count so we'll start at zero and then we also want to increment this count so we're going to have a button with some text for increment this actually isn't too bad to write it kind of fits the declarative style of Zam because I feel like the way we've typed this out kind of represents the UI that we're going to see so let's use this counter so it's a Content view just like the zaml version would be so on our page we're just going to import that component and render it and boom there we go we got we got our UI we got our count and our increment button all right our UI is kind of ugly so let's clean it up let's Center everything so horizontal Center and also vertical Center let's make our counter text bigger so 48 pixels let's make sure this text is centered so it's not floating all the way to the right as we saw let's put some top margin on our button so we have to initialize a new thickness instead of being able to use that zaml syntax and we're going to do 20 to the top sounds good and let's also make this font bold as well there we go looks better so now if we want to continue following mvvm principles we'd want to set a binding on this counter text so instead of displaying zero we would bind to some sort of property that contains the count so let's see this text is a string which means we can't set some sort of binding on here because again it has to be a string it can't be like a binding object and looking through these properties properties I don't see anything that allows us to easily set a property when we initialize it in this way so we could call a method called let's see there's like set binding which is what we would want to use to set a binding on the text but as we can see this returns a void which means if we want to call this we'd have to move our label up here as like a variable that we could call methods on and then pass that label variable down here so I actually don't really want to do that because then we would be taking our label outside the flow of our UI and then we wouldn't have this declarative syntax where we can look at this code and kind of get a understanding of the structure of our UI just by looking at these flow of elements here so if we moved this to a variable we wouldn't get that benefit anymore so that means we really can't set a binding here so we're going to have to kind of ditch mvvm principles honestly so this is kind of a disadvantage of doing a c UI rather than a ZL one but let's keep going let's see if we can learn something here or at least build something valuable so rather than doing a binding we're going to store our raw count value somewhere so we're going to store this in some sort of State variable so we're going to have state that contains all the relevant data for our component and I actually want to make this a record I think and we'll see why not only are records super easy to Define as we'll see here we're just going to have account and boom there we go there's our type but I think there's other benefits that we'll see down the road and then let's have a property for our state using our counter State this needs to be private since this type is basically internal to our class and now let's initialize that state with a count of zero and now instead of hard coding zero here let's take our state count and get that as a string all right not bad so far but now we need to update our UI whenever this state changes so how are we going to do that what if we just rendered the entire UI whenever our state changed maybe we could do that let's try so let's extract all of this to a method and we'll call this render okay pretty cool so now whenever our state changes we should call render again so let's do that let's update this property to be a full property which means we're going to need a backing field now so let's expand that whenever we call get we want to return our backing field but then whenever we call set we want to update the state so update that backing field to the value that we get passed in but we also want to call render again so we're just going to render the entire UI again whenever our state changes so this is kind of interesting there's probably Major Performance implications that we would need to work around in order for this to be a good pattern but hey let's keep rolling let's see how far we can take this so next up of course course is we need to add reactivity so whenever we click this button we want to update our count state so let's see we know buttons have a clicked event do they have some sort of oneclick property that we can buy into they do not so again we have the same issue we don't want to take this button outside the flow of the UI that we're trying to render but this is a little bit more challenging because we definitely need to tap into that clicked event so so what we can do instead is we can create our own button our own button type to align with this pattern that we're working with so let's add a new class down here we'll call this like the reactive button and we want to inherit from our regular button and ideally all we want is some sort of onclick property that we can set to some sort of call back so let's create this onclick property I don't know what the type's going to be let's just throw an INT for now so we'll call it on click and I really only want to set this property whenever we're using using this initializer syntax so I only want to set the anit setter here and the call back that we passed to this anit Setter I want to subscribe that to the clicked event on our button and now we need to update our tip so that means this onclick property is going to have to be an event handler so that we can subscribe to this clicked event so let's make it an event handler and boom there we go so now we can Define our own call back that we'll pass to one click we'll call let's handle increment clicked let's generate this Handler and now we just have to update our state because whenever we update this state it's going to call render again and since we want to hit this Setter we can't do something like set the state count directly because setting the count directly here or just doing a Plus+ isn't going to trigger this Setter so we need to actually set a new value on our state so we need to initialize a new counter State and take take the current state count and add one to it so that'll cause our Setter to get called and then we'll call render again and render our entire UI so not sure how I'm feeling about this but hey let's test it out all right here we go let's increment boom seems to be working we got some pretty good reactivity here so cool let's keep going let's see how conditional rendering would go because that's something that I tend to struggle with in zaml not necessarily struggle but the synex is kind of quirky so let's see it goes with this pattern so let's let's add another value to our state called Max count and we'll set this value to five so whenever we create this new state let's make sure we forward the max count as well and what we're going to do is whenever our count matches the max count we're just going to display something down here and since we're in C here which is more of a programming language than zaml is we can just conditional render with C so we want to check if our state count equals the state Max count and we can just throw in a turn area here so the value is equal we'll throw in a new label we'll have the text B you have reached the maximum count we'll throw a top margin of five and then if the count doesn't equal the max count so the last part of our turn area will just return null and render nothing so here we go let's hit our Max count there we go so conditional rendering super easy but one of the many things that's quirky with this is setting this new state so as you can see we have to forward all of the Old State whenever we want to change just one value and this is where records are super cool so records have syntax that make it super easy to clone the previous value and modify certain Fields so to do that we can take our state and use the wi keyword and then we only have to set our count to the new count value that we want so the count plus one and this with keyw what it's doing is it's cloning the old state record and then merging in the new values that we want so super powerful and this goes really well with this pattern conveniently and there we go works as expected so this is kind of cool what we built here but there are definitely some quirks with this so for one is this C syntax really that great not really we would probably need a more declarative approach maybe some sort of C templating language that we could call like c x Maybe and then obviously we're rendering the entire UI whenever our state changes so maybe we would need something that renders more efficiently some sort of virtual Dom that has like an in-memory representation of our UI which we could update as many times as we want since it's in memory and then it takes that inmemory representation of the UI and merges it efficiently into the real UI so definitely some gaps here but I like what we built we have a UI that's basically a function of our application state Prett cool but in the end maybe this is just a terrible idea and we should just stick to [Music] [Music] zaml
Info
Channel: SingletonSean
Views: 2,753
Rating: undefined out of 5
Keywords: wpf, programming, visual, studio, xaml, custom, control, generic, system, line, display, timer, template, binding, c#, how, to, series, tutorial, easy, time, maintain, package, design, code, register, static, state, default, view, style, wrap, panel, stack, first, action, void, model, user, data, error, icon, class, clean, simple, sub, file, host, deploy, domain, list, app, maui, type, api, test, functional, unit, mvvm, guard, check, return, throw, dry, patterns, interface, pattern, best, practice, pie, react, next, js, javascript, reactive, update, function, vue, vercel
Id: DpghF7b2LB0
Channel Id: undefined
Length: 10min 20sec (620 seconds)
Published: Tue Feb 13 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.