How Handlers Work In .Net Maui!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so today's video this is a bit of a follow-up to last week's video where we talked about how you can create custom reusable controls in dot-net maui well there's kind of a another level to that that you kind of need to understand if you're going to be working in dotted maui and that's an architecture they call handlers so in this video i'm going to explain to you what handlers are how you use them how you can create your own in your own custom classes and yeah all you need to know about it so let's dig in so this is the class that we worked on in the last video the circular button and i showed you how you can create your own properties you kind of inherit from an existing view and in our class we're hearing from the graphics view and then we added three properties to this view that you can then use in xaml and then we did the bindable property stuff which we talked about again in the last video and then we also had these static methods that handled when those properties were changed and you'll notice that i've commented out that from the bindable properties and the reason i did that was you kind of can take care of this in a handler so what i've done i just i removed that logic and then over here in this new handlers folder i created a circular button handler now what is a handler well essentially it's kind of a little helper class that dotnet maui uses that handles this mapper thing architecture and what a mapper is is it's essentially how specifically in dot-net maui how they're mapping a an action in the cloud in the control to the platforms so for instance a button in android is a specific library that the android you know jdk whatever uses and in ios it's obviously a different thing it's completely different code right and the way maui works and the way maui maps these centralized things that allow you to just type button in xaml it maps them to platform specific stuff through handlers and property mappers so that's all well and good we'll talk more about that in a moment but just to show you you can create your own in your own custom classes and essentially what i've done here takes the place of the property changed methods that we did in the last custom class video so just to talk through that first we have these three methods map button color map image and map is visible and they have almost the exact same logic that on button color changed on image changed and on visible changed do they have essentially the same logic the the difference is you don't get past a bindable object and an old value a new value what you actually do in the handler is at the point this is called the property is already changed inside of the class so you don't need a new value in an old value or anything like that the value is just stored in the property of the class and you get the class because the signatures of all these methods are the handler that's calling them and then the class that you're handling in our case that's our circular button so you can just access ifbut.drawable and you get the drawable instead of instead of doing the bindable object stuff so a little cleaner i think in terms of code so i'm doing here if the button drawable is a circular button trouble which you know pattern matching stuff then drawable dot button color equals button dot button color so button.color has been set already at the point this triggers and so we just use it as our drawable.button color and we invalidate the button which then redraws the drawable okay and similar thing on map image and we're also doing our fade to logic and is visible so anytime is visible changes you get a little fade animation it operates the exact same way as the code in the class did on the property change methods but now they're inside of a handler so we've got these three static methods how do we attach them to a property and the way we do that is with a property mapper let me zoom out just a little bit because this is a long long guy so in a handler every handler has a property mapper and it is of type i property mapper and then the types it takes is it's mapping the class that's handling the circular button and the class we're in the circular button handler so it's mapping a class to its handler the property mapper is called propertymapper and equals new property mappers implementation circular button circular button handler and we're also passing it something here we're passing it graphicsviewhandler.mapper and you'll notice in my custom handler i inherited the graphicsviewhandler which there is one the reason i did that is because i still want it to map all the other properties that are in a graphics view that i don't want to have to rewrite so drawable for instance is one of them i don't want to go through all the stuff to do the drawable property and all the other properties that we inherited in graphics view those were already done already let's just take in that code and in the same way for the graphics view handler we are passing in to the property mapper constructor sorry it keeps jumping around the property mapper constructor we're passing in the mapper from the graphics view handler so that it knows it needs to start at that place so all of the mapping in the graphic view handler is already in our property mapper and then in our initialization we're also adding three more to it so this is how it maps things it maps a property name so you can use the name of function circular button.buttoncolor that is the property name and it equals a static method which is the map method and so you do this for the properties you add and now you've got a property mapper that contains everything in graphics you handler plus your three you've added so you've got your graphics view handler um and also just to note you also in your constructor you want to pass your property mapper this is a static thing so when a new version of your circular button handler is created you pass the property mapper to its base function i think graphics you do the exact same thing as this and i think there's like a view handler base class that they use that eventually creates the dictionary so if you were to run this code and you looked at this property mapper in memory you would see like 40 or so different properties all mapped and that's all the properties are inside of your kind of class hierarchy that you're using for your custom control so yeah that's how you create one and you might be thinking well isn't this the exact same thing as this so what's really the point and you're right it is i'm not really using it to its full potential here i will say that there's nothing i i don't think there's much you can do in a circ in this circular button handler that you couldn't also just do in the property changed methods that we used earlier so and honestly if i were writing this not just as an example for people but just as my own code i probably wouldn't even bother with the handler but handler is a very important architecture for you to understand because it's all over the place in dot-net maui they use it for all the platform-specific stuff as mentioned so if you wanted to do platform specific stuff in your custom class you could do that in the handler and using the if deaths you know like if android do this else ios mac do this you know that kind of stuff though i will point out you can do literally the exact same thing in here so it's not that different but the cool thing about handlers i will say is that they're kind of extendable without creating new classes things like that so i will actually show you how to do that so you can extend the handlers for the base controls that are in.net maui you know button label entry we'll talk about that in just a second so you can see why handlers might be useful and also might be useful for your custom class if you were going to create a library of custom classes and for whatever reason it wasn't open source i don't know uh you could put together that library create all your custom controls sorry i keep saying classes i mean controls you put you put together a library with all your custom controls you put it out and then you can provide handlers so that people can augment the behavior in the platform specific stuff in those handlers so now that hopefully that all makes sense in terms of how you create your own and how they work because i think it's important this is important first step to understanding how they work because then once you see the code for how you change the mappings inside of the net maui handlers like for the base controls i think it'll make a lot more sense because i know the first time i saw that that's how it was explained was just here's this big long dictionary resource thing and you got to do all this stuff and how does it fire and things like that it was it was kind of confusing but after i made my own i kind of got it more it's like oh okay it's always just name of a property equals a function and that that method gets called when the property changes easy enough so oh and one last thing just to point out right here in the constructor for my circular button i also set the handler property the handler property is built in it comes from eye view handler visual element.handler which graphics view had as well so we're getting it from graphics view which is inheriting it from visual elements so just to know you do have to set the handler for your class to be an instance of your handler okay hopefully all that makes sense let's move on to how you can actually augment the mappers in.net maui so you can change any controls behavior that you want all right so now let's look at this example here this is an example of how to change the mapping of existing handlers and their mappers inside of.net maui and this actually comes straight from the microsoft docs which i'll link in the description below along with a few other resources i think will be pretty helpful for this so basically you can call this maui.handlers entry handler so what we're modifying here is the entry control so like you know text entry and there's an entry handler and you can grab its mapper and then use this method called append to mapping and there's three types there's pre-pin to mapping there's modify mapping and then there's a append to mapping so pre-pinned an apenned you can probably figure out what those do but basically pre-pen to mapping will insert your code to kind of run before all the other mappers get evaluated apen to mapping does the same but it runs at the end and then modify mapping is you can pick a specific property to change all of its code so in this case we're doing a pin to mapping we've got a key the key i don't think for append and prepend really matters that much you can call it whatever you want and it's just gonna run it no matter what obviously if you're doing modify mapping i think you would need the exact name of the mapping and then you pass it this lambda function this anonymous function and you're passing a handler view and then in here you're doing just platform specific code with these if deaths if android we do a specific thing so the special thing about handlers is that they expose this platform view property and what it does is it gives you kind of platform specific code that you can call so for instance in this case what this code wants to do is change how the entry is focused when the view comes into view in the the entry so if we're doing android what we're going to need is handler dot platform view dot set select all on focus true that's the android specific way to do this for ios and mac catalyst you have to call platformview.editingdid begin and you give it a another anonymous function and you do handler.platformview perform selector and then you do this objective c runtime class dot selector select all no i i wouldn't even pretend to know exactly what this is doing um i i don't know ios specific code very well but this is kind of out of the the docs for microsoft and yeah so like like you can see here you're calling like objective-c code or you know the dot-net wrapper for it in here and that's if you're doing ios or mac catalyst if you're compiling for those and if you're you know your build target and then if we're doing windows then it's similar we have platformview.gotfocus giving an anonymous function and doing handler.platformview.select all this is basically just a bunch of platform-specific code that you can put into the entry handler mapper and now at the end of when your entry is updated or whatever your this code will run at the end of all that because you appended to the mapping and whatever platform you're using that specific code will execute and it will do the thing you wanted it to do so hopefully this helps a little bit in terms of seeing how handlers and mappers are powerful for one they expose this platform view which is gives you a lot of code that you can mess with in terms of creating platform specific things it's actually pretty nice to use and there's you can find more information in the docs about what all platform view can do just the tons and tons of different stuff obviously it's vibrant specific i'll also say that these entry handlers and i didn't really talk about this a moment ago but most of the time you create these as a partial class and you'll do like a base handler class and then you'll do a circular button handler android.cs or ios.cs or whatever and you'll do partial classes of this as well but have the android specific code and that one the ios specific code on the other and if you look in the dot net code base you'll see this the same thing special to note that this is kind of a static change of this code and so anywhere you do this it'll just be globally true so in our case all entries that are instantiated after this point will have this code in it and i i don't know where the best place to put this is i mean if you put it in your maui program.cs it'll guaranteed run at the beginning and you'll be good to go yeah there's probably a good place you know like a standard place to put this i would probably put a bunch of them in like a method and maybe call it in here but either way so just to note that that wherever this runs it'll be globally true for all your entries as things kind of instantiate afterwards they'll all have this appended to the end of the mapping all right with that out of the way i wanted to give just a little bit better of an example in terms of a custom handler that you could write there's an example in the microsoft docs that i think does a very excellent job of why this is architecture is very important and it actually takes the example of if you're doing a video view class obviously video is something that's going to be very platform specific ios will do it differently than android will do it differently than windows and all these things will have different apis and all this stuff and so handlers are a great way to kind of tackle that problem and give you the ability to write platform-specific code and kind of package it up in a nice little package and then also give people the ability to extend it so let's just look at those docs real quick and because i just want to talk you through that example so you can kind of see where this could go because i think it's an excellent example so let's do that okay so here is the microsoft doc example that i was talking about obviously again it's linked in the description below i think this does a very very good job of talking you through basically all the stuff this video has been about and uh kind of walking you through when you would kind of have to do this with handlers so again what they're doing is they're creating a video control that's kind of um let me zoom in a bit a video control and as mentioned that would be very platform specific so they want this control to do two things play a video from a url play a resource embedded in the app and play a file on the device's video library and it kind of talks through what it looks like etc and here's kind of the architecture that they're using so this is the platform the cross platform control video and then they write handlers for android ios and then they have this maui video player class and yeah it's like the native side of things so if we scroll down here this part right here talks you through the steps that you would need to do uh and it's a lot of the things we've discussed in this video in the last so they create a class for the cross platform control that's in our case that was the circular button class and that kind of gives the public api then you create the handler class you create the property mapper that we discussed you can also do a command mapper which is a a mapper of commands to actions so we'll talk about that in a moment but that's another thing that wasn't in the custom circular button mapper and then like i discussed you can do partial classes for each platform to kind of separate the code which is a little nice that way you don't just have a thousand if defs and then you register the handler using the configure maui handler and add handler methods uh in your app's maui program class uh which we'll talk about in a second so here's the code they use so again they have the bindable properties they have the these different properties here they have autoplay etc and then here's their handler so they're using if-defs in the using statements to determine if platform view is using videodemos.platform.android.mount video player or microsoft ui xaml framework element you know that kind of stuff so they're using the if-defs in the usings to make platform view a specific thing which is kind of cool and then they create the property mapper which is it looks exactly like what we did it's your you're taking the name of a property and you're mapping it to a method so pretty straightforward it talks about what a property mapper is all this stuff and then the command mapper which is the thing i wanted to talk about so this video class has these actions these commands and there they've got a command mapper which is a of type command mapper it's not a video to video handler just like propertymapper and a second name of video.updatestatus video.playrequested pause requested and it's mapping it to a function inside of the handler as well and you would do this because obviously the code to pause in android is going to look different than the code to pause in ios because they're completely different apis it's a pretty convenient way to kind of encapsulate that code as well so scrolling down here and then they walk through this is what i was discussing you can do the partial classes so you can do videohandler.cs as a partial class and then do videohandler.android.cso.mac ioscs.window.cs to kind of separate that code out and prevent you from happening to a thousand if else if android else ios whatever okay and another thing i want to discuss was this connect handler and disconnect handler these are invoked to kind of well connect handlers so you can use this to for instance if you're using android you do base.connect handler platform view and that platform view is specific to android so you'd have to connect the handler disconnect handler that's that's how you get use the partial class and inject it in basically i i really wanted you to just be aware of that okay and yeah i think you know you can scroll through here the rest of this as well it has a lot of really good example code found it pretty helpful when i was trying to figure this stuff out and i honestly it's like a perfect use case for why you would need this stuff because again very platform specific so you can really take advantage of that platform view from the built-in handlers and yeah do all kinds of stuff it's a very long example by the way don't get sick but i'm gonna do this and show you there's a lot there so great great example if you like reading there you go you're on youtube so you might just like videos i don't know but the very least if you're just looking for information uh here's a lot of it so you can you can learn to your heart's content about videos and handlers and how they did the platform specific stuff so okay i hope that all helped i hope you kind of get what handlers are what mappers are how they connect together like i said when when i was looking for all this information i had trouble because every time i wanted to know what the heck's a handler what the heck is a mapper i mean i get the general idea of it's a dictionary and there's there's properties and stuff mapped but it was just this big long string of stuff and then there would be some platform view stuff and i'm like okay i don't know how do these work under the hood you know that kind of stuff and a lot of learning about this was digging into the dotnet maui source code because these things are all over the place and uh yeah so it's very important to understand it's very important to understand how you can change the built-in things it's kind of a nice way to make them extendable without you know having to write a new class necessarily and obviously if you're creating your own class you can create your own handlers too and map properties to actions that way map commands to actions that way and kind of keep the code clean keep it encapsulated keep your source files small you know that kind of stuff there i have some other resources that i think will help if you want to dig in further i found a few good really good blog posts the blog post i mentioned last week from pedro jesus on creating customized controls talks about handlers in there as well so you might go back to that one as well but i'm going to stick a bunch of resources in the description below to give you further reading to kind of hopefully help you you know get a little more advanced in terms of handlers but in general i think that's kind of it you know you could probably learn some more stuff from looking at the.net maui source code and see how they did certain things or you know i like to look at githubs from people who work at microsoft or work on.net maui because obviously they're going to be very up to date on how to do this stuff and they're doing some really advanced stuff oftentimes so you can always learn more about this stuff but hopefully this video helps and i will talk to you guys next time bye
Info
Channel: Programming With Chris
Views: 4,030
Rating: undefined out of 5
Keywords: .net maui, .net maui community, .net maui example, .net maui preview, .net maui tutorial, csharp, dotnet maui, dotnet maui getting started, dotnet maui tutorial, first net maui app, learn .net maui, learn dotnet maui, maui c# tutorial, maui for beginners, maui tutorial, what is .net maui, Custom Controls, Customized Controls In .Net Maui, Custom Controls In .Net Maui
Id: Dt81GTnzPxU
Channel Id: undefined
Length: 20min 48sec (1248 seconds)
Published: Tue Sep 06 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.