Creating Reusable Controls - WPF TUTORIALS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
duplicating xaml will make your application harder to maintain so in this video i want to go over how to create reusable user controls to prevent and remove any duplication of xaml and this is a pretty straightforward wpf concept but it's often overlooked even though the benefits of creating reusable user controls is just through the roof and we're going to see that in this demo so for this application we're going to have a bunch of tiers now currently i just have one tier so here are my tiers and the only tier i have is the basic tier now i'm going to add some new tiers and i have that whole tier inside of this grid right here so you know what i'm just gonna copy and paste this grid let's just take the whole thing i'm adding two more tiers so paste once paste again and i'll just update all this so i'm gonna have the pro tier as the second tier this tier is going to be blue we'll update the description and i also have join buttons on all these tiers and whenever we click that that fires a click handler which i have in my code behind and that just pops a message box that we joined the tier so i'm gonna have to create new ones for all of my tiers so this will be on join pro clicked and we'll create that handler in just a second let's move on to the other tier and this is going to be the enterprise tier so kind of like the visual studio tears maybe i should have done community as the most basic but this will do and the fill for this will be green update the description and create a new click handler on join enterprise clicked and before i create those click handlers i think i'm going to wrap all of my cards into a grid so i can put them in separate columns so let's surround this with a grid and that grid will be in our second row so groove row one and then we'll have some columns in here so each tier will go in its own column and we'll update that so column zero for the first grid column one for the second grid get rid of this row and column two for the last grid hopefully that'll look good we might have to play around with that add some margins or something but let's create this click handler so just gonna copy this and create two new ones so on join pro click successfully join the pro tier one join enterprise clicked successfully join the enterprise tier and let's go ahead and run this all right so this actually looks pretty good they are different widths so i'm going to update that i think if we just set a width on the actual grid let's go ahead and do that so let's make all of them 200 just for now that might not be the best solution but it will look good with our current layout all right that looks good and then we can join each of the tiers and it pops the message box but i noticed something that's a little bit off so i have this black border around all of my colors for the tiers and i don't like that border i just wanted to be a little bit more fluid and just blend into the background no border necessary so we're going to go through and remove the border all right so let's remove it here and then okay i'm going to go down and remove it here and then my last rectangle remove it here and there we go that looks good that's what i wanted but i just had to update that in three places and that was a pretty simple update all i did was remove three lines one in each place but what if my changes were a lot more drastic then i'd have to do those changes in all three places ideally i would just want to do it in one place in one card that i'm reusing for all of these different tiers that i have so that is exactly what we're going to do we're going to create a custom control that'll display our tier content and then we can just reuse that control for each of our three tiers so let's create a folder in our project we're going to call this components you can call it controls components whatever you wish and we're going to create a new item in here and this is going to be a user control so i'm going to call this the tier card because it kind of looks like a card and it displays a tier and there we go so now back in the main window where we have our tiers defined let's just copy one of them and plop it into our tier card there we go and now we can reuse this but the issue is that we're gonna have to pass a bunch of different content into this tier card so for example we can't just hard code the title as basic because we need a different card for basic pro and enterprise so we're gonna have to get this content passed in and the way to do that is with a dependency property so in our code behind we're gonna define some dependency properties the first one we want is the title so we can do a prop dp snippet should be built into visual studio so expand that and this is the title property it's going to be a string because it's just text the inner class is this tiered card and by default we can make it string dot empty and now when we use this tier card we can pass in the title that we want so let me actually demonstrate that real quick so back in the main window let's just completely get rid of this first grid for basic and let's use our tier card so we can do a ctrl dot on that and import our components or controls namespace whatever you called it and now we can pass in the title that we want and we want basic as our title so we pass in basic that gets set as the dependency property the title dependency property on our tier card and now we want to use this value that's on our tier card in our actual xaml so to do that we can use a binding here and we're going to be binding to the title property but we need to reference the tier card as the source for this binding it doesn't do that by default so the easiest way to do that is to give our user control a name i'll just call it root because it's the root of our control and then we can reference that down here so pass in root and we're getting the title dependency property on our root and binding to it so it will display inside this text block and now we should see that in our application so let's run this and we should see that title and we get an error and that is because we have this click handler on our tier card but we haven't implemented that and we're just going to remove that for now there we go and let's run this and there we go we get basic as our title here so now we just need dependency properties for the other content we have such as the color of our rectangle and then this description that we have down here and we're also going to do something special for handling this join button click which we'll do in a second but let's set up those dependency properties so we are going to have a description which is also a string on the tier card and by default will be string dot empty and while we're here we're gonna have another one this is gonna be for the color property and the type of this is actually gonna be a brush on the tier card again and by default we can do brushes dot i guess we'll just do transparent as default that works and now let's use these dependency properties on our actual tier card let me just copy this binding and we're gonna set that as the fill but this time binding to the color so as you can see intellisense does pick up those dependency properties that is nice and then finally the description so let's change that and there we go so now we just need to pass those in where we use the tier card so the description we had was the most basic tier and the color was yellow and now let's run this and we should have the same thing there we go looks good but now if i try to join the basic tier it doesn't work because we removed our click handler so i want to get that back and you might think okay just grab the handler from our main window that we were using before and paste it inside of the tier card code behind but we can't do that because we're gonna have to support each of these different click handlers we can't just bake one of them into the tier card so what we need to do is have this button click propagate up and then define the handler that we want so the handler is going to be the same thing that we have in our code behind so to get that click to propagate up from the join button we're gonna have to define a routed event so this is another fundamental wpf concept in addition to these dependency properties and sadly i do not have a snippet for added events i don't think there's one built into visual studio either so we will have to manually define it so first we need to define a routed event as static on our tier card and this is going to be the join click event and we're going to register that using the event manager register a router event that's what we want we're going to name this join click the routing strategy will be bubble i go more in depth about routed events in my custom control series so i'll link to that rather than going too deep into it now i'm not exactly sure what our handler type is going to be but it's going to be the same handler type as whatever the button click event is so we'll figure that out in a second we'll just scaffold that out let me move this to a new line so we can see everything and last but not least the owner class is the tier card and now we need the actual event for this routed event that we defined and that's going to be a regular.net event we're still not sure about the handler type so i'm just going to put this as a route of the van handler might have to change that in a second and this is the join click event and this has to match what we have here so in fact we can use name of just to make sure that there's always match and it's strongly typed and now whenever we subscribe to this event we'll call add handler and we're adding a handler to this join click event for the value that we subscribe with and then same kind of thing when we remove or unsubscribe remove handler and now we need to raise this route at the event whenever we click our join button so we are going to have a click handler on here we'll call this on join click and now that we have this generated we see that this method signature is for the routed event handler so we know that that is the type of our handler just because this method signature matches the delegate of a rounded event handler so now whenever we click that join button we want to raise our join click event and to do that we can call raise event and we need some routed event args in here and the event that we're raising is the join click event so this event is going to get raised now we need to handle this event in our main window so we can have a join click handler and that is going to be for on join basic click in this case and now if we run this we click join and there we go our message box is back so now we have all of our card functionality now we can just use it for our other tiers so let's copy this and paste it two more times this time we're gonna have the pro tier which is blue a join click we'll call it one join pro clicked and this is the tier four pros and lastly we have enterprise which is the best here and that is green animal handler for that being joined is on join enterprise clicked and now we can delete all of this xaml that we had duplicated and look at this this is just so much fun just completely remove everything and now we have so much less duplication so much less xaml and the same functionality except we didn't put these into their grid columns so let me just update that real quick so group column one and two for enterprise there we go that's what we want and now you know i decided maybe i did like those borders that we had on these rectangles so let's add that back and now all i have to do is go to my single card and set the stroke as black and there we go it's added and i only have to change it in one place so i'm pretty satisfied with what we've done so far we've reduced a lot of duplication but let's tackle some more tricky concepts so maybe for my enterprise header i want to have like a little star to the side here just to denote that that is the best here and i want that to be an image so how are we going to do that well we really can't because our title is just a string we can't pass in an image to put next to that so real quick let me just get a star in here let me create a new folder for resources i have a star png i'll drop in here and then we have to change this to copy always and has to be content and i have the source control link in the description if you want to grab this image but anyways back to getting that star into the header well our header cannot be a text block instead it can be anything it can be any combination of controls it can be in our case we want a text block and an image so what we're going to do is change our header and actually i call this title maybe we should call it header so we're going to update that that's going to be the header property and instead of it being a string it's going to have to just be an object because it can be anything it can be any control any combination of controls and let me just update this real quick the header property and again it's going to be an object and now i'm going to put this header into my tier card and the way to do that is by putting it inside of a content control so the content for this content control is going to be a binding to my header on my user control which i named root and let's copy some of these dependency properties so we want it in grid row one and with the margin again and we're going to remove our text block and now here on the tier card i'm going to have to define my header so to do that we can open this up set the tier card header and we're going to define that with some xaml so for the basic and pro tiers i just want text blocks same thing as before with the text as basic in this case and they're both going to have font size i believe we had 28 maybe it was 24 i don't remember i think it was 24 actually and then let's remove this title dependency property because we don't even have that anymore and let's just copy this header to all of our other tier cards so paste that in there and paste it for the enterprise tier which we're gonna have to change to put the star next to that get rid of the title dependency properties update this to pro and update this to enterprise now for enterprise like we said we want that to have a star next to it so i'm going to surround this in a stack panel and that can be horizontal and next to this enterprise text block we're going to have an image and the source for that is going to be the resources star.png hopefully that's the correct path and we'll throw some margin to the left as well and it's going to be pretty small so we're going to make it i guess 20 by 20. and let's check this out so we can define any kind of content we want inside of our header and let's see how that looks and there we go so we got the star next to enterprise i guess it's a star i think it's actually called explosion.png but i just renamed it this star looks good enough but the main idea here is that we have a lot more flexibility because we can pass in any kind of header that we want now we created the reusable tier card but you can create reusable controls all day so maybe i would want these tier cards to be used somewhere else in my application maybe i want it on like the home screen and then maybe like on the join screen i don't know so maybe i could wrap all of these tier cards into some kind of tier card listing component and that's what we're going to do real quick so this is going to be the tier card listing and we're just going to copy all of that from the main window so just this entire grid we can actually cut that paste it here get rid of this grid row and import our tier card and we can actually do that by just changing this local namespace to components because our tier card listing is in the same name space as the tier card and there we go and i'm actually just going to copy over all of my event handlers to the tier card listing control as well so we can cut those out paste those in the tier card listing code behind so we can reuse these for all of our tier card listings and now in the main window let's use our tier card listing put that in grid row one and there we go we got our tier card listing and now we can reuse this all throughout our application if we needed to i wouldn't recommend just making a million components unless you actually really need to reuse them i think of course it doesn't hurt to do so anyways so the last thing i want to cover is how does this compare to custom controls in scenarios where you do something like inherit from button or inherit from control well in those cases you're most likely defining some kind of custom functionality for that control so for example in my custom control series i create an analog clock now that analog clock does all kinds of complicated things it keeps track of time it updates the hands on an analog clock so there's parts to that control and i put all that functionality into a custom control and then the actual template for that control is defined somewhere else and can be overwritten in other places so it's known as a lookless control and the main purpose for those is just reusing functionality so i would recommend custom controls in that case if you have some kind of complex functionality that you want to reuse and isn't dependent on how it actually looks and i would use this reusable user control approach if you want to reuse a bunch of controls that you put together such as all the controls in this tier card that don't really have any advanced functionality and we can see that in the tier card code behind we don't really have anything advanced we just define dependency properties routed events there's not really any logic that we do inside of this code behind so it's pretty simple the main idea here is just putting ui controls together so that we can reuse them so keep that distinction in mind and hopefully you can create your own reusable user controls in your own applications so that you can reduce or remove xaml duplication if you have any questions criticisms or concerns be sure to leave them below in the comments section if you enjoyed the video or are enjoying the channel consider becoming a member other than that leave a like or subscribe for more thank you
Info
Channel: SingletonSean
Views: 13,993
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, part, event, code, framework, register, static, state, default, view, style, wrap, panel, stack, scroll, viewer, first, width, command, func, action, void, model, layout, user, box, mvvm, data, error, icon, class, relay, clean, simple, sub, log, file, host, grid, scope, align, margin, deploy, github, actions, release, download, link, essential, validation, rule, logic, domain, message
Id: d1PqVmmFMSQ
Channel Id: undefined
Length: 17min 10sec (1030 seconds)
Published: Sat Jul 24 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.