Practical Attached Property Behavior - WPF RESPONSIVE DESIGN ESSENTIALS #2 (.NET CORE)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody welcome back so I have more news from my experimentation with responsive design in WPF now last episode what we did is we set up this responsive stack panel so whenever our window is wide enough we make our stack panel go horizontal but then whenever our window gets skinny or too small we make our stack panel vertical so that all of our elements fit on the screen and we can just scroll through them now to set this up we created this style and there's a couple of issues with this style so first off this ticks quite a few lines of code and even worse this style is not reusable at all we depend on this element name of root and then we also hard-code this converter parameter of 400 so even if we didn't depend on this element name of root that means every single stack panel that used this style would have to go into horizontal mode whenever the width of the window went to 400 so based all those issues we cannot use this style in my opinion so let's just go ahead and delete it and we're also done with this converter as well so we need a better solution and what is that solution it is behaviors behaviors are super powerful in WPF there's actually two ways to implement behaviors you can use behaviors in the form of attached properties which are built into WPF or you can use behaviors from the system windows interactivity DLL which we're not going to be getting into in this episode because I really haven't touched as much I really feel that attached properties are super powerful in WPF and they get the job done plus they're built-in so you can't go wrong with them and they're pretty fundamental part of the framework so let's go ahead and set this up let's make some attach properties so that we can get a responsive stack panel so what I'm going to do is create a new folder here and this is going to be behaviors and we are going to create a behavior here called the responsiveness behavior so keep in mind I'm calling this the Ries positiveness behavior because this is gonna have nothing to do with stack panels this is going to give us responsiveness for any element in WPF so it's gonna be super awesome let's go ahead and make this public and let's start defining our attached properties that we're gonna use that are gonna make up this behavior so what you can do is you can use this prop a snippet hopefully this is built into Visual Studio for you guys it was for me so go ahead and set up this property snippet and just press tab and it will generate an attached property just like that and if you guys aren't familiar with the touch properties no worries we're gonna go over that in just a second so this first attached property we are going to name this that is responsive property and this is just going to be a boolean and the owner class is going to be this behavior so the responsiveness behavior and by default is responsive is going to be false that's the first property or the first parameter of this property metadata constructor let's go ahead and move this to a new line and let's import all of this stuff so what is so great about an attached property it's actually very similar to a dependency property except all we're doing here is we register attached rather than just register so we're registering an attached property and what is so great about this well if I go into my stack panel view and I import the namespace with that behavior so our behaviors and then on the stack panel I can use that namespace take a look at our responsiveness behavior in that namespace and I have this is responsive property so by using an attached property we can well we can attach this property to any element in WPF so I am going to set is responsive on the stack panel to true so what does that do well it does nothing because we don't react to setting is responsive to true own elements so this isn't just like magic we're not going to be able to set is responsive the tree on our stack panel and it's gonna work we're gonna have to actually do things in there but before we get into that let's define some more attached properties so that we know what to do when is responsive gets set to true so we're also gonna need an attached property and this is going to be horizontal breakpoint property and this is going to be a double and the owner class of course can be the responsiveness behavior and by default this is just gonna be double dot max value actually and what this basically represents is that converter parameter that we had before so before it was 400 as that converter parameter and what we did was whenever the window was 400 we went into horizontal mode so that is what this horizontal breakpoint property is it's going to be that 400 so another thing that we're gonna need is an attached property for what we want to do when the window width is wider than this horizontal breakpoint so inside here we're gonna have horizontal breakpoint setters and this is going to be a setter based collection so this is pretty much what you see in a style you see a collection of setters that's what the setter base collection is going to have inside of it and it's going to be responsiveness behavior and by default it's just going to be an empty setter based collection let me move this to a new line as well like that all right so what we're doing is we're gonna have a horizontal breakpoint and whenever the window is wider than that breakpoint we're gonna apply all these centers to the element that is responsive now one last thing that we're actually going to need is we need to track if these setters are active or not so what I'm going to do is create another attached property is horizontal breakpoint setters active and this is going to be a boolean so they're either active or they're not and by default it's just gonna be false so there we go that is all of our attached properties that we need now we need to just set this up so that whenever the window is wider than this breakpoint we apply all those setters to our responsive element so let's actually go into our stack panel view and set up what we want those values to be so behaviors responsiveness behavior what do we want our horizontal breakpoint setters to be well we need a setter based collection and inside here we want to set the stack panel orientation property to horizontal and as you guys may have noticed I prefix this with stack panel because we're not inside of a style so we need to explicitly state the path to the property so we're gonna set orientation a horizontal and actually while I'm here I'm also gonna set horizontal alignment to Center cuz why not show off how you can do multiple setters in here and then the other attach property that we have is horizontal breakpoints so this is when we want these setters to be applied so when the window is wider than 500 we want these setters to be applied so now we just need to actually implement this so you might be thinking okay I know what you're going to do inside this setter right here this is what gets called when we set is responsive the true what it's going to do is call this method pass in the stack panel pass in the new value of true what you're gonna do Sean is you're gonna check if that value is true you're going to apply a bunch of stuff to the stack panel to make it responsive but that is not the case that is not what we're gonna do you really do not want to mess around inside of the setter because if I were to do that and apply a bunch of stuff to the stack panel make it responsive and this set value didn't actually set the value say there was some kind of validation then that wouldn't be good because that means it wouldn't actually be responsive but we just applied all that stuff so what you want to do instead is you want to set up a property changed callback that is only going to be called when the is responsive property actually got set so I'm gonna call this one is responsive changed and I'm gonna generate this callback let's go ahead and move this all the way to the end of the file because I don't want to get it mixed in with all of these property definitions right here so what I'm gonna do is I'm going to check if the dependency object so this is gonna be our stack panel I need to make sure it's a framework element and a framework element is pretty much the base class for almost every element in WPF or at least a lot of them so we're going to be able to apply this behavior to pretty much every element so let's call this element and what I want to do is I want to get a reference to the current window of the application and you'll see why in a minute but you can do this with application current main window and then what I want to do is I want to see if this new value is true so I want to see if our stack panel or our framework element or whatever gets passed in here I want to see if is responsive is true on that and to do that we can call it get is responsive which is this method up here and it'll give us the new value of the properties so I can pass in the framework element so if that's true what I want to do is I want to take my window and I'm going to subscribe to the size change event and inside here I'm just gonna do a little anonymous function I am going to update the element and pass in the window and pass in the element so this is going to execute this method that I generate it's going to execute every single time the window size changes so inside this method we really do not want to be doing anything too intense because I mean size changes that's like pixel-by-pixel any little change it's gonna fire update elements now if is responsible gets set to false all we're gonna do is unsubscribe so let's go ahead just do a little minus equals there and this element is no longer going to be responsive so inside here what I want to do is I want to get the window width so we can do that with our window that we have and I want to see if the width of the window is greater than the breakpoint width so this horizontal breakpoint property that we have here and if it's greater than that then we're going to apply our horizontal breakpoint setters that we define so let's go ahead and get the breakpoint width for the element and we can do that with our get horizontal breakpoint method right here pass in the element so for example for our stack panel that's going to give us back this 500 because that's what we passed in as the attached property value so if the window width is greater than what you greater than or equal to the breakpoint width then we are going to first offset is horizontal breakpoint setters active for the element that's true so that means we are currently in horizontal mode the reason we want to keep track of that is because inside this if statement we only want to apply those horizontal breakpoints setters if the setters aren't currently active so we can make sure that is the case by calling get is horizontal breakpoint setters active so that's going to give us back the value of this attached property and if it is false then we are going to activate the setters and we're going to do that by applying a custom style to our element so I'm actually going to move this to its own method so we'll call this create responsiveness style for the element but we'll do that a little bit later but otherwise if the window width is less than the breakpoint width so that means we need to go back into vertical mode we need to unup lie that responsiveness style that we're going to create right here undo all these setters and we need to make sure that the setters are actually active before we try to unapplied them then what we're gonna do is first set these setters to inactive for the element and then we are going to undo the style and we'll go over how to do that in just a second so let's actually create this responsiveness style and inside here we are just going to create a new style so I'll call this responsiveness style and the new style and inside this constructor we specify the target type so that's going to be element get type of our framework element so of course if our framework element is a stackpanel this is going to return stackpanel it's not gonna return framework element because you know polymorphism and then we're gonna base the style off of the current element stuff because I don't want to override the element style because it might have specific stuff applied to it such as like a background color or something I don't know but then inside here we need to apply those horizontal breakpoint setters so we need to apply everything in this center base collection that is our horizontal breakpoint setters property so what we're going to do is do it for each and we're going to iterate over all the setters in the horizontal breakpoint setters attach property for the element and we're going to apply the setter to the style by just adding it to the setters collection for the style like that and then once we're done with that we can just return their responsiveness style and there we go so now inside here we have this method and how are we going to undo the style well to do that we can just get the style that we based on so we passed it in right here this is the old element style that doesn't have the setters so that is what we're basing the response in the style on so if we just set that as the new style it'll undo all the setters there we go so now let's go into our stack panel view and I think we're actually ready to test this out so let's give it a go all right so it looks good so far we are horizontal because our window is past that 500 breakpoint so let's actually go small and there we go now we are no longer applying these horizontal breakpoint setters because we are under 500 for our window width so that's great but you might be looking at this and you might say okay well we still have to define all this but take a look we can define a style for all of our stack panels so we can give this a target type of stack panel and inside here let's actually bring in our behaviors namespace right there and I can provide setters for these properties so I can set the property for the behaviors is responsive we can set that the true by default and then I can also set the horizontal breakpoint setters and of course to provide this value we're gonna have to put this into its own little nested value down here and we can just go ahead and copy that from right here and remove that you can also remove is responsive the true because we're gonna inherit that value from this style and there we go and we get the same behavior and why is this great because now if I have another stack panel so let me just copy this and we're gonna have to wrap this in a another stack panel so that we can have multiple elements here so now let's say this stack panel has a bunch of user cards so we don't want this one to go horizontal until say 800 so when our window is greater than 800 width then we're gonna go horizontal so to set this up all I had to do was change one little property right here and now our stackpanel didn't go horizontal until we hit that breakpoint so this is all tucked away in a style it's super reusable and it's all through the power of attached properties to make a behavior and even better it's not even tied the stack panels you can do this for pretty much any element you want so we're probably explore that later in the series and a future episode anyways if you guys have any questions criticisms or comments be sure to leave them below in the comment section but other than that if you like the solution be sure to leave a like or subscribe for more thank you
Info
Channel: SingletonSean
Views: 3,202
Rating: undefined out of 5
Keywords: wpf, programming, visual, studio, xaml, custom, control, generic, system, line, display, dispatcher, timer, template, binding, behavior, c#, how, to, series, tutorial, easy, time, reusable, maintain, package, design, part, dependency, property, attached, event, converter, code, metadata, framework, register, static, delegate, state, visual state, null, default, clean, user control, view, multiconverter, multibinding, sizing, dynamic, trigger, media, query, responsive, style, grid, wrap, panel, stack, scroll, viewer, bar, card, component, mobile, first
Id: PMSrH8RemTc
Channel Id: undefined
Length: 18min 30sec (1110 seconds)
Published: Sat Jun 06 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.