Creating Custom Observable Collections (w/ INotifyCollectionChanged) - WPF TUTORIAL

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today i want to show off how to create a custom observable collection so observable collections in wpf offer us a list like api where we can add remove or insert items but what if that api doesn't really fit our application what if a queue or a stack will be better all for our application well then we would want something like an observable queue or an observable stack and that is exactly what we're going to make in this demo let me start off by introducing this demo so i kind of have this drive through setup let's start this up and if you think about it a drive through is kind of like a queue because the first car in is going to be the first car out in most cases i would hope otherwise everything else would get messed up with the orders but anyways for this application you can put in the item you want to order submit it and that actually doesn't work right now because we don't have an observable queue yet but when we submit let me go to my submit order command we submit and we submit the order to our viewmodel which puts it into our orders queue that currently has one of the orders that's an order view model that we created in the submit order command but we're not using an observable queue so our ui does not get updated right now we're just using a regular queue so we need an observable queue so let me create a new folder in my application we're just going to call this utilities because that's exactly what this is it's just a utility that offers us a cue api that's also observable and inside here we are going to create our observable queue so there's actually many ways we could do this we could wrap an observable collection with a q api that does things like nq and dq we could wrap a q and then do what we need to do to make it observable or we could just inherit from q and that's going to be the easiest approach so i'm going to go with that so we're going to inherit from q and we're going to make this generic so we will make our observable queue generic as well so now we have the same exact q api we're inheriting from q but we need to make this an observable queue so we need to implement i notify collection change import that and implement that interface and that just requires that we have this collection changed event that we need to raise whenever our queue changes so when is our collection going to change well it's going to change whenever we enqueue an item into our queue so what we need to do is override our cues nq method so let's first get that method in here i believe it's void and that is nq and that takes the item that we want to enqueue and first off we need to actually enqueue the item so we can do that by calling the base and queue method and pass in our item but then what just happened our collection changed so we need to raise collection change so we will take that event and invoke it the sender is this and we need to pass in some notify collection changed event arc so let's instantiate those and there's a ton of constructors for this so the first parameter is what kind of action happens well in this case we added an item so we will set our action as add and then if we look at these constructors they have this description of the action parameter so in this case we can only use this constructor if the action was a reset so we need to find what constructor is allowed for the add action so let's scroll through those and actually the second one looks like the one that we want so this describes a one item change which is exactly what we have we added a single item so we can pass in that changed item and that is just the item that we added now if we look at this enqueue method we see it has the green squigglies and that is because we hide the base cues enqueue method so you know you might think okay object-oriented programming let's override this because we inherited q but nq is not a virtual method so what we have to do is use new as our way of hiding the base method and i'm not going to go into the differences between new and override in this case but the quick summary here is that this and q method is only going to be called if the type of the variable or field that calls this method is an observable queue which it will be in our case hopefully that explanation made sense otherwise i'm sure there's plenty of resources out there on the differences between new and override but anyways we can enqueue items so that's good enough to test this out let's go ahead and use this observable queue in our drive through view model so i have a queue right here now this is going to be an observable cue and let's import that so now whenever we enqueue an item oh this has to be an observable cue as well where we instantiate it but now whenever we enqueue an order into our drive through our ui should update because as we recall we've raised collection changed which our ui is going to listen to so let's go ahead and run this and let's select an item and add it and there we go we got our chicken in our orders so that's like the customer placing the order so maybe when the order is done i want to give the order to them so i press this give button and then it would remove the order and give it to them so to do that we use the dq method so that means we're gonna have to go back into observable queue and create a new method for dq this is also going to have to hide the base dq so we will use new and i think i don't think this returns void was this return oh obviously it returns the item in the queue that we're dequeuing so it's going to be our t type and this is dq and we'll start off by calling dq on the base queue and we're going to put that into a variable so that's the item that we dequeue and eventually return that from the method but what happened when we dequeued well our collection changed so let's just copy this and this time our action that we're raising with this event is a remove and we can pass in the item that was removed so now let's go ahead and test this out we should have our item get removed so first let's enqueue an item into our orders and then let's give that order to the customer and oh looks like we used the wrong notify collection change to event args constructor so this remove action has to specify the item's position well if we're dealing with a q then we know that position of the item that we dequeued was at the front so that would be index zero so that's easier than i expected let's go ahead and try this again hopefully that's the constructor that they wanted so let's place a couple orders we'll do a different item a salad it's a very healthy restaurant and let's submit that and now let's give which should be the chicken because that is the first item that went through let's give that and there we go the item does indeed get dequeued so now we've implemented all the methods that we need for our drive through but we also are going to have to override all the other methods that change the collection so that we can raise collection change accordingly so let's take a look at what those are we can look at our base queue for that and that would be clear so whenever all the items get cleared our collection has changed and also try dq so let's start off with clear so we're going to have a new method for that i believe that was just void and clear and we'll call the base clear method and then raise collection change let me just copy this but this time what happened well we have a few options here we have reset so the contents of the collection changed dramatically i think this is a pretty dramatic change but you could also argue that it should be a remove but if we look at remove this specifies that an item so implying that it's singular was removed from the collection so i'm not sure about that i think reset is a better option here so we're going to do that and pass in nothing to this constructor and i feel like i should test this out so let's change dq into clear and then try this out so we'll throw a bunch of fruit cups in here and now let's click give which is actually going to clear all the items and there we go as expected and then the last thing we want to do is create a new method for try dq so i believe this returns a boolean for true false for success and this is try dq and it has an output parameter for the item that was dequeued if it was successful so that's going to be our t type and we'll call that item and we'll call the base try dq pass the output to our item parameter and we're going to put this into a variable to return it at the end of this method which we will do true false for success and then gonna have to raise collection changed and it's gonna be exactly the same as the dequeue method so we just copy that and paste it because it's pretty much doing the same exact thing so let's go ahead and run this and actually maybe i should only call that if it was successful so if we did successfully dequeue an item then we should raise collection change otherwise we don't need to raise it and if we did raise it and it wasn't successful then this item we pass in will be gnaw so that's probably not a good idea let's go ahead and try this out first off update our view model to use try dq and throw in an output parameter even though we don't use it so place a bunch of orders and then give an order and same functionality we do successfully dequeue the item with try dq so there we go we have created our observable queue so our ui does update as we enqueue dequeue clear or try dq items from our queue and keep in mind you can do this with any kind of data structure such as a stack maybe you have some kind of weird tree that you're binding to somehow all you'd have to do is provide some kind of api that raises a collection changed event on i notify collection changed whenever the items in that collection are mutated so keep this in mind if you need to create your own custom observable collections for some kind of different data structure other than a list if you have any questions criticisms or concerns be sure to leave them below in the comments section if you're enjoying the channel or enjoyed the video consider becoming a member other than that leave a like or subscribe for more thank you
Info
Channel: SingletonSean
Views: 504
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, first, width, command, func, action, void, model, user, box, mvvm, data, error, icon, class, relay, clean, simple, sub, log, file, host, grid, scope, align, deploy, github, actions, release, essential, validation, rule, logic, domain, message, obvservable, collection, notify, changed
Id: 3XQNvPmydHg
Channel Id: undefined
Length: 9min 38sec (578 seconds)
Published: Sat Dec 18 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.