This .NET MAUI Crash Course
almost coming to a close, but not before we've learned how to implement styling
theming, and more specifically, how to implement light theme and dark
theme support in our Monkey Finder application. Just a quick check. This video is part
of a full course which makes the most sense if you follow it from front
to back. So if you didn't come here through the rest of the course,
then make sure to check out the playlist that's popping up on your screen right
now. For this video. We're going to learn all about theming and styling.
Actually, I'm not going to spend too much time going over the theory here,
at least not on camera, because I think it will work the best
if I just walk you and talk you through the code that is in our
Monkey Finder application. So let's just switch over to Visual Studio and see
what it's all about. Now you can follow along with this part of the course.
Make sure that you clone the repository, the link you can find down below in
the video description, clone it to your local disk. And here we have Part 6 -
AppThemes. That is the start for our episode that
we are watching right now of this course
there is a solution and whenever you open that in Visual Studio you will get the
Monkey Finder solution. The Monkey Finder application project that we left off
for the previous video. But I actually started a File, New
project because I wanted to show you another thing. If
you do File, New .NET MAUI application, you will get a template like this with...
Go to the Solution Explorer, just the App, an AppShell, MainPage,
all kinds of the basic ingredients, but under the Resources there's also
the Styles.xaml. So I mentioned before, like if you are
going to start working with cross-platform
development, then there is enough to learn already. So what we are trying
to do is make that threshold as low as possible for you to start. And the
Styles.xaml is also there because of that basically. Because
we've styled everything in your application so that you can... A) you do not have to
go out to the documentation and see how to do all the styling
things. You already have an example here and B) if you are happy with the
styling because we're doing a lot of the stuff that you probably also want
to do, you can just tweak the colors right here and you will just style our
application like that if you're just getting started.
So it's just good to know that this is here and I'm net going to go over
to the Monkey Finder and explain everything there. So let's just close
this one basically and give you a quick tour. I already had the code
running here. I got the monkeys we implemented like this
pull-to-refresh in the previous video right. So that it gets the new
monkeys. Whenever we get in here, then you can see the details,
all the things we are pretty far with our application here. So for
Android and for Windows and for iOS, we have Dark
Theme or Dark Mode, as it's called in some operating systems. So
if I slide down here and slide this menu out, then you can see
the Dark Theme toggle here. And whenever I push that, then
Android is going to switch to dark mode. So it all looks dark and
handsome now. But our application is still burning
my eyes. It's still light mode, right? So we
need to fix that. So let me put this back actually to the light
mode right here so that we can see and be amazed at the results and be
shocked that it actually worked. So let's go over to our code. This is
our application right now. Let's go over to our code. I'm actually going
to stop running it here for a little bit. And what we're going to do is go
to our Solution Explorer. And here we have in our App.xaml.
So I think this application might have been
started when the Styles.xaml was not in the template
yet. So that's why it's here. But this also kind of like indicates
that you could put it in different places in your application. So
we have this ResourceDictionary, and in this case, it lives inside of
your Application and the Application. Resources. But you could also go to
your MainPage.xaml and we could do here ContentPage,
whoops I need to add the angle bracket to it.
ContentPage. Resources. We have that here as well.
I could do a ResourceDictionary here as well. And it would be specific
to this page. So it kind of like cascades throughout different
layers of your application. But for here, for the app one, it will
be available inside of your whole application. Now, you
can see Visual Studio helps us with the nice colors here that it's kind of like
previews for us. So that's nice. And inside of a ResourceDictionary,
you can have these colors. I think you can also have a Thickness that you can
use for like border thickness and that kind of stuff. But colors
will probably be the majority. So you can have these colors and those
just specify with the key this color. You can also do like the named
colors. You can see that here. Just black also works. And you can
give it a key or a name which you can reference it by later.
So, for instance, if we look here, the LightBackground, you can see that
this LightBackground is referenced here by this style. So before I go
into the styles, let's look at what's
happening here with this StaticResource LightBackground. So you have static
resources, you have dynamic resources, and you have the ApThemeBinding,
which is technically another thing altogether, but we'll get to
that. So the StaticResource, you just set that and this property, the
Background property will stop listening for any changes. This you should use
whenever you know that your theme is not going to change.
This is just a theme that you're doing in design time, and that's going to be
it. If you want to have some theming engine inside of
your application where you're going to switch themes by the user maybe, or by
whatever, then you want to set this to a DynamicResource.
And a dynamic resource will keep listening for
changes to this LightBackground key. So whenever
something changes there, whenever you change the value for the LightBackground or
you load a new ResourceDictionary, that's totally things that you can do.
I'm not going to show you. Let me know in the comments if that's
something that you want to see, but then it will update at runtime and it will
have that light background. Now for light theme and dark theme, we have
easier things to do that so you don't need to manually load
whole new ResourceDictionaries and whatnot. But we'll get to that in
a second. So you have the static and dynamic resources you've learned
about that. Now let's look into these styles right here. Let's scroll up a
little bit. So we have this Style, and with this style you can give it a
TargetType. So this Style goes to the TargetType Page. So this
Style will be applied to a Page. And there's also this
interesting attribute right here Apply ToDerivedTypes. So by default this
is set to false. So it will only be applied to a Page. And a
Page is kind of like the highest Page where all the
other pages are inheriting from. So it's very unlikely
that you're using just a Page. So you want to apply it to
derived types so that it also works for a ContentPage, a
TabbedPage, a NavigationPage. That is what this attribute does. So
whenever you want to style your Entry and you have kind of like an
inheritance of that Entry, then make sure to set it to true so that it will
trickle down through all those elements and it will be applied to that as
well. Now inside of this Style, we have the Setter, and in this case
we are setting the property. So you're going to have to specify the property
here, BackgroundColor and the value. Now I just showed you this with the
StaticResource. You can of course do this also with like, you
can put White in here directly if that's what you want, as long as you
have a value that is applicable to the type of the property here. But
of course, what makes this real powerful is if you reference this to the key
and you just have to change this one color here and it will all fall
into place and you will have that color suddenly everywhere. So again,
here the Property. It sees that we have this TargetType
here of Page. So the IntelliSense will help us here with all the
properties that are here for a Page. And of course you can add multiple
setters here. So if we just duplicate this line and we now set I
don't know, some other property here, some random one,
IsVisible, then we have to set the value obviously to
true or something like that. But you can set all the setters all
the properties for the thing that you're trying to style
here. Now if we scroll a little bit down, you can actually see another
nice concept where we have a Style also applied to derived types and a
TargetType of NavigationPage. So this is actually a level deeper
than the Page that we've just seen and we can just override the background
color. So you can make it more specific to other types of pages. You can make
that background color specific to that NavigationPage and actually
add even more properties to it because the
NavigationPage will now have more specific properties to the NavigationPage. So
that's how you can nest all these things. There is another way to
do that which I'm going to show you right now. So let's scroll down a
little bit here again. And here we have this Style with TargetType Label.
So here we're going to do labels and here we suddenly have this
x:Key="BaseLabel". Now whenever you leave out the x:Key
it's going to be an implicit style. So this
is going to be applied to a NavigationPage no matter what, or
a Page no matter what. But if you specify this key it's going
to be an explicit style and then you have to go out to a label and
actually say like hey, you need to have the BaseLabel style,
else it's going to be not applied to any Label. So if we scroll down
here a little bit and we see this happens for the rest of
the styles here as well. So if we take like, I think the x:Key MediumLabel, I think we then go to the DetailsPage.xaml
which I have opened right here and we scroll down, you can see
these labels will have a Style attribute and that will reference to
the StaticResource MediumLabel or MicroLabel. So if we don't apply this
style then it will not work. It will not be
applied unless we leave out the x:Key and then it's
suddenly applied to all of our labels. So you can definitely play with that.
How to configure with that. But what this also opens up the
scenario where you say the x:Key, you can say with the next style with
an x:Key you can say BasedOn because now because it's an
explicit style right so we need to say BasedOn=
"{StaticResource BaseLabel}". So now it will get these properties,
the font family, the text color, it will have all those properties. And
we can add to that with our own font size. And that's the only thing
that's kind of different between the different styles that you can see.
Right. And I think that is kind of like everything that you need to know about
the styles right now. Implicit styles, explicit styles,
dynamic resources, static resources. So now it's time
actually, I need to scroll back up for this. I skipped
over that for the AppThemeBinding, and that's an important one for the
Light Theme and the Dark Theme, as you can already see here. So this
kind of looks familiar, right? If we do the data binding, we
would not do AppTheme Binding. We would just do regular
Binding. And what we've already seen also is like the StringFormat, right?
So the Binding is just another C# object. It's just a
little extension here for our XAML stuff. And just like the StringFormat, we
can also specify the Light and the Dark here. And that's what's
happening. So we have this AppTheme Binding, which inherits from Binding,
which is very specific to loading these styles. And we have a property for
Light and for Dark. And I think we even have a fallback value, which is
kind of like the default. And here we can just specify, hey, whenever the
Light Theme is on for the operating system that we're running on, we want to have
the StaticResource of LightBackground. And whenever we have the Dark Theme,
which is the property here, we want to have the StaticResource of
DarkBackground, so it will automatically apply that. It can
be static resources. It doesn't even matter. It will just load that
automatically for you. So that is what the AppThemeBinding
does. And whenever you want to support Light Theme and Dark Theme, that is
exactly the thing that you want to use. Now, everything that you're seeing
here with the setters, you can apply to this background color directly as
well. We will see that in a little bit. So you can just put whatever is in the
value here also on the Navigation Page.BackgroundColor. Basically, you
can put that value in there as well. So with that, I think
it's time to actually start implementing that Light Theme and Dark
Theme support. Now, to do that, I'm going to add a couple of extra
colors here. So I'm going to copy them from the repository that
we've just seen and paste them in here. Now, this is just, it can be
kind of confusing. Of course, the keys can be whatever you want, but
I always find this a little bit confusing, like LabelTextDark, and
then it's going to be white. But this is going to be the value for
whenever it's set to dark, right? So then it has to be white,
else you can't read it. Does that make sense? But again, this can be
anything you want to give it a descriptive name that will make sense to you. So
now we can make the updates to the background color. And that's
actually pretty nice because we have kind of like these base styles right here. And
we can just change this value right here from the static
resource into a AppThemeBinding. So let's take
this page value right here. And I'm going to paste in
the AppThemeBinding. And now you can see it does for the light variant,
it does the Static Resource LightBackground, which we
already had here, and the DarkBackground. So it's just
going to be a shade of white and a black background. And this will
automatically now work for all the pages because we're doing Target
Type Page, and it applies to derived types. So it does it for all the pages.
It trickles down. And that is what makes this styling engine so very
powerful. So that's cool. We got that one. What's next? So
we're going to go to our BaseLabel, again, this is our
BaseLabel, so this will help for everything we are going
to do this text color, boom, paste that in here. AppTheme
Binding, StaticResourceLabel Text and LabelTextDark. The
background on our Refresh View. So we need to do this because
the RefreshView, although it seems kind of like
invisible, it might still seem a white background whenever we
scroll it down, and a little bit of white will
come after that. So better just set the background color on that, scroll
all the way down. TargetType Refresh View. I'm going to add a new key for
that. Nothing new here, just a setter property for the background.
And we're going to set this StaticResource LightBackground, Dark
Background so that it's in line with the rest that we've seen for the ButtonOutline.
So I already mentioned it in a couple of videos like, hey, we
already styled a little bit for this. The ButtonOutline is one of
those, which is like the buttons with the outline that you
see at the bottom of the main screen. And we can do that as
well with the background because else it will have a
light background, as you can see here, which is not what we want, of course.
So we are going to set the background for that and the CardView,
which is the cars that we see in the CollectionView for
all the monkeys in our main list. So we have a oh, I don't think
we have the background. Oh, here's the background color Light
Background. So let's paste in the App ThemeBinding here as well. And I think
we've done most of the things here. But in the repository
right now is mentioned that, this was created while .NET MAUI was
in development, so I'm not entirely sure if this is still needed.
A nice exercise for you at home, but it does show nicely
how to actually specify the same AppThemeBinding in an
attribute directly on any object. So let's go over to the MainPage.xaml
and here we are specifying also directly on the Grid
this BackgroundColor as well. So you can
see here this BackgroundColor, you can just set it to background is
AppThemeBinding and boom, that should work as well. Same thing for the
DetailsPage, on our ScrollView. So let's go up here, ScrollView.
We need to do this. So like I said, I'm not sure if this is entirely
needed, but just to make sure that my demo works and also to show you how
to do this directly on an element if that is something that you
would want. Now if we run this application, we're going to
run this on Android. But the same thing works again for
Windows, for macOS, for iOS. And we can see now whenever
we flip that Dark Theme toggle, then our whole
application should suddenly look nicely and will be for our Dark Theme
fans. Okay, our application is coming up
here... All right. Our application looks as it
did before. Let's get those monkeys. Yes, this still looks
good. Okay. But now whenever we are going to
toggle that Dark Theme thing. Here we go. Then our OS
changes and you can already see in the background our application
changes as well. Everything looks nice and dark. We have the white text
here. We can go to the details, you can also
see the white text. So now our application is ready for Dark
Theme support. And also our Dark Theme fans are happy
with our new Monkey Finder. Basically this
is definitely one of those things that you need to start working with in
order for it to make sense. Just see how it works with the
inheritance. Try out a little thing here and there, tweak
some of the colors of the themes and see how it all behaves and works. But
this is very powerful, very flexible, and if you get the hang
of this, it will be pretty amazing. And I
actually didn't even mention this. But you can also set those
ResourceDictionaries, you can have them on the application
level, you can have them on the page level, but you can also make it
separate files. That's exactly what the Styles.xaml is that I showed you in
the beginning. You can just have that in a separate file, you can link
it inside of your application and you can just use it that way. And then
you can swap out the whole ResourceDictionary while your
application is running. And you can have kind of like a theming inside of
your application if that is something that you want. Now this video has been
the last one. So actually, I'm not going to
congratulate you yet. There is going to be a video after
this one where I'm going to tell you a little bit about some resources
where you can go to make your app really awesome and
amazing because there's a wonderful community out
there that will help you make the best app you can and some
other tips and pointers. Maybe and there is a very special
surprise there, a gift especially for you to prove that you have built
your very first .NET MAUI application. So make sure to check that out and
don't miss it. I'll see you for the next one. Actually, here is the
link to that video right now. This is the playlist and this is the
button that you should definitely click to subscribe to my channel. See you for
the last video.