>> Welcome back to another.Net MAUI Beginner Series video.
I'm James Montemagno,
a product manager on
the Developer Community Team here at Microsoft.
Today, what we're going to do is
continue our journey building native,
cross-platform desktop and mobile apps with.Net MAUI.
Now previously we started to build our user interface with XAML,
and XML based markup language.
Now we're going to do is we're going to
extend that user interface and make it
responsive and reactive using MVVM or Model View View Model.
This architecture pattern is very popular when you're developing
applications with XAML because it enables a data binding,
a way for your user interface to
respond to your code behind and vice versa.
It's a way of managing your control and flow of data.
Your view just knows how to display data.
There's a button, there's a label, there's an entry.
Your view model, you can think of it as
code behind but completely decoupled,
and what it is representing is what to display.
It may have a list of objects or strings and may know what to
do when a button is clicked
and it may know what to display in a label,
and the binding system inside
of.Net MAUI is what brings it all together,
enabling your UI to
automatically update your code behind and vice versa.
It handles not only properties back and forth,
but also events like those button clicks or swipe to deletes.
What we're going to do now is head
over to my machine and we're going to update
that application and integrate MVVM directly into
this application so we can be more productive
and abstract our code in a very nice, testable way.
Let's head over there now.
So far we've created
our user interface for our my task application.
Here it's running on both Windows and on Android.
Now so far we're able to see the items and that's just mock data.
We have no way of entering or deleting the task yet.
Let's go ahead and implement this and we're
going to implement this with MVVM.
Let's go ahead and open up the source code.
The first thing that we can see that we're
doing is that we don't actually have
any data bindings to the entry
or any way of interacting with this button yet either.
Same thing down here with the swipe items,
we would want to probably add
something to say when I tap on the swipe item,
do something. Here's what we're going to do.
We're going to come in and we're going to create
a new folder by saying add, new folder.
I'm going to call this View Model
and then I'm going to go ahead and add another class.
This one I'm going to call it Main View Model.
Now I like to create
my view models very similarly named to my pages,
so main view model, main page.
Now this is going to be some default code here,
so we're just going to delete all of our using,
we don't need those and we're going to make this a public class.
Now, there's some traditional ways of
implementing MVVM into our application,
which is by implementing I Notify Property Changed.
Now INotify Property Changed gives us this system component model.
When we implement this here,
we can see that we get an event of property changed.
Now this is an event that.Net MAUI
will subscribe to automatically,
which means that we can notify.Net MAUI
when we wanted to update the user interface.
We will probably create a little method for ourselves
called on property changed passing a string,
which would be the actual variable name here.
Then what we could do is simply come in as a property
changed event and we're going to go ahead and invoke it.
We can pass it this as the sender and then give
it a new property change args of name.
Now, if this looks a little bit scary, well, don't worry.
I will walk through exactly what it's doing in an example here.
Let's say we had a string of text and that's what we wanted
to data bind our entry to;
we're entering text here.
What we could do is create a public string of text.
It's really important that it's public.
That is how the data binding happens.
In here we'll say "Get" and we'll return text.
There we go. And now when we do set,
we can also just set the value.
But the other thing that we would want to do over
here is not only set the value,
but also come in and say "On
property changed" and give it the name of text.
There we go. This means if we set the tax property,
it will set the code behind
text value and then raise this property change notification,
which means that the entry will
automatically be updated and vice versa.
The entry is automatically two way data bound,
which means if we enter text here will
automatically set the value right here in our code behind.
Now this does seem like a lot of code,
so what's amazing is that there are
amazing libraries from the community
and from Microsoft to help simplify this,
so what we're going to do now is right click on the project,
we're going to say "Manage NuGet
packages" and we're going to go ahead and
search for the communitytoolkit.mvvm.
Specifically, we want version 8.0.
Now it may be in preview when you're
watching this or it may be in for release.
If you don't see 8.0,
just check that include pre-release.
Now here, we're just going to go ahead and install.
What I love about the.Net Community
Toolkit is that this works with any.Net application
and it gives us source generators to generate awesome code for us.
Here's what we're going to do.
We're going to delete all this code
that we just wrote besides string.text.
Now what we're going to do is we're going to make
this a partial class and we're going to go ahead and
inherent from observable object
and bring in the Community Toolkit MVVM Component Model.
Now what this does is it automatically gives us a bunch of
those implementations so set
property on property change it implements,
INotify Property Changed for us automatically.
What's also really cool is that it
implements a bunch of source generators,
so here I can say "Observable property".
When I do that, what's great about
this private string is that
Observable property will generate source code for us.
In fact, it's telling us right here,
as I hover over what it's going to do,
I can go into my dependencies and into any of
these analyzers and I can
actually see the source generators in action.
Here's the observable property,
and specifically here,
is that text property.
Now this is generated code.
It's not the prettiest code but it's highly optimized.
Here we can see, our text and it'll
automatically call the property change
for us, which is really cool.
It does a bunch of data caching as well.
It's a super B optimized.
Cool, now we just have one line of code which is a lot prettier.
Now what this means is that we have
our observable property up and running.
Now if I come back over into my XAML,
I can now set the text property here binding to text.
Now we can note here that this is something that there's
no binding context for text,
so we need to also clean that up too.
What I'm going to do is I'm going to add a new namespace.
Just like we were using a namespace in code,
you can have a namespace in XAML.
Here I can just type in "View model" and it'll find
the namespace for us automatically in the IntelliSense.
What I'm then going to do is do
something called X colon data type.
What this will do is it will automatically associate
this content page with the view model and
we saw the little squiggles now go away, which is pretty great.
Now the other thing that we need to do inside of
our view model is create an interaction.
Basically what we want to do is we want to be
able to tap this button and call a method.
What we're now going to
do is we're going to create something called a command.
Now, commands are actually built into.Net MAUI,
and you can use one there,
but you can also use a command
that is built into the MVVM Toolkit for.Net.
What we're going to do is we're just going to go ahead and create
a method called Add, there we go.
What we want to do here is we want to add
our item and then we're going to
set the text property to string.empty.
So we just clear it out.
Now all we need to do is add another attribute called
ICommand to the top of it,
and ICommand is going to live inside of
the Community Toolkit MVVM input.
Just like we saw earlier,
if I pull over my source generators there's
ICommand and we can see that
this generated a bunch of code for us as well.
At the end of the day,
this is going to give us an eye relay command
and it's going to create a new command for us,
and what it's going to do is call the add event automatically.
This is really nice because if this was asynchronous,
it would automatically handle that for us back and forth,
and it's just really nice, tight code.
The other thing we need to do is create another property here.
This is going to be an Observable Collection
of type strain and we're going to call it Items.
Now, let's go ahead and bring that
in the system collections object model.
Again, we're also going to call this an Observable Property.
Perfect. Now, the final thing
I'm going to do is I'm going to create a new one here.
I'm going to say New Main View Model here,
and I'm going to say items.
>> [MUSIC]
>> Equals new. Perfect. Now that
we have that newed up and we can data bind to it,
what we'll be able to do is add that item.
I'm going to say Items.Add
and I'm going to set the text property here.
Perfect. Now, I might want to also do something
like say if string.IsNullOrWhitespace(text).
Let's go ahead and return. There we go.
Also, just make sure we always use the capital text there,
just to be sure. There we go.
We add it and then we empty it
out and that'll be added in to our list.
Now if we go back into our main page
we want to get rid of this item source.
We're going to go ahead and delete that here.
What we can do now is some data binding.
I'm going to say item source and reset
that equal to a binding to items.
Notice the IntelliSense automatically picks everything up for me.
Now I need to do one more thing,
just like we actually set a data type right
here for the view model we also need to set it
onto our data template because
this data template isn't bound to this main view model,
it's bound to a string.
That is what is inside of here.
I'm going to say x: DataType.
I'm going to say x: Type, x: String.
Well, that's going to do is associate
the data template to be a string.
Now here, most likely we would have
some model like to do item inside.
Now the last thing I need to do here before it is ready to go is
I actually need to come in and I need to say Command.
I need to set what the button is bound to.
I'm going to give it a binding to the AddCommand.
Now, this isn't a clicked event, but it is a command,
which means that when it is clicked or interacted with,
it'll call the AddCommand that will execute Add.
Notice that we're binding to the command.
That is the one that was generated
right here for us automatically.
We can see it's called AddCommand,
whereas the method it's going to be calling is Add.
The last thing we need to do is actually
create the binding context for this page.
I could come in and say binding context,
which all associated with this page to a new main view model.
That's one option that we can do here.
If we bring this in that automatically created in our code behind.
But we can actually use the built in
dependency injection system to cascade these down.
That's great when we add
additional dependencies into the main view model,
which we'll see in the future.
I'm just going to say vm and I'm going to pass in the vm.
Now, the last thing we need to do is to register
this system with the dependency service.
I'm going to go into the Maui program before we build it
up I'm going to say builder.services.AddSingleton,
and there's two different types
of things that you can add into a service.
A singleton, which means it's like
a global static it creates at once,
or a transient which will create it every single time.
We'll use that in the future.
We're going to go ahead and add a singleton here and we're
going to add a main page first.
We're going to register the page.
We're also going to add another singleton here.
Now we're going to call it main view model.
Now, when we do this,
these will now be automatically
registered with the dependency service,
which means that when I create this up and
if I put a breakpoint on to the main page view model,
we'll see that automatically be created for us.
This is really cool and one of
my favorite features I've done in Maui in show.
There it is. It's automatically created for
us and we can see that we have zero items here.
Let's go ahead and continue on.
Let's open up our application.
Now what I'm able to do is say bananas and hit "Add".
Now our bananas are there. Well, amazing.
I can also add a breakpoint here so if I hit "Add",
we can see that that ad is being called and boom, just like that.
The view comes in to
the text and it says that it's empty. There we go.
I come in and say Apple's hit "Add" and sure enough,
now we have Apple's right here.
You can see it in full glory.
Now, the last thing we wanted to do is
actually add that swipe to delete.
What we're going to do now is we're going to go
ahead and we are going to come in,
stop debugging one more time,
because we're going to add a little bit of code over here.
Now what I'm going to do is I'm going to say I
Command and I'm going to say void Delete.
I'm going to pass it in a string of s. Here,
what I'm going to do is I'm going to say if Items.Contains(s).
Then let's go ahead and remove it, so Items.Remove(s).
There we go. That's all we're really going to do.
See if it contains it and then remove it.
That should remove it automatically from our list.
You notice that when I added it,
it also automatically added it to the user interface.
That is because with the observable collection,
it automatically will trigger
different notifications when things are added or removed,
so that's pretty great. There we go.
Now we have our command. Now all we need to do is go into
our main page and specifically add a command to the swipe item.
Here's what we're going to do. We're going
to come in and say Command.
Now, remember, though, that we're currently bound to this string,
so it doesn't actually know anything about the view model.
We need to give it something called an ancestry binding,
which basically means relative binding.
It says, Hey, don't use this data type or this binding.
Use the one above it.
Here's what we're going to do, is we're going to say binding
source equals and it's going to be a relative source.
Here what we're going to do is give it an ancestry type to say,
go up the stack and find something for me.
We're going to say x:type in viewmodel MainViewModel.
That does seem a little bit complex,
but bear with me here,
because the last thing we need to do is
a path and then we're going to say,
please find the delete command.
If we walk through this, it's going to say,
don't use the source,
use a relative source.
It's an ancestor of type view model so walk up,
look for view model and specifically called this command.
Now we do need to pass it one more thing, though.
We do need to pass it a command parameter.
In that case, we are going to set it to bind just like this.
This is going to pass the string to
the command and delete it automatically.
Let's go ahead and debug this now
and add a break point into our delete.
What we'll see is that will have generated
a command that automatically takes in a parameter.
That's pretty cool. Here's our application.
I'm going to say Apples "Add",
we had a break point.
I'll say Bananas "Add" continue on.
Now we get our swipe. I'm going to hit "Delete" sure
enough what's pass in here is our apples automatically.
We're now going to remove them and
the animations are all completely built in.
We've now gone from start to finish using
MVVM and data binding to create a full application.
Well, there's a lot more that we can do.
There you have it. We've just integrated
an MVVM architecture pattern with
data binding into our.Net MAUI application.
Now, next up is something very common that you're going to
do in any of your applications, which is navigation.
Navigating from page A to page B and back and forth.
Stay tuned to the.Net MAUI Beginner Series.
>> [MUSIC].