-
Notifications
You must be signed in to change notification settings - Fork 81
Advanced theming
There are several entry points for getting started with Material themes for your application.
They all rely on the fact that you must add an element to your App.axaml
file in the Application.Resources
section.
-
MaterialTheme
- If you don't plan to change the theme and just want to set the colors you want on startup -
CustomMaterialTheme
- If you would prefer to use custom primary and second colors -
MaterialThemeBase
- If you want to control your theme and load it by yourself
Actually this is a wrapper for MaterialThemeBase
that helps you to set up your theme with BaseTheme
, PrimaryColor
, SecondaryColor
properties.
You can still use the CurrentTheme
property, but this is not the recommended use of this element.
This is an analogue of MaterialTheme
which allows you to setup custom colors for PrimaryColor
and SecondaryColor
.
If you need different colors for light and dark theme, the CustomMaterialTheme supports individual resources for light and dark theme.
<themes:CustomMaterialTheme>
<themes:CustomMaterialTheme.Palettes>
<themes:CustomMaterialThemeResources x:Key="Dark"
PrimaryColor="#4BEB59"
SecondaryColor="#04C9F0" />
<themes:CustomMaterialThemeResources x:Key="Light"
PrimaryColor="#29964A"
SecondaryColor="#0271A4" />
</themes:CustomMaterialTheme.Palettes>
</themes:CustomMaterialTheme>
Entry point of new Material.Avalonia theme and styles system. You can control application theme by setting value of CurrentTheme
property.
NOTE: Setting value for CurrentTheme
property internally convert your new value to struct that implementing interface ITheme
. This is done so that the internal state of the theme object is immutable. Therefore, if you get and use the value of the CurrentTheme
property (or subscribing CurrentThemeChanged
for example), then you will get a structure.
You can create a new empty Theme
object using Theme
ctor or use Theme.Create
helper method to create prefilled theme:
using Avalonia.Media;
using Material.Colors;
using Material.Styles.Themes;
using Material.Styles.Themes.Base;
...
PrimaryColor primary = PrimaryColor.DeepPurple;
Color primaryColor = SwatchHelper.Lookup[(MaterialColor)primary];
SecondaryColor secondary = SecondaryColor.Teal;
Color secondaryColor = SwatchHelper.Lookup[(MaterialColor)secondary];
// For dark theme use Theme.Dark;
IBaseTheme baseTheme = Theme.Light;
ITheme theme = Theme.Create(baseTheme, primaryColor, secondaryColor);
If you want you can use any arbitrary colors:
Color primaryColor = global::Avalonia.Media.Colors.Purple;
Color secondaryColor = global::Avalonia.Media.Colors.Lime;
IBaseTheme baseTheme = Theme.Light;
ITheme theme = Theme.Create(baseTheme, primaryColor, secondaryColor);
For changing main primary/accent colors or base mode use SetBaseTheme
, SetPrimaryColor
and SetSecondaryColor
on any ITheme
instance.
You can use ThemeExtensions.LocateMaterialTheme
extensions method to quickly locating you MaterialTheme (or MaterialThemeBase) instances in your app. Sample usage:
var materialTheme = Application.Current.LocateMaterialTheme<MaterialTheme>();
If you want to setup theme by hands then application is starting (for example to allow user to change and save themes) you can use the following approach:
Open your App.axaml.cs
and in your App
class override OnFrameworkInitializationCompleted
method.
Locate MaterialTheme (or MaterialThemeBase) and do what you want with the theme.
For example, I will create Dark theme with Cyan as primary color and Orange secondary color and set it for my application:
public override void OnFrameworkInitializationCompleted() {
base.OnFrameworkInitializationCompleted();
var primary = PrimaryColor.Cyan;
var primaryColor = SwatchHelper.Lookup[(MaterialColor)primary];
var secondary = SecondaryColor.Orange;
var secondaryColor = SwatchHelper.Lookup[(MaterialColor)secondary];
var theme = Theme.Create(Theme.Dark, primaryColor, secondaryColor);
var themeBootstrap = this.LocateMaterialTheme<MaterialThemeBase>();
themeBootstrap.CurrentTheme = theme;
}
NOTE: If you always set theme from code use MaterialThemeBase
in your Application.Styles. Because MaterialTheme
will create an additional overhead to apply the original styles (written in xaml), which you will override anyway.
Also, you can react to a CurrentTheme
change (for example, to save a new theme in the configuration) via subscribing to CurrentThemeChanged
(or subscribing to CurrentThemeProperty
changing via default Avalonia properties system).
Here is the example of saving and loading theme to a file (not a preferred way to save/load theme, but just an example):
public override void OnFrameworkInitializationCompleted() {
base.OnFrameworkInitializationCompleted();
var themeBootstrap = this.LocateMaterialTheme<MaterialThemeBase>();
themeBootstrap.CurrentTheme = LoadOrCreateDefaultTheme();
themeBootstrap.CurrentThemeChanged.Subscribe(newTheme => {
var configText = JsonConvert.SerializeObject(newTheme);
File.WriteAllText("themeconfig.json", configText);
});
}
private ITheme LoadOrCreateDefaultTheme() {
try {
var text = File.ReadAllText("themeconfig.json");
return JsonConvert.DeserializeObject<Theme>(text);
}
catch (Exception) {
// In case of any exception or file missing, etc
// Fallback to creating default theme
var primary = PrimaryColor.Cyan;
var primaryColor = SwatchHelper.Lookup[(MaterialColor)primary];
var secondary = SecondaryColor.Orange;
var secondaryColor = SwatchHelper.Lookup[(MaterialColor)secondary];
return Theme.Create(Theme.Dark, primaryColor, secondaryColor);
}
}
You can set the colors you want directly on the ITheme object, which you then use to set the value of CurrentTheme
in MaterialThemeBase
.
But often this is an overhead, and there is an easier way to override the desired color.
You can add a new resource to end of Application.Resources
in your App.axaml
like this:
<Application.Styles>
...
<themes:MaterialTheme BaseTheme="Light" PrimaryColor="Purple" SecondaryColor="Lime" />
<Application.Resources>
<SolidColorBrush x:Key="PrimaryHueLightBrush" Color="Red"></SolidColorBrush>
</Application.Resources>
Or you can create and use a new style and put in after MaterialTheme
in Application.Styles
section:
<Application.Styles>
...
<themes:MaterialTheme BaseTheme="Light" PrimaryColor="Purple" SecondaryColor="Lime" />
<Style>
<Style.Resources>
<SolidColorBrush x:Key="PrimaryHueLightBrush" Color="Red"></SolidColorBrush>
</Style.Resources>
</Style>
</Application.Styles>
List of brushes which Material.Avalonia uses located here.
Actually there is no breaking changes in this update. We make many things obsoleted, but it should work fine with the new version. Except:
- If you use anything related to
MaterialDesignColor.*.xaml
files,Swatch
andHue
classes you need to rework your system, cuz these things removed. - If you use
SecondaryAccentBrush
,SecondaryAccentForegroundBrush
,ValidationErrorColor
you need to switch to proper brushed defined at wiki.
If no there is migration tips:
- If you use only
BundledTheme
before (and do not manipulate theme by yourself) then this has backward compability 100%. - If you use
IThemeManager
,ThemeManager
,PaletteHelper
,ResourceDictionaryExtensions.SetTheme
,ResourceDictionaryExtensions.GetTheme
,ResourceDictionaryExtensions.GetThemeManager
, these things should work fine but consider switching toMaterialThemeBase
and proper theme manipulating.
v2.5 and before
The first step is to set the initial theme. There are two recommended ways to accomplish this:
- Use built-in markup extension (
BundledTheme
). These return a newResourceDictionary
instance with all of the brushes setup for you. - Create a new
ITheme
object and useResourceDictionaryExtensions.SetTheme(Application.Current.Resources)
. You can create a newTheme
object using:
using Avalonia.Media;
using Material.Colors;
using Material.Styles.Themes;
using Material.Styles.Themes.Base;
...
PrimaryColor primary = PrimaryColor.DeepPurple;
Color primaryColor = SwatchHelper.Lookup[(MaterialColor)primary];
SecondaryColor secondary = SecondaryColor.Teal;
Color secondaryColor = SwatchHelper.Lookup[(MaterialColor)secondary];
IBaseTheme baseTheme = Theme.Light;
//If you want a dark theme you can use IBaseTheme baseTheme = Theme.Dark;
ITheme theme = Theme.Create(baseTheme, primaryColor, secondaryColor);
If you want you can use any arbitrary colors.
using Avalonia.Media;
using Material.Styles.Themes;
using Material.Styles.Themes.Base;
...
Color primaryColor = global::Avalonia.Media.Colors.Purple;
Color secondaryColor = global::Avalonia.Media.Colors.Lime;
IBaseTheme baseTheme = Theme.Light;
//If you want a dark theme you can use IBaseTheme baseTheme = Theme.Dark;
ITheme theme = Theme.Create(baseTheme, primaryColor, secondaryColor);
Prior to version 2.6.0 the PaletteHelper
class provided methods for modifying the theme. These methods are now obsolete in favor of the new GetTheme
and SetTheme
methods on PaletteHelper
. To change the theme simply get the existing ITheme
, modify this theme object, and then simply set it with PaletteHelper.SetTheme
. Similar to this:
var paletteHelper = new PaletteHelper();
//Retrieve the app's existing theme
ITheme theme = paletteHelper.GetTheme();
//Change the base theme to Dark
theme.SetBaseTheme(BaseThemeMode.Dark.GetBaseTheme());
//or theme.SetBaseTheme(BaseThemeMode.Light.GetBaseTheme());
//Change all of the primary colors to Red
theme.SetPrimaryColor(Colors.Red);
//Change all of the secondary colors to Blue
theme.SetSecondaryColor(Colors.Blue);
//You can also change a single color on the theme, and optionally set the corresponding foreground color
theme.PrimaryMid = new ColorPair(Colors.Brown, Colors.White);
//Change the app's current theme
paletteHelper.SetTheme(theme);
Material.Avalonia Wiki pages is still WIP (work in progress), Pages could not ready for show if they unclickable.
Main section
- Main page
- Getting started
- Screenshots of Demo
- FAQ (frequently asked questions)
- Breaking changes
- Nightly builds
Widgets / Controls
- Buttons
- Inputs
- TextBox
- Switchable
- CheckBox
- RadioButton
- ToggleButton
- ToggleSwitch
- Selectable
- ListBox
- ComboBox
- Pickers
- Feedbacks
- ProgressBar
- Snackbar
- Dialogs
- AlertDialog
- TextFieldDialog
- CustomDialog
- Containers / Layouts
- ColorZone
- Card
- Expander
- DataGrid
Theming
Builders
Assist for widgets
- ButtonAssist
- SelectionControlAssist
- ShadowAssist
- SliderAssist
- TextFieldAssist
- TransitionAssist