How to Switch Themes in a WPF App at Runtime

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we take a look at how to change the theme of a WPF application at runtime you may want to customize the look and feel of your application or provide different themes for your users to choose from in this video I will show you step by step on how to change the theme of a WPF application dynamically at runtime so without further Ado let's get to the coding all right so here in Visual Studio I'll be demonstrating how to implement theme changing at runtime for a WPF application so what I have here in the main window.zamo file is a simple UI and it consists of a grid within this grid is a smaller grid that contains three text blocks so just as seen here in the designer I have a grid here and a smaller grid with three text blocks here so this is simply a card control that displays basic information so I'll be using this control to demonstrate theme changing now being able to change a theme is simply being able to change the style and feel Over Control so for this tutorial I'll be simply changing the colors of these controls now to do that I'm going to demonstrate by showing you what happens by setting the background color of this grid to a dark shade of blue all right so here I just set the background of the grid deduction of blue and instantly we can see that we have a dark grid which kind of simulates a dark theme so what I'll be achieving here is I'll be simply changing the properties of these UI controls at runtime now instead of me defining a solid color here by simply specifying a color code I can do that by defining resources so what I will do is I'm going to add a solid color brush to this Windows resources section so I'll say window resources then I'll add a solid color brush so for the color property I'll set it to the same dark shade of blue here then I'm also going to specify a key now the key is important because for us to use this resource we need to reference it so in this case I'm going to set it to back drop and to reference it we need to use a key so I'll be using this key to reference that resource so what I'll do here is I'll get rid of this color code here and what I'm going to do is I'm now going to Define a resource for this background so for me to do that I'll simply specify a dynamic resource now there are two types of resources that we can specify so in this case we can either specify a static resource or a dynamic resource but in this case since we want to be able to change the theme at runtime we need to use a dynamic resource so a dynamic resource ensures that the reference to the resource is dynamic so it can change and the dynamic resource will enable runtime changes so for this background I'm going to set it to a dynamic resource I'll say dynamic and in this case I'm going to set it to the back drop which is the key that I defined here so what I'll do is I'll copy this solid color brush and I'll pass twice to create two more color brushes so I'll change this key to text so here I'm going to Define solid color brush to apply to the text and I'll change one to card which I'm going to apply to the smaller grid here so for the text I'm going to set it to a light shade of gray and for the card I'm simply going to set it to a lighter shade of blue all right so I have three resources defined here so for this smaller grid I'm going to set the background by also defining a dynamic resource to say dynamic then I'll set it to card and there we have it we can see for the text I'll set the foreground set it to a dynamic resource and in this case I'm going to use the text solid color brush here so for the text I'll just simply copy this property and paste it on the other text blocks and there we have it so you can see the card control is now applying the Dark theme so by simply defining these resources here and referencing them using the dynamic resource attribute now what I'll be achieving at runtime is I'll be simply switching out these Resources with resources that have lighter colors now for me to do that or the best way to do that is by using a resource dictionary so what I'll do is I'll go to the solutions Explorer and here in my project I'm simply going to add a folder and I'll name this for the themes and within the folder I'm going to add a resource dictionary and I'll give it a name doc so a resource dictionary is a way of organizing resources in this case I'll be organizing these solid color brushes using the resource dictionary so I'll cut these colors then here in the resource dictionary I'll simply paste them so this resource dictionary is for our Dark theme so these solid color brushes have got keys that are defined here now if we go back to the main window.xaml we can see that we cannot resolve the references to these resources here so to do that we need to import a resource dictionary so I'll do that by simply specifying resource dictionary and setting the source property to the folder which is themes then specifying the resource dictionary which is dark dot Samo and I'll close it with the tag so change that okay and we now have the resources resolved and we can now see the theme has been applied so we are simply getting these resources from this dictionary that we applied here so to achieve theme changing at runtime I'll be simply switching out the resource dictionaries so to do that I'll have to create another resource dictionary so right here in the solutions Explorer in the themes folder I'll add a new resource dictionary and this time I'll set it to light all right so what I'll do is I'll go back to the dock resource dictionary and copy and right here in the light resource dictionary I just passed now one thing that I'm going to do here is I'll just simply change the color I'm not going to change the key or just simply change the color the reason for that is because we don't have to touch this keys because these UI controls here are still referencing those resources using the same keys so the only thing we need to change is the column so here I'm going to Define new colors so for the backdrop I'll simply set it to a light shade of gray for the text I'll simply do the same so I'll change that okay and for the card also simply change that to White okay so here if we go back to the main window here if I change this resource dictionary by changing the source let me change it to light we can now see we have a different theme being applied here and the reason for that is because we are now referencing a new set of solid color brushes here Okay so for the text let me change that to a different shade all right so for the text I'm going to do this color instead all right okay so more contrast there so I can change this to dark and we now have a dark theme if I change it to light we have a light theme okay now what I'll be doing is I'll be changing this at run time so I'll be simply changing the resource dictionary of the application from light to dark and these UI controls since we set them to Dynamic resources they'll simply update now we need to understand how WPF resolves these resources or how it finds them so for example on the grid here if we set a dynamic resource and we set it to backdrop the first place WPF is going to look for is on this very grid so this grid contains a resources collection if it doesn't find this property on this grid it will go to the parent and we understand that the parent is the window if it finds it on the window then it will use that but for this video I won't be setting these properties on the window I'll be setting them on the application that simply means how simply set them right here in the app dot xamo file right here okay so to do that I'm going to create a class that's going to help me switch the themes at runtime so I'll simply go to the file explorer here enter the project I'm going to add a new class and I'll name this class app Theme all right so here in our app Theme I'm going to create a public method and it'll be a static method and I'll simply give it a name change theme so this method is going to take in an argument of the type URI so it will return a void so it'll take in an argument of the type URI so say URI so the URI will simply point to the theme so just give it a name theme URI okay so what I'll do is I'll create a new resource dictionary so I'll say resource dictionary then I'll say give it a name I'll just say theme I'll set it to a new resource dictionary so for this new resource dictionary I'm going to set the source of the new dictionary based on the URI that we passed through this method so simply say source I'll set that to the theme URI then what I'm going to do is I'll say application then I'll get the current application which is the instance of the application then I'll access the resources then within the resources I'm going to clear all the resources that are there so if I have a resource dictionary defined in that resources section I'll simply clear that so once I've cleared that resource dictionary then I'll set it to a new resource dictionary so I'll say app and I'll get the current instance then resources then within this resources section I would like to access another collection and this is the maged dictionary collection so merge dictionary collection simply allows us to add a number of resource dictionaries or a collection of resource dictionaries so in this case I'm only going to add one so here I'm going to add a resource dictionary to that collection so I'm going to add the theme Here so this resource dictionary will be based on whatever URI we specify here as the argument and when we say app Current resources we are simply referring to this file here so app so we are simply adding the resource dictionaries here now if we add a resource dictionary here the main window here is still able to resolve that so I can demonstrate that by getting rid of this section and this section all right so right now we can see that we don't have anything applied because it can't resolve where these resources are so if we go to the app.zamo file here and right here I can specify to say application then resources and I can add a resource dictionary all right if I go back to the main window.zamo we now have a theme applied so we are simply doing this programmingly so instead of pasting it here we are simply doing that using this class that we created so this is our helper class it simply has a method called change theme creates a resource dictionary then we specify the URI we simply specify where to find this resource dictionary we clear the current resources then we add that dictionary there all right so I'll go back to the main window.xam file here now for me to be able to change the the theme I'm going to create a context menu so a context menu is simply the menu that appears when you right click on a control so in this case I'm going to say grid then the context menu of the grid then for this context menu I'll simply add a context menu so say context menu and within this menu I'm going to add two items so I'll say menu item so these menu items are clickable controls on the context menu in this case I'm going to add two of them and I'm going to set their click event handler so here I say click when this item is clicked then I'll create a new event handler now I'll get rid of this name I'm going to name it light theme click so say light then I'll say theme click so I'll name that to this so I'll do the same for this one so I'll say click event handler create a new Handler then I'll just change the name to dark theme click change that name all right so we can go to the main window here and we have these event handlers now because we changed the name we also need to change the names here so say light theme click all right so when the buttons are clicked which are on the context menu an event handler is going to be raised so we now need to do something we now need to change the theme okay so to do that I'll simply go to the main window here so I'm now going to use the helper class we created which is app Theme and I'm going to call the method which is the change theme method now remember that this change the method takes in a URI which simply points to a resource dictionary file so to do that I'm going to specify a new URI so this URI is going to have the path in form of a string so in this case we understand that it's the themes folder and we now have a theme called light so in this URI Constructor we need to specify another property which is the type of URI so in this case we're going to say URI kind and this is an NM so we need to set it to a relative so relative simply means that for you to find this resource you need to start from where the application is being executed so we need to set that so what I'll do is I'll copy this and I'll do the same for the Dark theme and for the Dark theme I'll simply change this to dark so to quickly have a recap what we are simply doing is we are changing the resource dictionary by specifying the URI for the two resource dictionaries and we created a class which is app Theme and it contains a method called change theme which simply just helps us to change the theme of the application by clearing the current themes and replacing them with the new theme that we specify all right so with that being said now let's go ahead and try the application all right so the application is up and running and you're going to notice one thing we do not have the theme defined here and the reason for that is because we haven't set the default theme so to Simply do that I'll close this and here in the after xaml file I can specify the default theme to use now we understand that the application is going to look for the resources from the parent until it reaches the application Level here so here I'll just simply Define the application resources and I'll simply specify the default dictionary that I would like to use and I'll set the source to the themes folder then the default theme will be the light theme all right so let's go ahead and test the application all right so the application is up and running and we can see we have the light theme as the default theme so if I right click here where the grid is we should see a context menu now here you notice that we do not have some text written the reason for that is because we forgot something so I'll go ahead and close this and in the main window.summer file here so when creating these menu items I forgot to specify the header so I'll simply do that by saying header and I'll simply specify a text or say light theme so copy this that are specified for the other menu item for this one I'll set it to Dark theme all right so we can go ahead and try the application all right so it's up and running and we have the white default theme so if I right click here I now see light and dark so if I click dark the theme changes if I click light it goes back to light so we are simply switching the results dictionaries okay light dark okay so what I'll do is I'll try to copy and paste this card control so close this so here in the main window I'm going to change this Ctrl to a wrap panel so simply say wrap panel or do the same for context menu so wrap panel then context menu okay so we have our control here in the corner so I'll give it a margin just to ensure that there's some space so it's a margin then I'll set it to 8 pixels okay so what I'll do is I'll copy and paste this card control so copy all right now we have multiple cards displayed here so I'll go ahead and run the application all right so the application is up and running simply expand that I'll change it to a dark theme then light and back to a dark theme all right so the source code for this video will be placed in the video description thanks for watching remember to give this video a thumbs up and subscribe to this channel if you find this content useful happy coding I'll see you in the next one
Info
Channel: Tactic Devs
Views: 10,198
Rating: undefined out of 5
Keywords: wpf ui design, wpf animation, c# tutorial for beginners, programming, how to animate in WPF, themes in WPF, c# pro, c# programming, how to programme a soft, ui design, ui design course
Id: AHbQs99o4IA
Channel Id: undefined
Length: 24min 10sec (1450 seconds)
Published: Tue Feb 28 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.