HypernovaDesktop Components · docs
Binarymission
WPF › Skinning › BinarySkinManager

BinarySkinManager

class.NET 6 / 8 / 10.NET Framework 4.8Binarymission.WPF.Skinning

Holds the skin in force for the whole application, publishes it in the application's resources under BinarySkinKeys, and says when it changes.

public static class BinarySkinManager

Remarks

What follows the skin

Binarymission controls that follow the manager redraw themselves when SkinChanged is raised; the ribbon does when its skin is RibbonSkin.Shared. The other Binarymission WPF controls follow it too, unless AppliesToControls is turned off: each control's colours are theme resources, and a skin in force gives them values made from its own colours. A colour the application sets on a control itself, or on the control's resource key in its own resources, always wins.

Your own windows and styles

Refer to the keys in BinarySkinKeys with DynamicResource, and they change with the skin. A control of your own can also make its colours from each skin through RegisterControlResources.

Threading

Call it from the thread the application's windows run on. The skin is published into Current's resources; with no application object, the skin is held and SkinChanged raised, but nothing is published.

Examples

The application starts in the user's Windows colours, and offers a dark skin and touch spacing.

using System.Windows;
using Binarymission.WPF.Skinning;

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        BinarySkinManager.Apply(BinarySkins.Create(BinarySkinTheme.System));
    }
}

// From the View menu:
private void OnDarkSkinClick(object sender, RoutedEventArgs e)
    => BinarySkinManager.Apply(BinarySkins.Create(BinarySkinTheme.DarkGray));

private void OnTouchModeChecked(object sender, RoutedEventArgs e)
    => BinarySkinManager.Density = BinarySkinDensity.Touch;

See also

Members at a glance

Properties
AppliesToControlsGets or sets whether the Binarymission controls other than the ribbon take their colours from the skin in force.
CurrentGets a copy of the skin in force.
DensityGets or sets how closely controls that follow the manager pack their commands.
HasSkinGets whether a skin is in force.
IsDarkGets whether the skin in force is a dark one.
Methods
ApplyPuts a skin in force: publishes it in the application's resources and raises SkinChanged.
ClearTakes the skin in force away: removes it from the application's resources and raises SkinChanged. The controls go back to their own default colours.
CreateResourcesCreates the resources a skin is published as: each colour as a frozen brush and as a colour, the corner rounding, the density and whether it is dark, under the keys in BinarySkinKeys.
RegisterControlResourcesRegisters the way a control's colours are made from a skin. Each Binarymission control type that follows the skin calls it once; a control of your own can use it the same way.
Events
SkinChangedOccurs after Current, Density or AppliesToControls changes and the new values are in the application's resources.

Properties

AppliesToControls static

public static bool AppliesToControls

Gets or sets whether the Binarymission controls other than the ribbon take their colours from the skin in force.

Value
true, the default. When false they keep their own default colours whatever skin is in force; BinarySkinKeys is published either way.
Remarks

A change publishes the skin again and raises SkinChanged.

Current static

public static BinarySkin Current

Gets a copy of the skin in force.

Value
A copy of the skin, or null when none has been applied.
Remarks

A copy, so changing it changes nothing on screen until it is applied with Apply.

Density static

public static BinarySkinDensity Density

Gets or sets how closely controls that follow the manager pack their commands.

Value
BinarySkinDensity.Standard by default.
Exceptions
ArgumentOutOfRangeException
The value is not a BinarySkinDensity.
Remarks

A change is published under BinarySkinKeys.Density and raises SkinChanged. It is held whether or not a skin is in force.

HasSkin static

public static bool HasSkin

Gets whether a skin is in force.

Value
true after Apply and until Clear.

IsDark static

public static bool IsDark

Gets whether the skin in force is a dark one.

Value
The skin's BinarySkin.IsDark; false when no skin is in force.

Methods

Apply static

public static void Apply(BinarySkin skin)

Puts a skin in force: publishes it in the application's resources and raises SkinChanged.

Parameters
skin
The skin. It is copied, so changing it afterwards changes nothing until it is applied again.
Exceptions
ArgumentNullException
skin is null.
Remarks

The skin replaces whichever was in force, in place among the application's merged dictionaries.

Clear static

public static void Clear()

Takes the skin in force away: removes it from the application's resources and raises SkinChanged. The controls go back to their own default colours.

Remarks

Does nothing, and raises nothing, when no skin is in force.

CreateResources static

public static ResourceDictionary CreateResources(BinarySkin skin)

Creates the resources a skin is published as: each colour as a frozen brush and as a colour, the corner rounding, the density and whether it is dark, under the keys in BinarySkinKeys.

Parameters
skin
The skin.
Returns

A new dictionary. Merge it into a window's resources to give that window a skin of its own.

Exceptions
ArgumentNullException
skin is null.

RegisterControlResources static

public static void RegisterControlResources(Func<BinarySkin, ResourceDictionary> create)

Registers the way a control's colours are made from a skin. Each Binarymission control type that follows the skin calls it once; a control of your own can use it the same way.

Parameters
create
Makes the control's theme resources from a skin: a new dictionary, keyed by the same keys the control's default style refers to with DynamicResource. It is called with a copy of the skin each time a skin is published; registering the same delegate again does nothing.
Exceptions
ArgumentNullException
create is null.
Remarks

Safe to call from any thread, including from a static constructor: when a skin is already in force, the resources are published on the application's own thread before anything is next drawn.

Example
public class OrderCard : Control
{
    public static readonly ComponentResourceKey HeaderBrushKey = new ComponentResourceKey(typeof(OrderCard), "HeaderBrush");

    static OrderCard()
    {
        BinarySkinManager.RegisterControlResources(skin =>
        {
            var resources = new ResourceDictionary();
            resources[HeaderBrushKey] = BinarySkin.CreateBrush(
                ColorContrast.Mix(skin[BinarySkinColor.Surface], skin[BinarySkinColor.Accent], 0.15));
            return resources;
        });
    }
}

Events

SkinChanged static

public static event EventHandler SkinChanged

Occurs after Current, Density or AppliesToControls changes and the new values are in the application's resources.

Remarks

The sender is null, as the manager is static. Raised on the thread that made the change. A handler that holds on to a window keeps it alive while subscribed, so unsubscribe when the window closes.

Example
BinarySkinManager.SkinChanged += OnSkinChanged;
Closed += (sender, e) => BinarySkinManager.SkinChanged -= OnSkinChanged;

private void OnSkinChanged(object sender, EventArgs e)
{
    chart.Palette = BinarySkinManager.IsDark ? darkPalette : lightPalette;
}