Models - WPF MVVM TUTORIAL #1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
mvvm architecture is quite common for wpf applications and ultimately allows us to keep our view separated from our model so in this series we're going to be building a wpf mvvm application and we're going to be going over all the parts of an mvvm application such as the models which is the m the views which is the v and the view models which is the vms and we're going to go over some other parts as well and by the end of this you should have a good idea of how to structure and create your own wpf mvvm application and you can even use this project as a reference so speaking of the project i have this solution in visual studio and i have named it reserve so the idea behind this application is represented by this quick little uml diagram i put together so this represents the models we're going to be creating for our application and the domain of our application is a hotel reservation system hence the name reservim i thought that would sound good not sure about it but anyways we're going to start off by tackling the m of mvvm which is the models and this is where our domain logic is going to live so all the logic regarding hotel reservations is going to live in our models so here in my models i'm going to have a hotel and a hotel is going to have a reservation book just one of them and a reservation book is going to have multiple reservations and each reservation is going to be for a specific room and each room is going to have a room id so the reservation will just reference that room id so let's head into our solution in visual studio and implement the m of mvvm the models so in past tutorials on my channel i have split my solution up into multiple projects but in this case i'm just gonna have everything live in a single project this is going to be strictly a wpf application so we can select wpf application and we are going to name this just reserve we are going to target.net 5 but this should work on.net core potentially even net framework and hopefully.net 6 and beyond so we'll create that so we got our application scaffolded out let's rename our main window to reservoom and we can run the application and we get our blank screen so now we just need to build our mvvm application how exciting and we're going to start off by doing the models so we're focusing on the model layer right now the m of mvbm so i'm going to create a folder in my project for models so looking back at our visio diagrams this is kind of like a poor man's class diagram but we are going to have classes for each of these pieces of our domain so we're going to have a hotel let's create a class for that we're going to have a reservation book a reservation and we are also going to have a room id so i'm putting room id into a class because there is going to be some logic in calculating a room id so i want to encapsulate all that logic within the class so that the models of our domain layer are strong and meaningful so let's head back up to the hotel and i mentioned that my visio diagram is a poor man's diagram and the reason i say that is because this is just the class names i don't have any fields defined on here but we do know that hotel is going to own a reservation book so we're going to have a private field we can go ahead and make it read only for the reservation book and we'll initialize that in the constructor and i think i also want my hotel to have a name that might be useful when we get to the v of mvvm the view so i'll just be a string the name and we can make that read only and we'll go ahead and get that through the constructor and then just assign the property now we're going to come back to this class later so that we can implement some methods to interact with the reservation book but for now let's go over to the reservation book we can make this public so the reservation book is going to be a data structure that's going to hold all the reservations and we see that in our diagram we have a store here so a reservation book is going to have many reservations so i think the best data structure to represent the reservations in our reservation book is gonna be a dictionary actually so we can define a dictionary in here and the key for the dictionary is gonna be the room id and a room id can have a list of reservations and the reason they can have a list of reservations and not just a single reservation is because the reservations could be at different times that don't conflict with each other and i'll call this dictionary the rooms to reservations because that's exactly what it does it maps the rooms to the reservations for the room and we'll initialize this dictionary in the constructor and same thing with the hotel we'll come back here later to add methods to this so that we can interact with this dictionary but moving on to the reservation this will have a room id and we're going to make this read only so just to get her and real quick we get an error here because our reservation is public and room id is not public so let's make it public real quick and back in the reservation we're also going to have a start date so that's going to be represented by a date time for start time and this will be read only as well and we'll also have an end time for our reservation and we'll get all these through the constructor which we actually have to because i made them read only and the reason i made them read only is because i don't want these to be added to the reservation book and then somehow the room id changes on the reservation which will be bad because we map it to a specific room id as the key for this dictionary i also don't want the start time and end time to be changed because then it might conflict with another reservation in this dictionary and the reservation book wouldn't be able to handle that because all those changes will be directly on the reservation properties and last but not least we have the room id and this can have a property for the floor number which can be read only and then a property for the room number and now we're using this room id as the key for our dictionary in the reservation book so we're going to have to override the equals method so that the dictionary knows how to compare these keys whenever we add values to the dictionary or get values from the dictionary so room id will equal this other object if that object is another room id so just do a quick type check there and we'll put it into a variable because that room id also has to match the floor number of the current room id instance and then the room number has to match as well and then we get this green squiggly because if we override equals we should also override git hashcode so we can do that real quick no big deal and rather than doing our own hashcode stuff we can just use hashcode and combine all the properties in our class so we can combine the floor number and the room number and hashcode we'll just combine those into a unique hashcode for our room id but anyways we made these properties read only so we will have to get those through the constructor so let's generate that while we're here we could also override two strings so why not do that and for that we'll just have the floor number first followed by the room number so this might be useful when we get to the view as well but anyways should be done with the room id should be good with the reservation as well because all of these properties are read only so nothing else to really do there although actually we could have a calculated property on our reservation we might need this so that could be a time span that'll represent the length of the reservation and for that we can just subtract the start time from the end time so we can do end time subtract with the start time and that will give us the length of the reservation and actually this is probably something that we'll need to display on the ui eventually so i actually decided to make a use case diagram real quick just to clarify what our application is going to do before going any further with our reservation book and defining methods so the user will be able to make a reservation and then if there's some kind of conflict with making the reservation such as the room is already taken during that time then we'll display a conflict error and then the user is also going to be able to view their reservations so a couple changes to make based on this if a user wants to view their reservations we're gonna have to put some kind of user identification on our reservation class so we are gonna have another property on the reservation real quick and this will just be a string for the user name but if we were to go in depth with some kind of user authentication maybe this would just be a user id or some kind of stronger user type but for this application we're going to bypass authentication and just identify users by some kind of username that they'll put in and then we'll get this username through the constructor and then lastly to view reservations we're gonna have to iterate over all the reservations in this dictionary to get all the reservations for some kind of username so rather than a dictionary i feel like a list would be a better choice here iterating over dictionaries is actually kind of slow it's not that much slower and performance really isn't our top priority right now to be honest plus getting reservations for a room and adding reservations to a room will be a little bit slower as well but i feel like the list is a simpler approach plus it's just a private field in our reservation book we have this logic all encapsulated we can change it if we wanted to and outside classes wouldn't have to worry about it but we are just going to have a list here and now we're ready to define some methods to satisfy our use cases so first we're going to be able to get reservations for a user so we're going to return an innumerable for all of those reservations and this will be get reservations for user and we'll just get the username for that user and then simply use some good old link on our reservations and get the reservations where the username equals the username that we are querying for so that'll eventually satisfy viewing reservations now we need a method to satisfy making reservations and this will simply just be a method to add a reservation and we'll take in the reservation to add and simply add it to our list of reservations but what about displaying a reservation conflict error if this reservation conflicts with the existing reservations so for example if the room is already taken at the time of this new reservation so we're going to have to check before we add this reservation so first we're just going to iterate over all the reservations that currently exist the existing reservations so i actually haven't thought about how the reservation conflict method is going to work so we can just scaffold that out and i think i actually want that method to be defined on the reservation class this should read pretty nice so we can do existing reservation oh if i could spell this right let's not mess that up but we can check if the existing reservation conflicts our incoming reservation then we're going to throw a reservation conflict exception so we're gonna have to create a class for that i'm gonna put that in its own folder for exceptions and create a new class a reservation conflict exception we're gonna have to extend exception we can generate all these constructors and i like to have some data with my exceptions so we are going to have a reservation on here import that this will be the existing reservation we'll make that read only get that through the constructor in a second and we also have the incoming reservation so we can add these to all of our constructors go through all these add the parameters there we go now let's go ahead and use this exception in our reservation book import it and pass in our reservations to the existing reservation we got that and then the incoming reservation is the one passed into this method so now we just need to implement conflicts so let's generate that method so first off we know the reservations do not conflict if the room ids do not match so for that we can just return false right off the bat and now a reservation will conflict if the reservation that's incoming has a start time that is before the existing reservations end time or the incoming reservations end time is after the existing reservations start time and now back in the reservation book we will throw this exception if we get any conflicts but if we get past all the conflict checks then we'll add the reservation so we should be able to satisfy all of these use cases let's head all the way back up to the hotel now and finally let's define some methods that use our reservation book and these will be pretty straightforward so in fact we're going to have the same exact method names that we have on our reservation book and we'll just delegate all this functionality down to the reservation book so pass in the username to get reservations for user on the reservation book and then we'll also have a make reservation passing in the reservation that we want to make and we'll use the reservation books add reservation and pass in the reservation so then i'm going to go through and document all my methods real quick i especially like to do this that i can document exceptions such as our reservation conflict exception all right so i'm pretty satisfied with our models now let's go ahead and set this up in the app.xml.cs so what i'm going to do is override on startup and we'll just create a hotel real quick import that give it a name the singleton sean suites and then we'll use the hotel to make a reservation so let's instantiate one of those and we're gonna have to instantiate a room id so we'll be on the bottom floor room number three our username is singleton sean just throw in a random date here for the start time and for the end time so let's get another reservation in here we'll avoid a conflict right now because first i want to get my reservations so pass in my username and there we go let's put a breakpoint here and see our reservations and here we go we got a list of two reservations and now let's get a conflict so we're gonna wrap this in a try catch gonna catch a reservation conflict exception and now for a conflict gonna have to have the same room id we're gonna have to have conflicting times and now let's see if we get our exception i hope we get an exception oh we didn't so apparently our room ids do not equal but clearly they do oh and i forgot we're actually using the equals operator here rather than the dot equals method which is what we overrode in our room id so actually what we have to do or not what we have to do we could just use the equals method but what we're going to do is override the equals operator for the room id so this just takes in a couple of room ids so the only weird thing about overriding the equals operator is that we have to do null checks here so if they're both null then we will return true and then we just dig into our equals override so we can use room id 1. i'm gonna have to null check that first and then use equals to pass in room id2 and then if you override the equals you have to override the not equals which is actually what we use but that's pretty easy because now we can just use our equals operator so i return the opposite of comparing room id 1 and room id 2. oh and i forgot we're using equals equals here but we're currently implementing equals equals so we get a stack overflow so we have to use is so check if it is null and then use is null down here but we want the opposite of that so difficult but now finally we hit our exception our reservations do conflict and our model layer is good to go keep in mind that some applications your model might be much simpler for example a blog application you might just have a post with a user and maybe a comment and some properties on those classes maybe this isn't the best hotel reservation domain model in the world but it is our model and it will indeed satisfy the m of our mvvm application which we will continue next time hopefully you can apply these concepts to your own 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 enjoyed the video consider becoming a member other than that leave a like or subscribe for more thank you
Info
Channel: SingletonSean
Views: 12,003
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, animation, key, frame, storyboard, story
Id: fZxZswmC_BY
Channel Id: undefined
Length: 15min 21sec (921 seconds)
Published: Sat Sep 04 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.