Overview
Flowery.Uno uses a palette-based architecture where themes are defined as collections of color resources. This guide covers how to create custom themes, override palette resources, and use lightweight styling patterns.
Palette Architecture
Flowery.Uno’s theming system is built on these principles:
Palette Factory - DaisyPaletteFactory produces per-theme resources
Stable Brush Instances - Brushes are mutated (Color property) when themes change
ThemeResource Bindings - Controls use {ThemeResource} to automatically update
Resource Hierarchy - Application → Page → Control resources
Key Palette Resources
Resource Usage DaisyBase100BrushPage/window background DaisyBase200BrushElevated surfaces (cards, sidebar) DaisyBase300BrushBorders DaisyBaseContentBrushDefault text/icon color DaisyPrimaryBrushPrimary accent color DaisySecondaryBrushSecondary accent DaisyAccentBrushTertiary accent DaisyInfoBrushInfo status color DaisySuccessBrushSuccess status color DaisyWarningBrushWarning status color DaisyErrorBrushError status color
Lightweight Styling (Per-Control Customization)
WinUI/Uno supports lightweight styling - overriding theme resources for individual controls without creating full custom styles.
Override a Single Control’s Colors
Place a ResourceDictionary with ThemeDictionaries inside the control’s Resources:
< Button Content = "Custom Purple Button" >
< Button.Resources >
< ResourceDictionary >
< ResourceDictionary.ThemeDictionaries >
< ResourceDictionary x:Key = "Light" >
< SolidColorBrush x:Key = "ButtonBackground" Color = "Transparent" />
< SolidColorBrush x:Key = "ButtonForeground" Color = "MediumSlateBlue" />
< SolidColorBrush x:Key = "ButtonBorderBrush" Color = "MediumSlateBlue" />
</ ResourceDictionary >
< ResourceDictionary x:Key = "Dark" >
< SolidColorBrush x:Key = "ButtonBackground" Color = "Transparent" />
< SolidColorBrush x:Key = "ButtonForeground" Color = "Coral" />
< SolidColorBrush x:Key = "ButtonBorderBrush" Color = "Coral" />
</ ResourceDictionary >
</ ResourceDictionary.ThemeDictionaries >
</ ResourceDictionary >
</ Button.Resources >
</ Button >
Handle Pointer States
Override state-specific resources using standard suffixes:
State Suffix Example Hover ButtonBackgroundPointerOverPressed ButtonForegroundPressedDisabled ButtonBorderBrushDisabled
< CheckBox Content = "Purple CheckBox" >
< CheckBox.Resources >
< ResourceDictionary >
< ResourceDictionary.ThemeDictionaries >
< ResourceDictionary x:Key = "Light" >
< SolidColorBrush x:Key = "CheckBoxForegroundUnchecked" Color = "Purple" />
< SolidColorBrush x:Key = "CheckBoxForegroundChecked" Color = "Purple" />
< SolidColorBrush x:Key = "CheckBoxCheckGlyphForegroundChecked" Color = "White" />
< SolidColorBrush x:Key = "CheckBoxCheckBackgroundFillChecked" Color = "Purple" />
</ ResourceDictionary >
</ ResourceDictionary.ThemeDictionaries >
</ ResourceDictionary >
</ CheckBox.Resources >
</ CheckBox >
Page-Wide Overrides
Apply lightweight styling to all controls of a type on a page:
< Page.Resources >
< ResourceDictionary >
< ResourceDictionary.ThemeDictionaries >
< ResourceDictionary x:Key = "Light" >
< SolidColorBrush x:Key = "ButtonBackground" Color = "Transparent" />
< SolidColorBrush x:Key = "ButtonForeground" Color = "MediumSlateBlue" />
</ ResourceDictionary >
</ ResourceDictionary.ThemeDictionaries >
</ ResourceDictionary >
</ Page.Resources >
<!-- All buttons on this page get the custom colors -->
< Button Content = "Button 1" />
< Button Content = "Button 2" />
App-Wide Overrides
Place theme overrides in App.xaml to affect all controls globally:
< Application.Resources >
< ResourceDictionary >
< ResourceDictionary.MergedDictionaries >
<!-- Your other resources -->
</ ResourceDictionary.MergedDictionaries >
< ResourceDictionary.ThemeDictionaries >
< ResourceDictionary x:Key = "Light" >
< SolidColorBrush x:Key = "ButtonBackground" Color = "Lavender" />
</ ResourceDictionary >
< ResourceDictionary x:Key = "Dark" >
< SolidColorBrush x:Key = "ButtonBackground" Color = "DarkSlateBlue" />
</ ResourceDictionary >
</ ResourceDictionary.ThemeDictionaries >
</ ResourceDictionary >
</ Application.Resources >
Daisy Control Styling Resources
Flowery.Uno controls support lightweight styling through control-specific resource keys.
Why Daisy-Specific Resources?
Since Daisy controls are code-driven (they build their visual tree programmatically in C#), standard WinUI template-based lightweight styling doesn’t apply. Instead, Daisy controls check for resource overrides using a consistent naming pattern.
Resource Naming Convention
All Daisy styling resources follow this pattern:
Daisy{ControlName}{Part?}{State?}{Property}
Examples:
DaisyButtonBackground – Button background
DaisyToggleKnobBrush – Toggle switch knob color
DaisyTableRowHoverBackground – Table row hover state
DaisyInputPrimaryBorderBrush – Primary variant border
Lookup Priority
Resources are resolved in this order:
Control.Resources – Instance-level override (highest priority)
Application.Current.Resources – App-wide override
Fallback – Control’s internal palette logic
Application-Level Styling
Override in App.xaml to affect all instances of a control:
< Application.Resources >
< ResourceDictionary >
< SolidColorBrush x:Key = "DaisyButtonBackground" Color = "MediumSlateBlue" />
< SolidColorBrush x:Key = "DaisyCardBackground" Color = "#2A2A3A" />
</ ResourceDictionary >
</ Application.Resources >
Instance-Level Styling
Override on a single control instance:
< daisy:DaisyButton Content = "Custom Button" >
< daisy:DaisyButton.Resources >
< SolidColorBrush x:Key = "DaisyButtonBackground" Color = "Coral" />
< SolidColorBrush x:Key = "DaisyButtonForeground" Color = "White" />
</ daisy:DaisyButton.Resources >
</ daisy:DaisyButton >
Common Controls (Quick Reference)
Control Resources DaisyButton Background, Foreground, BorderBrush + variant-specificDaisyInput Background, Foreground, BorderBrush + variant-specificDaisyCard Background, ForegroundDaisyBadge Background, Foreground + variant-specificDaisyToggle KnobBrush, TrackBackground + variant-specificDaisyProgress FillBrush, TrackBrush + variant-specificDaisyModal BackdropBrush, Background
Variant-Specific Resources
Many controls support variant-specific overrides. The pattern is:
Daisy{Control}{Variant}{Property}
Example for DaisyButton with Primary variant:
DaisyButtonPrimaryBackground
DaisyButtonPrimaryForeground
DaisyButtonPrimaryBorderBrush
< Application.Resources >
< ResourceDictionary >
<!-- Override all Primary buttons -->
< SolidColorBrush x:Key = "DaisyButtonPrimaryBackground" Color = "DeepPink" />
< SolidColorBrush x:Key = "DaisyButtonPrimaryForeground" Color = "White" />
</ ResourceDictionary >
</ Application.Resources >
<!-- This button now has DeepPink background -->
< daisy:DaisyButton Content = "Primary" Variant = "Primary" />
Creating Custom Themes
Method 1: Override Palette Resources
The simplest approach is to override the core palette brushes in App.xaml:
< Application.Resources >
< ResourceDictionary >
< ResourceDictionary.MergedDictionaries >
<!-- Include Flowery.Uno resources -->
< ResourceDictionary Source = "ms-appx:///Flowery.Uno/Themes/Generic.xaml" />
</ ResourceDictionary.MergedDictionaries >
<!-- Override palette for custom theme -->
< SolidColorBrush x:Key = "DaisyBase100Brush" Color = "#1E1E2E" />
< SolidColorBrush x:Key = "DaisyBase200Brush" Color = "#2A2A3A" />
< SolidColorBrush x:Key = "DaisyBase300Brush" Color = "#3E3E4E" />
< SolidColorBrush x:Key = "DaisyBaseContentBrush" Color = "#E0E0E0" />
< SolidColorBrush x:Key = "DaisyPrimaryBrush" Color = "#FF6B9D" />
< SolidColorBrush x:Key = "DaisySecondaryBrush" Color = "#C678DD" />
< SolidColorBrush x:Key = "DaisyAccentBrush" Color = "#61AFEF" />
< SolidColorBrush x:Key = "DaisyInfoBrush" Color = "#61AFEF" />
< SolidColorBrush x:Key = "DaisySuccessBrush" Color = "#98C379" />
< SolidColorBrush x:Key = "DaisyWarningBrush" Color = "#E5C07B" />
< SolidColorBrush x:Key = "DaisyErrorBrush" Color = "#E06C75" />
</ ResourceDictionary >
</ Application.Resources >
Method 2: Custom Theme Dictionary
Create a separate ResourceDictionary for your theme:
Themes/MyCustomTheme.xaml:
< ResourceDictionary
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" >
<!-- Base colors -->
< SolidColorBrush x:Key = "DaisyBase100Brush" Color = "#0F0F1E" />
< SolidColorBrush x:Key = "DaisyBase200Brush" Color = "#1A1A2E" />
< SolidColorBrush x:Key = "DaisyBase300Brush" Color = "#25253E" />
< SolidColorBrush x:Key = "DaisyBaseContentBrush" Color = "#EAEAEA" />
<!-- Accent colors -->
< SolidColorBrush x:Key = "DaisyPrimaryBrush" Color = "#FF5370" />
< SolidColorBrush x:Key = "DaisySecondaryBrush" Color = "#C792EA" />
< SolidColorBrush x:Key = "DaisyAccentBrush" Color = "#82AAFF" />
<!-- Status colors -->
< SolidColorBrush x:Key = "DaisyInfoBrush" Color = "#82AAFF" />
< SolidColorBrush x:Key = "DaisySuccessBrush" Color = "#C3E88D" />
< SolidColorBrush x:Key = "DaisyWarningBrush" Color = "#FFCB6B" />
< SolidColorBrush x:Key = "DaisyErrorBrush" Color = "#FF5370" />
</ ResourceDictionary >
App.xaml:
< Application.Resources >
< ResourceDictionary >
< ResourceDictionary.MergedDictionaries >
< ResourceDictionary Source = "ms-appx:///Flowery.Uno/Themes/Generic.xaml" />
< ResourceDictionary Source = "Themes/MyCustomTheme.xaml" />
</ ResourceDictionary.MergedDictionaries >
</ ResourceDictionary >
</ Application.Resources >
Method 3: Programmatic Theme Creation
Create themes dynamically in code:
public static class CustomThemeManager
{
public static void ApplyCustomTheme ( string themeName )
{
var palette = themeName switch
{
"Midnight" => CreateMidnightPalette (),
"Ocean" => CreateOceanPalette (),
"Forest" => CreateForestPalette (),
_ => CreateDefaultPalette ()
};
ApplyPalette ( palette );
}
private static Dictionary < string , Color > CreateMidnightPalette ()
{
return new Dictionary < string , Color >
{
[ "DaisyBase100" ] = Color . FromArgb ( 255 , 15 , 15 , 30 ),
[ "DaisyBase200" ] = Color . FromArgb ( 255 , 26 , 26 , 46 ),
[ "DaisyBase300" ] = Color . FromArgb ( 255 , 37 , 37 , 62 ),
[ "DaisyBaseContent" ] = Color . FromArgb ( 255 , 234 , 234 , 234 ),
[ "DaisyPrimary" ] = Color . FromArgb ( 255 , 255 , 83 , 112 ),
[ "DaisySecondary" ] = Color . FromArgb ( 255 , 199 , 146 , 234 ),
[ "DaisyAccent" ] = Color . FromArgb ( 255 , 130 , 170 , 255 ),
// ... other colors
};
}
private static void ApplyPalette ( Dictionary < string , Color > palette )
{
foreach ( var ( key , color ) in palette )
{
var brushKey = key + "Brush" ;
if ( Application . Current . Resources . TryGetValue ( brushKey , out var resource ) &&
resource is SolidColorBrush brush )
{
brush . Color = color ;
}
else
{
Application . Current . Resources [ brushKey ] = new SolidColorBrush ( color );
}
}
}
}
Theme Color Calculation
Deriving Shades
Generate lighter/darker variants from a base color:
public static Color Lighten ( Color color , double amount )
{
var hsl = new HslColor ( color );
hsl . L = Math . Min ( 1.0 , hsl . L + amount );
return hsl . ToRgbColor ();
}
public static Color Darken ( Color color , double amount )
{
var hsl = new HslColor ( color );
hsl . L = Math . Max ( 0.0 , hsl . L - amount );
return hsl . ToRgbColor ();
}
// Usage
var baseColor = Color . FromArgb ( 255 , 100 , 150 , 200 );
var base100 = Darken ( baseColor , 0.3 );
var base200 = Darken ( baseColor , 0.2 );
var base300 = Darken ( baseColor , 0.1 );
Complementary Colors
Generate accent colors from primary:
public static Color GetComplementary ( Color color )
{
var hsl = new HslColor ( color );
hsl . H = ( hsl . H + 180 ) % 360 ;
return hsl . ToRgbColor ();
}
public static Color GetTriadic ( Color color , int offset )
{
var hsl = new HslColor ( color );
hsl . H = ( hsl . H + offset ) % 360 ;
return hsl . ToRgbColor ();
}
// Usage
var primary = Colors . Blue ;
var secondary = GetTriadic ( primary , 120 );
var accent = GetTriadic ( primary , 240 );
Style Inheritance with BasedOn
Create style hierarchies using BasedOn:
< Page.Resources >
< Style x:Key = "BaseButtonStyle" TargetType = "Button" >
< Setter Property = "Height" Value = "40" />
< Setter Property = "CornerRadius" Value = "8" />
</ Style >
< Style x:Key = "PrimaryButtonStyle" TargetType = "Button" BasedOn = "{StaticResource BaseButtonStyle}" >
< Setter Property = "Background" Value = "{ThemeResource DaisyPrimaryBrush}" />
</ Style >
< Style x:Key = "SecondaryButtonStyle" TargetType = "Button" BasedOn = "{StaticResource BaseButtonStyle}" >
< Setter Property = "Background" Value = "{ThemeResource DaisySecondaryBrush}" />
</ Style >
</ Page.Resources >
For system controls, base on the default style:
< Style TargetType = "TextBox" BasedOn = "{StaticResource DefaultTextBoxStyle}" >
< Setter Property = "BorderBrush" Value = "{ThemeResource DaisyPrimaryBrush}" />
</ Style >
Implicit vs Explicit Styles
Implicit Styles
Implicit styles (no x:Key) apply automatically to all matching controls:
< Page.Resources >
<!-- Applies to ALL Buttons on this page -->
< Style TargetType = "Button" >
< Setter Property = "CornerRadius" Value = "12" />
</ Style >
</ Page.Resources >
< Button Content = "Gets rounded corners automatically" />
Explicit Styles
Explicit styles (with x:Key) must be referenced:
< Page.Resources >
< Style x:Key = "RoundedButton" TargetType = "Button" >
< Setter Property = "CornerRadius" Value = "12" />
</ Style >
</ Page.Resources >
< Button Content = "Default corners" />
< Button Content = "Rounded" Style = "{StaticResource RoundedButton}" />
Best Practices
Prefer lightweight styling over full templates
Use BasedOn and resource overrides instead of creating custom control templates. Templates break when WinUI updates.
Use HSL for color manipulation
Generate theme variants using HslColor for consistent lightness/saturation adjustments.
Override only the core palette resources. Let controls derive their colors from the palette.
Use ThemeDictionaries for light/dark variants
Define both Light and Dark resource dictionaries for system theme support.
Ensure sufficient contrast ratios (WCAG AA: 4.5:1 for normal text, 3:1 for large text).
Include comments in your theme dictionary explaining color choices and intended usage.
Complete Example: Custom Theme
Themes/SunsetTheme.xaml:
< ResourceDictionary
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" >
<!-- Sunset Theme: Warm, vibrant colors inspired by twilight -->
<!-- Base colors: Deep purples and blues -->
< SolidColorBrush x:Key = "DaisyBase100Brush" Color = "#1A1625" />
< SolidColorBrush x:Key = "DaisyBase200Brush" Color = "#2A2435" />
< SolidColorBrush x:Key = "DaisyBase300Brush" Color = "#3A3245" />
< SolidColorBrush x:Key = "DaisyBaseContentBrush" Color = "#F0E6FF" />
<!-- Accent colors: Sunset hues -->
< SolidColorBrush x:Key = "DaisyPrimaryBrush" Color = "#FF6B6B" /> <!-- Coral -->
< SolidColorBrush x:Key = "DaisySecondaryBrush" Color = "#FFB347" /> <!-- Orange -->
< SolidColorBrush x:Key = "DaisyAccentBrush" Color = "#FFD93D" /> <!-- Yellow -->
<!-- Status colors: Matching the sunset palette -->
< SolidColorBrush x:Key = "DaisyInfoBrush" Color = "#A29BFE" /> <!-- Lavender -->
< SolidColorBrush x:Key = "DaisySuccessBrush" Color = "#6BCF7F" /> <!-- Mint -->
< SolidColorBrush x:Key = "DaisyWarningBrush" Color = "#FFB347" /> <!-- Orange -->
< SolidColorBrush x:Key = "DaisyErrorBrush" Color = "#FF6B6B" /> <!-- Coral -->
</ ResourceDictionary >
App.xaml:
< Application.Resources >
< ResourceDictionary >
< ResourceDictionary.MergedDictionaries >
< ResourceDictionary Source = "ms-appx:///Flowery.Uno/Themes/Generic.xaml" />
< ResourceDictionary Source = "Themes/SunsetTheme.xaml" />
</ ResourceDictionary.MergedDictionaries >
</ ResourceDictionary >
</ Application.Resources >
Your entire app now uses the Sunset theme!