Our guys will come back.
So let's jump right into creating our view model, our view models, right?
So typically we want to start off with a base, right?
The same would kind of go for model, right?
So like a model.
Typically all of them would have an idea.
So let me just do this for an example.
So we could have had a base class so public.
I'll call this one public class base model or base entity and we call it entity cos will soon be looking
at data base stuff and then that base entity would actually have an ID and typically would want to be
this abstract because base entity shouldn't stand on its own.
Right.
So just create that base entity, place it in its own file.
And then our model or models, all of them that require that base property or those base properties
would just inherit from the base class.
Right.
So that way we don't have to repeat ID every time or if we need to change it to only change it one place.
So let us go over to view models now with that principle.
So the first one I'm going to create here is a base view model.
So our base view model is going to have the base properties that we know whatever view model would probably
need to have.
And then what happens with these view models is that our with MVM is that we actually have the inherit
from an interface called I Notify a property changed.
When you put that in here you wouldn't have to add a missing using reference, but I notify property
change wants us to implement an interface and that interface has the event property change event handler.
So what happens is that this interface allows our properties from our view model to be observed by the
application.
And any time they change, we would actually want to fire off an event that says, Hey, the property
has changed, right?
So I'm going to implement a method here.
So public void and I'm going to call it on property changed.
Let me just copy this quickly.
On property changed.
I would like to take the callers name so I can just say caller member name.
And then, as I say, street name is equal to null, right?
So by default, what this will do is say, okay, get the name of the I would just include the missing
using reference, get the name of whatever property was triggering this.
So and we put in our properties, of course we would want to actually pass in the name of the property,
but using this, this which I call this on this attributes or this annotation, we can bypass the passing
in the manual passing of the name and it will just know what member name came in and stored it here
and the string variable name and we'll just before that to null.
Right.
And then well we just really just generated that line for me so pretty much is just going to say property
change invoke and then it's seeing in the notification that something has changed and the argument for
the change will be the name of whatever property has changed.
So all of that to kind of go back now and say, okay, what properties would we typically want?
So before I do properties, let me do fields.
The first field I'm going to do is titles.
I can see a string, underscore a title.
All right.
And the difference between properties and fields properties.
Well, property is the name that you get something that is publicly accessible and and and feels sorry
is what we call the private ones.
Right.
So I have two here.
I have string title and our bull is busy.
So title will be used to determine what is the title of the piece that we're on where as is busy will
be used to determine.
Is the page currently loading?
Is it busy fetching the data, busy carrying out an operation?
And we of course, change that value after the operation is completed.
Now let's move on to their matching properties.
So the first property I'm going to define here is the is busy, so is busy.
And then typically you would say get return is busy and set is busy is equal to.
So that's what Visual Studio wants.
But Visual Studio is not quite on the same page as us because we're about to get a little more creative
than what Visual Studio is suggesting.
So let me take it's edition.
What we're going to modify it so the get well yes we are going to return is busy that's fine.
We could also have written this like in this syntax if you wanted to write can make use of the more
modern syntax so that would be the same thing as seeing return is busy right for the set.
We're going to have a little more logic here.
Right.
So for the set, I'm going to see if.
Is busy.
On the square is busy is equivalent to whatever value came in.
And so we're trying to change or trying to change something.
And if that is the same as the value that came in, then we just need to return.
So if we're providing the same value, which in this case would be true or false, if it's already true,
we're getting the same true, then that's fine.
We can return.
Otherwise we want to assign is busy the value and then we want to call our on property changed method.
So let's go again whenever we're going to be changing the value of is busy we want to see is the private
property is a private field sorry the same value as our property.
Then if it is, then there's nothing.
We don't need to do anything right.
Frankly, this statement could be optional because we could always just set it to the value and return
the property change.
But then if it is true and it's already it's already true and we're sitting at the true again, then
we wouldn't want to fire off.
That's something I'd change because nothing changed really.
Right.
And then we would do something very similar for a title.
So if I do this, I just copy all of that and just change this to string and change just a property
called title which is then going to return or field called underscore title and then we're checking
is a title the same as a value?
Then don't do anything otherwise.
Set the title to the value and return on property change.
Now, that is the typical syntax for the MVM pattern.
All right.
Now, if you're tired after just seeing this, I understand, because I got tired many times trying
to do this, and especially when you have multiple properties that you want to observe like this.
So thankfully, Microsoft has provided an Nvme toolkit which helps us to generate some of these things,
right?
So without us having to write all of this verbose code for every single property, we can actually go
and get that toolkit library and then we can cut out some of this manual work.
So let us go over to the new Get package manager.
That's right.
Click our project, go to you, get package manager and then we will browse and look for community tool
kit.
Start Nvme and we'll just download that one issued by Microsoft that toolkit so we can go ahead and
install that.
But what this library really brings to the fore, if you just read the literature that it comes with,
it comes with a bunch of helpers and it comes with observable object, which is a basic class for objects
implementing that.
I know.
What if I notify a property change interface?
So it comes with a number of built in facilities for my VM including give our really commands and I
think that it's going to go well.
I don't think it really will cut down the amount of code we have to write, so let us take it for a
spin.
So our first change here will be that we don't need to inherit the I notified property changed.
Instead we will inherit from our new base class called Observable Object.
So that is now telling our application that this whole object, anything here is observable.
And then by extension this is the base view model.
So every other value model that will inherit this will automatically also inherit our observable object.
Notice that you had to add a new using state and here.
Right, just remove anything that's unnecessary.
So that is what we now have for our observable object.
And then what this also does is it generates code that allows us to.
No longer need to put in all of these properties so I can remove these properties, I can remove this
property change, I can even remove this event.
If you actually look at it, it's green now because it's seeing that it's hiding the inherited member,
right?
So any time you're inheriting from a class and then you have the same property or the same method on
the child class or the derived class, you will get a warning that you're hiding the best class.
So that means all of this can go because it's now implied through our observable object.
I can also remove all of this code that was very verbose.
I'm sorry I made you write all of that, but we can actually remove it, right?
And I'm going to clean up the field names.
And the reason I'm cleaning up the field names is that we now have a new annotation that we can place
above the property called observable property.
What this does is it generates a property to match our field.
So yes, we have fields, we have properties already.
Explain that.
But I had put in the properties because that's what you really interact with through an application,
because that's what's public.
But through observable property, we will actually have public implementations.
Our representations of these fields now to verify or validate all of that, we can actually go to our
dependencies.
We can expand and look at there we go.
Went unfunded.
It's the spirit of the treasure hunt.
So if we look at dependencies, we look in the dot net six android and then we look we will see that
we have community toolkit and VM source generators and then we have the generators for the observable
property generator.
Right?
So if we double click that, we will see that we actually have a class called the Base View model and
then we have the property generated for us in very much similar style to what we had implemented.
This is also generated.
So I'm not telling you that you have to understand this word for word and that you're going to have
to use it and modify it.
You don't have to modify this because this was generated, right?
So I'm just showing you where that property is coming from and the fact that we actually have base view
model here and we have our own implementation here, they're more going to crash than work together.
So at one to me at this a partial implementation, that way you can have multiple classes with the same
name and then this one is partial and they're really just, you know, extensions of each other anyway.
So that's really all that there is to it.
So, you know, this one, you got updated at the same time to be partial.
So we have one more property that we're going to implement and that one is called is busy now is busy
pretty much sorry we have is busy.
We're going to be implementing is not busy or is not loading or whatever the opposite of is busy.
And I think I prefer seeing is loading, right?
I think that reads a bit better.
So let's see is loading and then I'm going to have a property of my own and I'm going to see ball is
not loading or is finished loading whichever one and we're going to use the fancy syntax again and then
this is just going to return the opposite of is loading.
So if this is true, then this should return false and vice versa, right?
Now, obviously, we're going to want to watch if this has changed also.
Instead of making it an observable property, because then you're going to have to work out logistics
on how to change in between these two.
I can actually decorate is loading since that's the determining factor of is not loading anyway and
I can see also notify change for and then I would have to put in the name of the property here and that
could be is not loading but I tend to not like this magic string stuff so I would use or.
Compiles safe name of.
Method, right?
So this just gives the string representation of that property name.
Also, if I change this and refactor through my code, you'll also get that.
So that makes it much easier to maintain in the long run.
And just like that, we have implemented our base view model for our MVC pattern.
So this is just part one because this is just the bits we haven't even looked at creating the view model
for our actual view that would be dealing with our cars as yet.
But the principle will carry on.
So when we come back, we'll look at implementing our car view model, which will just extend our base
view model work.