Skip to content

Custom themeable controls

anarchie347 edited this page May 15, 2023 · 3 revisions

Custom themeable controls

IMPORTANT NOTE - This library uses reflection to get properties from their names, so the name of properties is VERY important

To define your own controls, make a new class that implements IThemeableControl

For all the themeable properties you want to add, create a new property whose name must start with Theme Implement the property as below

You must also have a backing field for the property, the name of it doesnt matter

The type should be a Func<>? of whatever type the themeable property is editing. In this example, it is an image

replace base.BackgroundImage with whatever you want the property to edit

This example is for setting the Background Image of a control (it is from the ThemeableButton class)

private Func<Image>? themeImage = null;
public Func<Image>? ThemeImage
		{
			get { return themeImage; }
			set
			{
				themeImage = value;
				if (themeImage != null)
					base.BackgroundImage = themeImage();
			}
		}

For each themeable property, you must also have an Action<> property that refers to the property the themeable property changes. THis should be static and only have a get accessor

The first type for the Action<> is the class that the method is in. The class must implement IThemeableControl (ThemeableButton in this example)

The second type is the type of the property the themeable property edits, in this case Image because the themeable property edits the BackgroundImage property

This property must be named PropertyToEdit

The below is for the themeImage example above

public static Action<ThemeableButton, Image>? ThemeImagePropertyToEdit { get { return (ctrl, value) => ctrl.BackgroundImage = value; } }

The themeable control must also implement the ThemeChangedEvent. This can be done with the code below. It should not need changing between implementations

public event ThemeChangedEventHandler ThemeChanged = delegate { };
public void OnThemeChange(Theme oldTheme, Theme newTheme)
{
        ThemeChangedEventArgs tcev = new(oldTheme, newTheme);
        ThemeChanged?.Invoke(this, tcev);
}

The ThemeableForm will use reflection to get all of these properties so (other than the private backing field for the theme property) the names must match the specifieed naming. They must all begin with Theme and the Action<> property must be named after one of the other themeable properties and end in PropertyToEdit

The custom themeable controls must NOT have any properties that begin with Theme unles they are to be used by the ThemeableControl