Navigation - WPF MVVM TUTORIAL #5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
we've covered the core concepts of mvvm we've added models views and view models we've also covered commands which kind of fit into the view model layer but in order to bring our application together we're going to need some navigation so that we can navigate between our views and navigation really fits into the broader concept of stores so a store is something that manages our application state it's our single source of truth so navigation fits perfectly here because we want our navigation state to be centralized so we know what view we should display and we can control what view we're on from anywhere in the application now we are going to cover stores more in depth later in the series because they're useful for other things such as asynchronously loading data and communicating between view models but navigation will be a good place to start to demonstrate these concepts and we really need navigation right now so we are going to start off by creating a stores folder in our project and inside this folder we're going to create a class for our navigation store and i feel like i've covered navigation so much on my channel so i will be linking to the main series where i discuss navigation and some more advanced concepts there but all our navigation story is going to do is store the current v model for our application so we are going to have a property on here which will be our view model base which all view models inherit from and this will be the current view model now i'm actually also going to create a backing field for this property it's just a private current view model and we need this backing field because we're going to do a little bit more inside of our setter but our getter is going to be pretty straightforward just return the value of that field but then in the setter we are still going to set the current viewmodel to the value that gets passed in to the setter and then we'll come back here later and add something else but anyways this navigation store is going to hold the current view model for the application so that means we only want one navigation store in our application we don't want to instantiate this multiple times because then we wouldn't be sharing this current viewmodel state throughout the application so that means in the app.xaml.cs where we start the application we are going to have our navigation store in here so right at the root of our application we can instantiate that in the constructor of our app and now this will be our single navigation store for the application and we can pass that down throughout our application via the main view model and in fact our main view model actually needs the navigation store so that we know what view to display on our main window so what we're gonna do is get that navigation store as a field in our main view model so import the navigation store and now to get the current view model for the application we're just gonna get that from our navigation store which has a property for the current view model so rather than storing the current viewmodel state on our main view model we have it in this third party kind of mediator like object which will allow us to change the current view model for the application from pretty much anywhere as we're about to see in a little bit but now let's get the navigation stored through the constructor let's just generate a new constructor and get rid of this old one we don't need that anymore and now in our app.xama.cs let's pass in the navigation store and back in the main v model so the current v model is from the navigation store but by default that currentviewmodel is null so on our application startup we will set the currentviewmodel i think i want this to be the reservation listingv model so let's instantiate that there and now actually if we start this we are going to see we're still in the make reservation view and that is because in the main window we hard code the make reservation view as what we display in the main window but we want our view to be determined by whatever the current view model value is so ultimately we want to map our view models to views and the way to do that is with data templates so on our root grid in our main window we're going to have some grid resources and we can define data templates and our data type is going to be our viewmodel so let's get our viewmodels namespace in here let's call that vms and that'll point to the viewmodel's namespace and i want to map my make reservation v model so we can do an x type and get the make reservation view model from our vm's namespace i want to map that to a make reservation view and we actually don't have to define any data context here that's automatically going to get set to this make reservation view model that we're mapping from and then we want another data template this time mapping the reservation listing view model to a reservation listing view and now that we have those mappings we can now use a content control and set the content of our content control to the current view model and that current viewmodel in our case is either going to be a make reservation view model or a reservation listing view model so when that content is set it's going to be like oh there's a data template for that so the content control will display the corresponding view and now if we run this we should see our reservation listing view which we do indeed so now i want to click make reservation and go to the make reservation page and to do that what we are going to have to do is change the current view model in our navigation store so that means our navigate command which is what the make reservation button is binding to that's going to need our navigation store in here so that we can ultimately change the current view model so we can get that through the constructor and for now we're just going to hard code the new view model that we want so we're going to set the current v model to a make reservation view model and that actually needs a hotel for now we're going to hard code a hotel in here and give it an empty name and now lastly in the reservation listing view model we need to pass a navigation store to our navigate command in here so we can get that through the constructor to add a parameter for that and then we instantiate this in our app.zambo.cs and we conveniently have our navigation store here so now we should be able to click that button so make reservation there we go we hit our breakpoint in the navigate command so we are going to set the current viewmodel to a new value and we did not change the view so the reason for that is because the main view model is getting the current view model from the navigation store but this current v model changed and we did not raise an on property changed for this current v model property so the view didn't re-grab the value of this property and update the view so our navigation store is going to have to notify the main view model when the current v-model changes and the easiest way to do that is with an event so we can define an event on our navigation store it can just be an action instead of subscribing with a method that has no parameters and returns a void and we'll call this current view model changed and when the current view model does change we'll create a method called on current view model changed which will just give us a clean way to invoke this event so we can take our event and invoke it so we are going to be raising this current viewmodel changed event so in our main view model we want to subscribe to that event so let's create a method to handle that we'll call it one current viewmodel changed and when the current viewmodel changes we want to call one property changed so that our ui will re-grab the value of the currentviewmodel and update our view so let's try this again click make reservation and there we go view updated hooray so the next thing i want to tackle is when i'm on this make reservation view when i click cancel i want to go back to the reservation listing view so last time we did create this cancel make reservation command which we would execute whenever we click that cancel button but what i'm thinking instead is that we're just going to reuse the navigate command to do the navigation so we're going to remove this cancel make reservation command and just use our navigate command originally what i was thinking was the cancel make reservation command would do something a little bit more than navigation by like displaying some kind of message but i think i want to keep it simple and just do regular old navigation so we will update that in the make reservation view model we will just use a navigate command which takes a navigation store and we'll get that as a parameter to our make reservation view model but now the issue we have is that the navigate command just takes us to the make reservation view model every single time and that's not what we want this time we wanted to take us back to the reservation listing view model so what we're going to do is move this viewmodel instantiation into a function and then we'll take that function as a parameter to this navigate command and then we'll just execute that function to get the viewmodel that we want to set as the currentviewmodel so this will be a func that returns a viewmodelbase so it can be any viewmodel and we'll call this createviewmodel and we'll put that into a field and then instead of instantiating the viewmodel right here we'll just call our createviewmodel method which is going to give us back our viewmodel so now our make reservationv model needs that create viewmodel so we're going to get that through the constructor as well and then just pass that into the navigate command and then we're going to do the same exact thing in the reservation listing v model so let's just paste that create v model in there and pass that in to the navigate command as well and actually i want this to create a make reservation v model so let's change that and require this return type to be a make reservation view model and then same kind of thing in the make reservation view model i want this to be a reservation listing view model and we'll rename the parameter as well and then all this bubbles up into the app.xaml.cs so we need to pass in a function to create a make reservation view model so we can just define that function right here so giving back a make reservation view model we'll call it create make reservation view model and all we're going to do in here is instantiate a make reservation view model that needs a hotel we got our hotel right here in the app.xaml.cs it needs our navigation store we got that as well and then it needs a function to create a reservation view model so we're going to put that into a function so create reservation view model and generate that method and in here instantiate the reservation listing view model which takes a navigation story and a function to create a make reservation view model well we got that right here so we can just pass that in and in fact we now have this function to create a reservation view model so we can just use that up here where we set the initial view model for the application so now go to the make reservation page there we go let's cancel and back on view reservations so one thing to note is that we are instantiating a new view model each time so click make reservation we get a new view model and then go back to the reservation listing view new view model as well so i believe the last navigation we need to do is on the submit button so let's throw some data in here and submit and what i would want this to do is take me to the reservation listing view so let's head into the make reservation command so that's where the submission goes and right when we're done making the reservation we want to re-navigate so what we could do is similar to the navigate command we could get a navigation store in here and then a create view model delegate and then do the same exact thing but then we kind of be duplicating all of this and all the current view model setting so what i'm going to do is create a service that'll take care of all this navigation for me and i'm going to create a new folder over here for services i want to go more in depth with services in another video but i feel like this really fits into navigation right now so this is going to be a navigation service and i'll just have a simple method to navigate and all navigate is going to do is the same thing we're currently doing in the navigate command so we can cut this out and paste that in here and then it needs a navigation store and a create view model func so let's just copy this entire constructor and our navigate command and paste that into the navigation service import everything we need and change this constructor name for the navigation service so now we've encapsulated all of this logic into our navigation service and now in our navigate command we can just take a navigation service so make sure you import the one from reservem.services not the one from system.windows and get that through the constructor and now to navigate all we have to do is take our navigation service and navigate and that's going to do the same exact thing it was before except our navigation service is doing it and the benefit of that is that now in the make reservation command all we need here is a navigation service so we'll get that through the constructor and actually i'm going to call this the reservation view navigation service because that is ultimately where i want to navigate to put that into a field and now when we make the reservation we'll take our navigation service and navigate so now we did change a bunch of constructors for example the navigate command now takes a navigation service and the make reservation command takes the navigation service as well so we're gonna have to update all these constructors so our make reservation command now needs a reservation view navigation service which will get through the constructor so generate a parameter for that and now the navigate command needs a navigation service as well and that's actually going to be the reservation view navigation service as well so i want my submit button and my cancel button to both take me back to the reservation view so i'll just use the same navigation service and now we no longer need our navigation store we no longer need our view model func and our constructor is much simpler and now same thing in the reservation listing view model our navigate command needs a navigation service and this will be a navigation service that takes us to the make reservation view so we'll call this the make reservation navigation service get that through the constructor get rid of these old parameters that we don't need and now we're finally bubbling up to the app.xama.cs so now we have to pass in a navigation service here so let's instantiate that and we have to pass in our navigation store and in this case the create reservation v model and then same kind of thing for our reservation listing view model passing in the navigation service so now go to make reservation i can cancel so navigation still works but if i make a reservation and submit that we navigate back to the view reservations but you may have noticed my reservation is not on here so that being said our reservation listing view model will take the hotel as a parameter so let's pass that through add a parameter for that and let's get rid of these hard-coded reservations we can create a method called update reservations and first what we'll do is clear any existing reservations which by default there should be none because the only time we call this method is in our constructor when our collection has just been initialized but let's clear and then we're going to iterate over all the reservations in our hotel so i think what i want to do is put my hotel into a field so get the hotel reservations i have this get all reservations method and now we'll simply map each reservation to a reservation view model so instantiate that pass in the reservation and we'll add that view model to our observable collection of reservations so there we go we got no reservations maybe we would want to display something on here like no reservations have been made rather than just showing this empty grid but we can handle that later let's create a reservation so submit that and there we go there's our reservation so the reason we don't have to raise an event or anything on our hotel is because we instantiate a new reservation listing view model every time we go to the reservation listing page so we will be updating the reservations by default but anyways we have our models views view models we have commands we've implemented navigation to bring our application together we still need to go deeper into stores i want to look into services for asynchronously loading data and maybe go into some other things like styling and error handling but we do have a functioning application right now so hopefully you can apply these concepts to your own wpf mvvm application 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 enjoy the video consider becoming a member other than that leave a like or subscribe for more thank you
Info
Channel: SingletonSean
Views: 3,678
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, 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, essential, validation, rule, logic, storyboard, story, navigation, store
Id: bBoYHl3pLEo
Channel Id: undefined
Length: 15min 40sec (940 seconds)
Published: Sat Oct 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.