Monthly Archives: January 2016

Binding a Slider to an Enumeration in UWP

Very often an Enumeration type represents a sequence or a ranking, like Offline-Connecting-Online or Bad-Good-Better-Best. In a user interface it would make sense to bind a property of such an Enum to a Slider control and let it more or less behave like a rating control.

In this article we’ll build a templatable custom control that

  • looks and behaves like a Slider,
  • can be two-way bound to most Enum types,
  • supports {x:Bind} and {Binding} declarative binding as well as programmatic binding,
  • provides a tooltip while sliding,
  • respects the Display data annotation attribute to support custom text, and
  • does not crash the XAML designer (!).

This is a screenshot from the sample app. It shows three instances of the EnumSlider control. Each of the sliders is bound in a different way to the same Importance property in the viewmodel:

EnumSlider

Style

It is possible to derive from the Slider base class, but we went for a templatable control. Here’s the default template, it contains just a Slider:

<Style TargetType="local:EnumSlider">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:EnumSlider">
                <Slider Name="PART_Slider"
                        SnapsTo="StepValues"
                        StepFrequency="1" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Class Definition

Properties and Initialization

The class definition holds a private field to store the Enum type, and a Value dependency property of type Object:

// The Enum Type to which we are bound.
private Type _enum;

// Value Dependency Property.
public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register(
        "Value",
        typeof(object),
        typeof(EnumSlider),
        new PropertyMetadata(null, OnValueChanged));

/// <summary>
/// Gets or sets the Value.
/// </summary>
public object Value
{
    get { return GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

When the template is applied to the control, we initialize the Slider:

/// <summary>
/// Called when the (default or custom) style template is applied.
/// </summary>
protected override void OnApplyTemplate()
{
    if (_enum == null)
    {
        // Keep the XAML Designer happy.
        return;
    }

    InitializeSlider();
}

During that initialization,

  • we set the slider’s range to the number of constants in the enumerator list,
  • we register an event handler to ValueChanged,
  • we update its Value by casting to integer, and
  • we assign a ThumbToolTipValueConverter so that the tooltip –while  sliding- shows text instead of the numerical value:
/// <summary>
/// Configures the internal Slider.
/// </summary>
private void InitializeSlider()
{
    var slider = this.GetTemplateChild(SliderPartName) as Slider;
    if (slider != null)
    {
        slider.ValueChanged += Slider_ValueChanged;
        slider.Maximum = Enum.GetNames(this._enum).Count() - 1;
        slider.ThumbToolTipValueConverter = new DoubleToEnumConverter(_enum);
        slider.Value = (int)this.Value;
    }
}

The range of the slider now goes from zero to the number of items in the enumeration (minus one), and we’re using the default Enum-to-int cast to map the values. This technique does NOT work when the enumeration does not use an integral type as its underlying type. It also does NOT work for enumerations that override their sequence, like this:

enum Importance
{
    None = -1,  // Does not work.
    Trivial,
    Moderate,
    Important = 10, // Does not work.
    Critical
};

In this version of the EnumSlider, we’ll NOT work around these issues. We assume that an enumeration without linear sequence numbers is probably not a good candidate to be bound to a linear slider. We like to keep this control lightweight, and hence only focus on the ‘regular’ enumerations.

If you *do* want a version of a slider control that deals with custom sequence numbers and underlying data types, please check this older version that we wrote a couple of years ago. Its mapping logic is built upon an internal dictionary with the enumeration’s text values.

Keeping the XAML Designer happy

The OnApplyTemplate is not only called at runtime. It may also be called at design time, by the XAML Designer. At that moment the Enum type is not yet known, so we should not try to configure the slider then. That’s why there is a null-check on _enum in the start of OnApplyTemplate. If we would trigger the slider initialization there, it would fail. The code would compile and run, but the IDE will not be able to preview any page that hosts the control. You’ll end up with an empty designer, and some squiggly lines in the XAML:

EnumSlider_DesignModeFail

Here’s the same IDE after we added the null-check:

EnumSlider_DesignMode

If you want developers to use your control in their apps, make sure it does not crash the XAML designer.

Runtime behavior

When the Value property of our control changes, all we need to do is updating the internal slider. When app starts, the very first update(s) may occur before the control is ready (i.e. before OnApplyTemplate is called). So the OnValueChanged event handler starts with a check to see whether or not the slider still needs to be initialized. This is also the place where we get our hands on the real Enum type to which the control is bound. At the end of the method, we update the slider’s value with that same cast from Enum to Integer:

/// <summary>
/// Called when the Value changed, e.g. through data binding.
/// </summary>
private static void OnValueChanged(DependencyObject d, 
	DependencyPropertyChangedEventArgs e)
{
    var _this = d as EnumSlider;

    if (_this != null)
    {
        // Initialize the Enum Type.
        if (e.OldValue == null)
        {
            if (e.NewValue is Enum)
            {
                _this._enum = e.NewValue.GetType();
                _this.InitializeSlider();
                return; // Slider got its value.
            }
        }

        var slider = _this.GetTemplateChild(SliderPartName) as Slider;

        if (slider != null)
        {
            slider.Value = (int)_this.Value;
        }
    }
}

Converters, converters, converters

Dealing with data annotations

In the tooltip that is shown when the user manipulates the slider, we’re going to show the text value that corresponds to the current slider value (a Double).  Unfortunately, enumerator constants cannot contain special characters or spaces, and they’re also not localizable. It’s however possible to decorate them with a Display data annotation attribute, like this:

enum Importance
{
    None,
    Trivial,
    Moderate,
    Important,
    [Display(Name = "O M G")]
    Critical
};

The lookup of the corresponding text value is done in the converter instance that we assigned in the slider’s initialization. The string representation of the enumerator –also its name in the type definition- is found with a call to Enum.ToObject(). Then we apply some reflection –with GetRuntimeFields and GetCustomAttribute– to get to the Display attribute’s value: 

/// <summary>
/// Converts the value of the internal slider into text.
/// </summary>
/// <remarks>Internal use only.</remarks>
internal class DoubleToEnumConverter : IValueConverter
{
    private Type _enum;

    public DoubleToEnumConverter(Type type)
    {
        _enum = type;
    }

    public object Convert(object value, 
			Type targetType, 
			object parameter, 
			string language)
    {
        var _name = Enum.ToObject(_enum, (int)(double)value);

        // Look for a 'Display' attribute.
        var _member = _enum
            .GetRuntimeFields()
            .FirstOrDefault(x => x.Name == _name.ToString());
        if (_member == null)
        {
            return _name;
        }

        var _attr = (DisplayAttribute)_member
			.GetCustomAttribute(typeof(DisplayAttribute));
        if (_attr == null)
        {
            return _name;
        }

        return _attr.Name;
    }

    public object ConvertBack(object value, 
		Type targetType, 
		object parameter, 
		string language)
    {
        return value; // Never called
    }
}

[Remember to run your app from time to time in release mode, especially when using reflection!]

Here’s the result. The tooltip of the middle slider shows ‘O M G’ instead of ‘Critical’:

EnumSliderDisplay

Alternatively you can use the Display value for looking up a localized value from a resource. For an example of this, check this article by Marco Minerva.

Dealing with {x:Bind}

Regular bindings are evaluated at runtime, but when you declaratively bind with the newer {x:Bind} construction, then some of the binding code is generated at compile-time. For a two-way binding, the compiler will verify the compatibility between the viewmodel’s property (in our case: the enumeration) and the control’s property (in our case: the Value property of type Object). The compiler will not be happy if we define the binding like this:

<controls:EnumSlider Value="{
	x:Bind ViewModel.Importance, 
	Mode=TwoWay />

Here’s the complaint:

xBindIssue

To reassure the compiler, we are forced to plug in a converter. Here’s the full code of that converter:

/// <summary>
/// Facilitates two-way binding to an Enum.
/// </summary>
public class EnumConverter : IValueConverter
{
    private Type _enum;

    public object Convert(
	object value, 
	Type targetType, 
	object parameter, 
	string language)
    {
        _enum = value.GetType();
        return value;
    }

    public object ConvertBack(
	object value, 
	Type targetType, 
	object parameter, 
	string language)
    {
        if (_enum == null)
        {
            return null;
        }

        return Enum.ToObject(_enum, (int)value);
    }
}

Here’s the working version of the {x:Bind} declaration in XAML:

<controls:EnumSlider Value="{
	x:Bind ViewModel.Importance, 
	Mode=TwoWay, 
	Converter={StaticResource EnumConverter}}" />

For a regular –old school- binding, the converter is not necessary:

<controls:EnumSlider 
	DataContext="{x:Bind ViewModel}"
	Value="{Binding Importance, Mode=TwoWay}" />

OK, we covered the two declarative binding techniques. Let’s now take a look at programmatic binding. Here’s the XAML:

<controls:EnumSlider x:Name="CodeBehindSlider" />

And here’s the C# bit:

this.CodeBehindSlider.BindTo(ViewModel, "Importance");

For convenience, the EnumSlider has a helper method that facilitates setting up a two-way binding to its Value:

/// <summary>
/// Sets up a two-way data binding.
/// </summary>
public bool BindTo(object viewModel, string path)
{
    try
    {
        Binding b = new Binding();
        b.Source = viewModel;
        b.Path = new PropertyPath(path);
        b.Mode = BindingMode.TwoWay;
        // b.Converter = new EnumConverter();
        this.SetBinding(EnumSlider.ValueProperty, b);
    }
    catch (Exception)
    {
        return false;
    }

    return true;
}

[It turns out that the converter is optional, so this helper method does not actually add much value…]

Wait, there’s more: … another converter

The logic in the internal converter that looks up the value for the Display attribute, is so useful that we decided to expose it. The control’s project has a public EnumDisplayConverter that converts an enumeration instance to its display value. The code is roughly the same as in the DoubleToEnumConverter, and it can be used to bind a text to the enum property. This is the XAML for the text block in the upper right corner of the page:

<TextBlock Text="{
	x:Bind ViewModel.Importance, 
	Mode=OneWay, 
	Converter={StaticResource EnumDisplayConverter}}" />

Alternatively, we could have exposed the logic as an extension method of Enum, but then it would be less discoverable.

It’s Universal

We haven’t tested the project on a Raspberry Pi yet, but here’s how it looks like on the phone:

EnumSlider_Phone1 EnumSlider_Phone2

Takeaways

Here are some takeaways for custom control builders:

  • Write defensive code in OnApplyTemplate and OnValueChanged event handlers. You never know in which order they are called.
  • Make sure to not crash the XAML Designer.
  • Test your controls against all types of data binding.
  • Test your controls in release mode from time to time.
  • If your control contains logic that could be useful to the client, expose that logic.

Source

The sample app and the control live here on GitHub. The EnumSlider control has its own project, for easy reuse.

Enjoy!

Advertisements

Building a custom UWP control with XAML and the Composition API

In this article we’ll build a custom UWP control that will be drawn partly by the XAML engine and partly by the Composition API. We’ll start from scratch … well almost. We’ll build yet another new version of the Modern Radial Gauge. Here’s how it will look like. The ‘old’ full-XAML gauge is on the left, the new version is on the right:

CompositionGauge_Comparison

The design of this radial gauge is timeless, thanks to Arturo Toledo. Unfortunately its implementations are not as timeless. The ‘old’ gauge goes back to early versions of Windows 8 and the continuous upgrades to more recent platforms have stretched its limits. Literally. Over the last couple of years, device screens have improved and the XAML engine was adapted to run on more and more platforms. We noticed that on some screens, the rotations and translations of the XAML elements are starting to suffer from rounding errors. As a result the radial gauge does not look crisp anymore in every size and resolution. The screenshot proves why it’s time for a new version, and why we could use some help from the Composition API:

CompositionGauge_Errors

Anatomy of a Radial Gauge

A gauge is an indicator that displays a value within a range – so it needs to have things like Minimum, Maximum, Value, and probably a Unit. A radial gauge is a gauge that looks like an analog clock – so it comes with things like a Scale, Ticks, and a Needle.

Here’s an overview of the important UI parts of the Modern Radial Gauge:

CompositionGauge_Anatomy

Here’s the list of properties that are defined in the actual control:

  • Minimum: minimum value on the scale (double, default 0)
  • Maximum: maximum value on the scale (double, default 100)
  • Value: the value to represent (double, default 0)
  • ValueStringFormat: StringFormat to apply to the displayed value (string)
  • Unit: unit measure to display (string)
  • TickSpacing: spacing -in value units- between ticks (int)
  • NeedleBrush: color of the needle (SolidColorBrush)
  • TickBrush: color of the outer ticks (SolidColorBrush)
  • ScaleWidth: thickness of the scale in pixels – relative to the control’s default size (double, default 26)
  • ScaleBrush: background color of the scale (Brush)
  • ScaleTickBrush: color of the ticks on the scale (SolidColorBrush)
  • TrailBrush: color of the trail following the needle (Brush)
  • ValueBrush: color of the value text (Brush)
  • UnitBrush: color of the unit measure text (Brush)

Using the gauge on a page should be as easy as the following one-liner:

<controls:RadialGauge Value="{Binding Temperature}" Unit="°C" />

But the user of the control should be able to fully customize the looks – like this:

<controls:RadialGauge Value="85"
                        Unit="bottles of beer on the wall"
                        TickBrush="Transparent"
                        ScaleTickBrush="Transparent"
                        NeedleBrush="{StaticResource DarkBrown}"
                        TrailBrush="{StaticResource DarkBrown}"
                        UnitBrush="{StaticResource VeryDarkBrown}"
                        ValueBrush="{StaticResource DarkBrown}"
                        Margin="4">
    <controls:RadialGauge.ScaleBrush>
        <SolidColorBrush Color="#FFFFD9AA"
                            Opacity=".6" />
    </controls:RadialGauge.ScaleBrush>
</controls:RadialGauge>

On top of that, the control is templatable: a developer can hook the gauge to a custom template (provided or not by a designer) as long as some requirements are met.

Project Structure

In Visual Studio 2015, we created a class library and added a new item of the type ‘templated control’. The RadialGauge class inherits from Control, and comes with a Style definition the Themes/Generic.xaml file. Here’s how that looks like in the IDE:

CompositionGauge_VS

Control template

The generic.xaml file is a XAML ResourceDictionary that contains the default style with the ControlTemplate for the custom control – it can be overridden. We defined the radial gauge control as a 200 by 200 pixels grid, inside a ViewBox. All internal calculations are conveniently done against that 200×200 grid, but the ViewBox will stretch the gauge to any size:

<Style TargetType="local:RadialGauge">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:RadialGauge">
                <Viewbox>
                    <Grid x:Name="PART_Container"
                            Height="200"
                            Width="200">

Here’s how to decide what elements to put in the style. For the elements that are drawn by the Composition API, it’s simple: there’s no markup available for them (yet?), so they will always be drawn in code-behind. Any rectangle that is filled with a solid color or an image is a candidate for rendering through the Composition API and hence will not appear in the control template. For the radial gauge these are the ticks inside and outside the scale, and the needle.

If you’re not into DirectX then the remaining parts will be drawn in XAML. For these elements you still have the choice. You can declare them in the style, or program them in code-behind. For the radial gauge, the XAML parts are [the border of] two ArcSegment instances and the text blocks that display the value and the unit.

Here’s a visual overview of the radial gauge parts by technology:

CompositionGauge_Parts 

We can not define the arc segment fully in XAML: the width of the background scale is configurable, and the end point of the trail depends on the current value. So both arc segments need to be drawn programmatically. The corresponding Path elements are declared in the XAML control template, but only with their color properties set – no path or dimensions. The Stroke and StrokeThickness are bound through a TemplateBinding to properties that are defined in the class itself.

Here’s the XAML load of the control template:

<!-- Scale -->
<Path Name="PART_Scale"
        Stroke="{TemplateBinding ScaleBrush}"
        StrokeThickness="{TemplateBinding ScaleWidth}" />

<!-- Trail -->
<Path Name="PART_Trail"
        Stroke="{TemplateBinding TrailBrush}"
        StrokeThickness="{TemplateBinding ScaleWidth}" />

<!-- Value and Unit -->
<StackPanel VerticalAlignment="Bottom"
            HorizontalAlignment="Center">
    <TextBlock Name="PART_ValueText"
                Foreground="{TemplateBinding ValueBrush}"
                FontSize="20"
                FontWeight="SemiBold"
                Text="{TemplateBinding Value}"
                TextAlignment="Center"
                Margin="0 0 0 2" />
    <TextBlock Foreground="{TemplateBinding UnitBrush}"
                FontSize="16"
                TextAlignment="Center"
                Text="{TemplateBinding Unit}"
                Margin="0" />
</StackPanel>

Observe that all named elements follow the PART_Xxx naming convention which is typical for templated controls.

Class Definition

The C# class definition is decorated with TemplatePart attributes for those same named elements. Again, this is just a convention. It indicates to the template (re-)designer that the code will break when these parts are not provided by the template:

[TemplatePart(Name = ScalePartName, Type = typeof(Path))]
[TemplatePart(Name = TrailPartName, Type = typeof(Path))]
[TemplatePart(Name = ValueTextPartName, Type = typeof(TextBlock))]
public class RadialGauge : Control
{

Dependency Properties

The class definition also contains the properties that are exposed by the gauge: the Minimum, Maximum and current Value, and a set of colors. These are implemented as Dependency Properties, which makes them automagically available for data binding, animation, and change notification. A dependency property registration declares a name, a type, and optionally a default value and a change event handler.

Here’s part of the Value property definition:

public static readonly DependencyProperty ValueProperty = 
DependencyProperty.Register(
    "Value",
    typeof(double),
    typeof(RadialGauge),
    new PropertyMetadata(0.0, OnValueChanged));

public double Value
{
    get { return (double)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

private static void OnValueChanged(DependencyObject d, 
DependencyPropertyChangedEventArgs e)
{
    // Redraw trail, rotate needle, and update value text.
    // ...
}

The rest of the properties have similar declarations. They’re all generated by the same built-in code snippet: ‘propdp’.

Initial look

At runtime the OnApplyTemplate override is the first place where we have programmatic access to the fully templated control. All XAML elements are available there. If necessary, we can now refine the initial look. We will draw the scale and the ticks, and also the needle in its initial position. For each part, we call GetTemplateChild() to get a reference to the element in the template. It’s good practice to check if the part actually exists. After all, as a custom control developer we only provide a default template. We’re never sure of the actual template that will be applied.

Here’s the code for drawing the scale – we’ll spare you the details of the ArcSegment drawing routine:

var scale = this.GetTemplateChild(ScalePartName) as Path;
if (scale != null)
{
    var pg = new PathGeometry();
    var pf = new PathFigure();
    // ArcSegment details omitted.
    // ...
    pf.Segments.Add(seg);
    pg.Figures.Add(pf);
    scale.Data = pg;
}

So far for the XAML part, let’s move to the Composition API. In that same OnApplyTemplate() method we draw the ticks outside and inside the scale, and the needle. For an introduction to drawing with the Composition API, please check this article. The code presented there draws an analog clock with ticks and hands, so it is extremely similar to the radial gauge. With the Composition API you’ll always need

Here’s the code that draws the needle. The ticks and scale ticks are drawn the same way – they’re all just colored rectangles:

var container = this.GetTemplateChild(ContainerPartName) as Grid;
_root = container.GetVisual();
_compositor = _root.Compositor;

_needle = _compositor.CreateSpriteVisual();
_needle.Size = new Vector2(NeedleWidth, NeedleHeight);
_needle.Brush = _compositor.CreateColorBrush(NeedleBrush.Color);
_needle.CenterPoint = new Vector3(NeedleWidth / 2, NeedleHeight, 0);
_needle.Offset = new Vector3(100 - NeedleWidth / 2, 100 - NeedleHeight, 0);
_root.Children.InsertAtTop(_needle);

At the end of OnApplyTemplate() the gauge is properly initialized and ready to shine.

Changing the value

When the Value property changes, it fires the event handler that was registered in the dependency property definition. That handler is a static method –as imposed by the dependency property infrastructure- so you can’t use ‘this’  in it. The reference to the gauge comes in as a parameter of the type DependencyObject, so you have to cast it. I don’t remember why I called the corresponding variable ‘c’  in the following code, but it’s actually a common practice to call it ‘_this’, or ‘that’.

Here’s the code to update needle’s rotation, draw the trail, and update the text to its new value. The pattern is always the same: get a reference to the UI element from the control template, check if it’s really there, and then update it:

private static void OnValueChanged(DependencyObject d)
{
    RadialGauge c = (RadialGauge)d;
    if (!Double.IsNaN(c.Value))
    {
        var middleOfScale = 100 - ScalePadding - c.ScaleWidth / 2;
        c.ValueAngle = c.ValueToAngle(c.Value);

        // Needle
        if (c._needle != null)
        {
            c._needle.RotationAngleInDegrees = (float)c.ValueAngle;
        }

        // Trail
        var trail = c.GetTemplateChild(TrailPartName) as Path;
        if (trail != null)
        {
            if (c.ValueAngle > MinAngle)
            {
                trail.Visibility = Visibility.Visible;
                var pg = new PathGeometry();
                var pf = new PathFigure();
                // ArcSegment drawing omitted.
                // ...
                pf.Segments.Add(seg);
                pg.Figures.Add(pf);
                trail.Data = pg;
            }
            else
            {
                trail.Visibility = Visibility.Collapsed;
            }
        }

        // Value Text
        var valueText = c.GetTemplateChild(ValueTextPartName) as TextBlock;
        if (valueText != null)
        {
            valueText.Text = c.Value.ToString(c.ValueStringFormat);
        }
    }
}

In a production version of this gauge, it would make sense to also listen to changes in other properties. If you want to use this gauge to follow up the daily evolution of a stock quote, then the Minimum and Maximum values will change at runtime. This version assumes that all properties except Value are assigned in the XAML, and do not change after that.

Cleaning up the code

In the code snippets, we omitted the beef of the calculations. I admit that in earlier versions these calculations were hard to understand, and hence hard to maintain. In this version of the gauge, we took the time to finally factor out all relevant parameters, and defined them as constants with a decent name: 

private const double MinAngle = -150.0;
private const double MaxAngle = 150.0;
private const float TickHeight = 18.0f;
private const float TickWidth = 5.0f;
private const float ScalePadding = 23.0f;
private const float ScaleTickWidth = 2.5f;
private const float NeedleWidth = 5.0f;
private const float NeedleHeight = 100.0f;

Not only does this make the calculations easier to understand and more maintainable, it also reveals good candidate dependency properties for future versions of the control. I definitely want to experiment with a scale from –180 to +90 degrees, like the ones in this car:

A5_gauges

[For the record: this is *not* my car – my speedometer stops at 280 and I have more fuel]

Testing the looks

The SquareOfSquares control is an ideal container to check the looks of the radial gauge with different settings for size, colors, and scale width. Here’s how the gauge looks like in a variety of partially random configurations:

CompositionGauge_Square

Of course it also makes sense to create a gallery with some representative looks, like this:

CompositionGauge_Gallery

You may consider the SquareOfSquares and the Gallery as a kind of ‘visual unit tests’.

Keep it Universal

Since the control is meant to be Universal, we must test it on all relevant device families. Here’s how the pages of the sample app look like on the phone:

CompositionGauge_Comparison_Phone CompositionGauge_Parts_Phone CompositionGauge_Square_Phone CompositionGauge_Gallery_Phone

Source Code

The upgraded version of the Modern Radial Gauge looks crisp again in any size and resolution. Its Visual Tree is a lot smaller, and the needle rotation is not done by the XAML engine anymore. That should result in better performance. That may be important e.g. in a dashboard with a huge amount of gauge instances. Last but not least, we identified some useful enhancements for future versions.

All source code is available. The sample app and all related controls live here on GitHub.

Enjoy!

How to generate an Adobe Color Swatch and transform it to XAML brushes

There are a lot of good free web sites that can create a group of matching colors for you. While it’s nice to go online and create such a palette, it’s another thing to transform a –sometimes lengthy- list of colors on an HTML page into something that can be used in XAML, e.g. a list of brush definitions.

Luckily, most of these web sites have one thing in common: they allow you to export the color palette to a so-called Color Swatch. That’s an Adobe Photoshop file format for storing a list of named colors. Photoshop uses the .aco extension for this file type.

In this blog post, I’ll introduce you to some of these web sites, and I also present a Portable Class Library project together with a Universal Windows Platform app to read a Color Swatch, and export its content to a list of XAML SolidColorBrush definitions that you can use as a resource.

How to create a color palette

Here are some approaches that you can take to come up with a consistent color palette for your app.

The mathematical approach

In the mathematical approach, you hand pick one or two primary colors and calculate the rest of the palette. This calculation is based on the position of the colors in a color wheel. The generated theme will contain your selected base colors, plus their adjacent (a.k.a. analog or harmonious) colors or triad colors or tetrad colors, and optionally their complementary color.

There are a lot of web sites with an interactive color wheel, such as Adobe itself and ColorsOnTheWeb, but I always keep coming back to Paletton:

paletton

Not only does this site allow you to interactively design a color palette, it also has a lot of preview options: site samples, drawings, and even animations. It also allows you to export the color scheme to different formats, including XML, CSS, and ACO:

paletton_export

There is a lot more in color theory and color psychology than just the color wheel: warmth, shades, tints, hue, and so on. But unless you are a talented designer, a color palette based on the color wheel will have better harmony and contrast (and hence will be better perceived by your users) than a random set of hand picked colors.

The image approach

A second approach for generating a color scheme is analyzing the pixels of an image that you find attractive. There a a lot of web sites around that create a color palette out of an image that you upload.

Here’s an example of a palette that was generated from the picture of a fox, by Pictaculous:

Pictaculous

The site not only returns the colors of the calculated palette, but also links to related color schemes that are stored in the libraries of Adobe Kuler and ColourLovers. There’s also an API for all of this. The export format for Pictaculous is … Adobe Photoshop Color Swatch.

Every site or tool uses a different algorithm to pick scheme colors, so you may want to shop around. Here’s what Adobe –my favorite site for this approach- generates from that same fox:

AdobeColorCC

With the image-to-palette approach you rely on the inherent beauty and harmony of nature. Well … more probably you rely on the talent of a photographer, artist, fashion designer, or film maker. When they create an image, they do that with a color palette in mind. That palette is based on … the color wheel. Here’s a nice introduction to cinematic color design, and there are more examples at MoviesInColor (which unfortunately has no export feature).

By the way, it’s not only photos from nature that yield nice color palettes. Here’s what CSSDrive generates from a photo of a city:

cssdrive

Themes that are generated by CSS Drive can be saved as CSS or ACO.

Hint: if you’re looking for candidate pictures for this approach, any Bing background will do:

bing

Get a designer

Of course you can also get a professional graphic designer to create a color palette for you. The odds are very high that he or she will come up with an Adobe Color Swatch. That’s also what Google’s Material Design’s designers have done: you can download all of their color palettes right here. It should be no surprise that this is … an .aco file.

Reading an Adobe Color Swatch file

I was getting tired of copy-pasting individual hexadecimal color codes out of HTML, and into XAML. So I was pleased to discover that they all support the .aco format. The next step was building a Universal Windows Platform app to transform the list of named colors in a Color Swatch into a list of XAML SolidColorBrush definitions.

The C# code that reads the color swatch content is written by Richard Moss, and described in this excellent article. I just copy-pasted the algorithm out of its Windows Forms application into a stand-alone Portable Class Library. So it can be called now from any .NET environment, including Xamarin. I removed the references to File and Color from the original code (they don’t exist in PCL), and stored the algorithm in its own class.

The AcoConverter class has only one public method –ReadPhotoShopSwatchFile– that takes a stream –the content of the .aco file- and returns a collection of SwatchColor – a small helper class.

AcoConverterVS

I also created an UWP app that lets you select a Color Swatch through a FileOpenPicker, visualize the palette, and export it to a list of XAML SolidColorBrush definitions through a FileSavePicker.

Here’s a palette from Paletton:

paletton2

This is how that palette looks like in the app:

AcoConverter

And here’s the export:

<SolidColorBrush x:Key='Primary color 1' Color='#FFAA3939' /> 
<SolidColorBrush x:Key='Primary color 2' Color='#FFFF5555' /> 
<SolidColorBrush x:Key='Primary color 3' Color='#FFF35151' /> 
<SolidColorBrush x:Key='Primary color 4' Color='#FF612020' /> 
<SolidColorBrush x:Key='Primary color 5' Color='#FF180808' /> 
<SolidColorBrush x:Key='Secondary color (1) 1' Color='#FF226666' /> 
<SolidColorBrush x:Key='Secondary color (1) 2' Color='#FF4BE2E2' /> 
<SolidColorBrush x:Key='Secondary color (1) 3' Color='#FF319292' /> 
<SolidColorBrush x:Key='Secondary color (1) 4' Color='#FF133A3A' /> 
<SolidColorBrush x:Key='Secondary color (1) 5' Color='#FF050E0E' /> 
<SolidColorBrush x:Key='Secondary color (2) 1' Color='#FF7B9F35' /> 
<SolidColorBrush x:Key='Secondary color (2) 2' Color='#FFC3FA53' /> 
<SolidColorBrush x:Key='Secondary color (2) 3' Color='#FFB0E34C' /> 
<SolidColorBrush x:Key='Secondary color (2) 4' Color='#FF465A1E' /> 
<SolidColorBrush x:Key='Secondary color (2) 5' Color='#FF111607' />

Source code

The source code lives here on GitHub. As already mentioned, the core logic is in a PCL project, so it can be called from any .NET environment.

Enjoy!

Using a Simple Perfect Squared Square to test UWP controls

This article presents a UWP XAML control that displays 21 square UI elements, each of a different size, inside a square.

Math to the rescue

For testing the UI and the performance of some user controls, I wanted to create a square panel to host as many as possible square areas of a different size. That smells like a mathematical problem, right? And yes: I found a mathematical solution in a domain that is called squaring the square.

Allow me to introduce you to the lowest-order simple perfect squared square:

Squaring_the_square

It’s a “squared square” because … well … it’s a square made up of squares. It’s “perfect” because each of the inner squares has a different size, and it’s “simple” because no subset of inner squares forms a rectangle or square. On top of that, all of the 21 inner squares are “integral”: their side is of integer length (which is convenient for calculating coordinates).

You can devote an entire web site to this, or you can use it as a design for furniture. Personally, I think of it as a nice frame for torturing testing UI components.

Creating the Square of Squares control

So I built the SquareOfSquares, a –square- XAML UserControl that hosts a series of –square- ContentControl instances, distributed according to the simples perfect squared square pattern. On the outside, it’s a square Grid, wrapped in a ViewBox. The side of the grid is a multiple of 112, which is the side of the mathematical square. It’s a size in relative pixels, so I made it big enough (1120) to avoid rounding problems when the actual controls are drawn:

<Viewbox Stretch="Uniform">
    <Grid x:Name="Root"
            Height="1120"
            Width="1120" />
</Viewbox>

The control has a private list of instances of an –also private- InnerSquare class. This list holds the position and the side of all the inner squares:

private List<InnerSquare> GetSquares()
{
    var list = new List<InnerSquare>();

    list.Add(new InnerSquare() { Position = new Point(0, 0), Side = 50 });
    list.Add(new InnerSquare() { Position = new Point(50, 0), Side = 35 });
    list.Add(new InnerSquare() { Position = new Point(85, 0), Side = 27 });
    // more of these ...
    return list;
}

When the SquareOfSquare is created, 112 rows and columns are created, and for each of the inner squares a ContentControl is created with the relevant attached grid properties (i.e. row, column, and both spans):

for (int i = 0; i < 112; i++)
{
    Root.RowDefinitions.Add(new RowDefinition() 
    { Height = new GridLength(1, GridUnitType.Star) });
    Root.ColumnDefinitions.Add(new ColumnDefinition() 
    { Width = new GridLength(1, GridUnitType.Star) });
}

foreach (InnerSquare square in GetSquares())
{
    var ctl = new ContentControl();
    ctl.SetValue(Grid.RowProperty, square.Position.Y);
    ctl.SetValue(Grid.ColumnProperty, square.Position.X);
    ctl.SetValue(Grid.ColumnSpanProperty, square.Side);
    ctl.SetValue(Grid.RowSpanProperty, square.Side);
    Root.Children.Add(ctl);
    Squares.Add(ctl);
}

The content controls are added to the grid, but also to a Squares list, which is exposed as a property:

public List<ContentControl> Squares { get; private set; } 
           = new List<ContentControl>();

I also added some extension methods that apply to the inner squares: Side() and RandomColor():

private static Random r = new Random(DateTime.Now.Millisecond);

/// <summary>
/// Returns the side of an inner square.
/// </summary>
public static int Side(this UIElement element)
{
    return (int)element.GetValue(Grid.RowSpanProperty);
}

/// <summary>
/// Returns a random color.
/// </summary>
/// <remarks>Not necessarily an extension method. Just for convenience.</remarks>
public static Color RandomColor(this UIElement element)
{
    byte red = (byte)r.Next(0, 255);
    byte green = (byte)r.Next(0, 255);
    byte blue = (byte)r.Next(0, 255);

    return new Color() { A = 255, R = red, G = green, B = blue };
}

Feel free to add similar methods to return the position of the square, if you require.

Using the Square of Squares control

To use the control, drop it on a page, and give it a name:

<controls:SquareOfSquares x:Name="SquareOfSquares"
                            Margin="20" />

To populate the inner squares, iterate through the Squares collection, create your UI element, and set it as Content of the inner square. The following code snippet creates a grid with a random background color, that displays the length of the side of the square in its upper left corner:

foreach (var square in SquareOfSquares.Squares)
{
    var grid = new Grid() 
    { Height = square.ActualHeight, Width = square.ActualWidth };
    grid.Background = new SolidColorBrush(square.RandomColor());
    var side = square.Side().ToString();
    grid.Children.Add(new TextBlock() 
    { Text = side, Margin = new Thickness(2.0, 1.0, 0.0, 0.0), 
       Foreground = new SolidColorBrush(Colors.White) });
    square.Content = grid;
}

Here’s how that looks like:

SquareColors

Here’s the code to add a Radial Gauge control (from NuGet) to each of the squares:

foreach (var square in SquareOfSquares.Squares)
{
    var gauge = new Gauge() 
    { Height = square.ActualHeight, Width = square.ActualWidth };
    gauge.TrailBrush = new SolidColorBrush(square.RandomColor());
    gauge.TickBrush = new SolidColorBrush(Colors.Transparent);
    gauge.ScaleTickBrush = new SolidColorBrush(Colors.LemonChiffon);
    gauge.NeedleBrush = new SolidColorBrush(Colors.OrangeRed);
    gauge.Maximum = 50;
    var side = square.Side();
    gauge.Value = side;
    square.Content = gauge;
}

This is the result:

SquareGauges

And here’s the very straightforward code to add a Composition API Clock control:

foreach (var square in SquareOfSquares.Squares)
{
    var clock = new Clock() 
    { Height = square.ActualHeight, Width = square.ActualWidth };
    square.Content = clock;
}

This code results in a simple perfect squared square of ticking clocks:

SquareClocks

Here’s how these three examples look like on a Windows Phone:

SquareColors_Phone SquareGauges_Phone SquareClocks_Phone

Source Code

The sample app, together with the SquareOfSquares control, lives here on GitHub. The control is in its own project, ready for use.

Enjoy!

Using the Composition API in UWP apps

In this article we’ll explore the Windows.UI.Composition API. The Composition API is a visual layer that sits between the Windows 10 XAML framework and DirectX. It gives Universal Windows Platform apps an easy access to the lower level Windows drawing stacks. The API focuses on drawing rectangles and images –with or without a XAML surface- and applying animations and effects on these. Here’s an illustration from the official documentation:

Composition_API

To discover the API, I created a sample app with different versions of a user control representing a clock. The clock is just an empty XAML element, the ticks and hands are drawn by the Composition API.

The first version of the clock is only composed of rectangles:

clock

The XAML surface of the clock control is a Canvas, wrapped in a ViewBox for easy scaling. The Canvas has a name –Container- so we can access it in the code behind:

<Viewbox Stretch="Uniform">
    <Canvas x:Name="Container"
            Background="Transparent"
            Height="200"
            Width="200">
    </Canvas>
</Viewbox>

The rest of the clock is drawn and animated through Composition.

Core classes

The core of the Composition API is the Compositor, a factory class that spawns all the drawing objects, like sprites and brushes. The clock UI is drawn as a ContainerVisual, a composite image. We need some fields or variables to hold a reference to an instance of these two classes:

private Compositor _compositor;
private ContainerVisual _root;

The clock is drawn inside a XAML Canvas. The link between any XAML element and the DirectX drawing layer is established through static methods on the ElementCompositionPreview class. I packaged these calls in a reusable extension method:

public static ContainerVisual GetVisual(this UIElement element)
{
    var hostVisual = ElementCompositionPreview.GetElementVisual(element);
    var root = hostVisual.Compositor.CreateContainerVisual();
    ElementCompositionPreview.SetElementChildVisual(element, root);
    return root;
}

Here’s how the clock control initializes the Composition layer and hooks it to its XAML Canvas (remember: Container is the name for the Canvas):

_root = Container.GetVisual();
_compositor = _root.Compositor;

All visuals are created by the _compositor, and added to the _root.

Drawing Rectangles

Visuals are just rectangles, if you want to fill the rectangle with a solid color, an image, or an effect (three types of CompositionBrush), then SpriteVisual is what you need – a Visual with a Brush. Here’s how the clock draws its twelve hour ticks. For each tick, the compositor creates a new SpriteVisual, the rectangle is properly configured (size, brush, position, center of rotation, and rotation angle), and finally it’s added to the ContainerVisual:

SpriteVisual tick;
for (int i = 0; i < 12; i++)
{
    tick = _compositor.CreateSpriteVisual();
    tick.Size = new Vector2(4.0f, 20.0f);
    tick.Brush = _compositor.CreateColorBrush(Colors.Silver);
    tick.Offset = new Vector3(98.0f, 0.0f, 0);
    tick.CenterPoint = new Vector3(2.0f, 100.0f, 0);
    tick.RotationAngleInDegrees = i * 30;
    _root.Children.InsertAtTop(tick);
}

The hour, minute, and second hands are created in exactly the same way. Here’s the code for the hour hand, its initial position is twelve-o-clock:

_hourhand = _compositor.CreateSpriteVisual();
_hourhand.Size = new Vector2(4.0f, 100.0f);
_hourhand.Brush = _compositor.CreateColorBrush(Colors.Black);
_hourhand.CenterPoint = new Vector3(2.0f, 80.0f, 0);
_hourhand.Offset = new Vector3(98.0f, 20.0f, 0);
_root.Children.InsertAtTop(_hourhand);

The hour and minute hands are not animated, we just update their rotation angle every now and then:

private void SetHoursAndMinutes()
{
    var now = DateTime.Now;
    _hourhand.RotationAngleInDegrees = (float)now.TimeOfDay.TotalHours * 30;
    _minutehand.RotationAngleInDegrees = now.Minute * 6;
}

Defining Animations

For the second hand we defined an animation on its rotation angle. We let the Compositor factory create a ScalarKeyFrameAnimation, configured it by inserting key frames and giving it a duration, an then started the animation:

var now = DateTime.Now;
var animation = _compositor.CreateScalarKeyFrameAnimation();
var seconds = (float)(int)now.TimeOfDay.TotalSeconds;
animation.InsertKeyFrame(0.00f, seconds * 6);
animation.InsertKeyFrame(1.00f, (seconds + 1) * 6);
animation.Duration = TimeSpan.FromMilliseconds(900);
// _secondhand.StartAnimation("RotationAngleInDegrees", animation);
_secondhand.StartAnimation(nameof(_secondhand.RotationAngleInDegrees), animation);

We did the calculation in the app’s code, but you may delegate some of that work to the Composition API. Every CompositionAnimation instance allows you to define different types of parameters. These parameters can be used in string expressions, such as the expressions that calculate the value of a key frame. Here’s an alternative for (part of) the previous code snippet:

animation.SetScalarParameter("start", seconds * 6);
animation.InsertExpressionKeyFrame(0.00f, "start");
animation.SetScalarParameter("delta", 6.0f);
animation.InsertExpressionKeyFrame(1.00f, "start + delta");

The animation is triggered every second by a timer, and lasts for 900 milliseconds, so the hand stops briefly at every second tick. In that short interval between the two animations, we update the rotation angle of the hour and minute hands. We do this not only because it looks nice, but also because we wanted an excuse to introduce you to the CompositionScopedBatch class.

Using a Scoped Batch

An individual animation has no Ended event. But you can create a batch with a group of animations. The batch contains all the animations that are defined between its creation and a call to its End() method. When all animations are completed, the batch raises its Completed event. In the clock control, we wrapped the second hand animation in a batch, and registered an event handler to update the hour and minute hands:

_batch = _compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
var animation = _compositor.CreateScalarKeyFrameAnimation();
// animation configuration
// ...
_secondhand.StartAnimation("RotationAngleInDegrees", animation);
_batch.End();
_batch.Completed += Batch_Completed;
private void Batch_Completed(object sender, CompositionBatchCompletedEventArgs args)
{
    _batch.Completed -= Batch_Completed;

    SetHoursAndMinutes();
}

When you run the app in Visual Studio you’ll see a fully functional clock. When you open the Live Visual Tree of the clock, you’ll see that the Container canvas has no XAML children.

Mixing XAML and Composition Visuals

Any XAML that you add inside the Canvas –declaratively or programmatically- will be displayed underneath the Composition API’s visual layer. Here’s the declaration of the Face – the circular background of the clock:

<Viewbox Stretch="Uniform">
    <Canvas x:Name="Container"
            Background="Transparent"
            Height="200"
            Width="200">
        <Ellipse x:Name="Face"
                    Height="200"
                    Width="200"
                    Canvas.Left="0"
                    Canvas.Top="0" />
    </Canvas>
</Viewbox>

And here’s how a background image is programmatically added as a XAML Image. Both Face and BackgroundImage become part of the XAML Visual Tree:

public Brush FaceColor { get; set; } = new SolidColorBrush(Colors.Transparent);
public ImageSource BackgroundImage { get; set; }

private void Clock_Loaded(object sender, RoutedEventArgs e)
{
    Face.Fill = FaceColor;

    // Composition API stuff.
    // ...

    // Add XAML element.
    if (BackgroundImage != null)
    {
        var xaml = new Image();
        xaml.Source = BackgroundImage;
        xaml.Height = 200;
        xaml.Width = 200;
        Container.Children.Add(xaml);
    }
}

So you can combine Composition API drawings and XAML elements into the same surface.

This is the declaration of the clocks on the main page:

<controls:Clock />
<controls:Clock ShowTicks="False"
                BackgroundImage="ms-appx:///Assets/modern_face.png"
                FaceColor="LightGoldenrodYellow" />

And here’s the corresponding UI:

Clock_Modern

Adding Images

A second version of the Clock control allows you to use images for the clock face and the hour and minute hands, such as these:

ClockElements

I provided some properties for the images, each with a default Uri:

public Uri FaceImage { get; set; } = new Uri("ms-appx:///Assets/roman_face.jpg");
public Uri HourHandImage { get; set; } = new Uri("ms-appx:///Assets/hour_hand.png");
public Uri MinuteHandImage { get; set; } = new Uri("ms-appx:///Assets/minute_hand.png");

When you want to work with image files in the Composition API, your project needs a reference to the Windows.UI.Composition.Toolkit. There’s no NuGet package for this [I assume that the functionality will become part of the API in the near future] so I copied the C++ source from the official Composition API Samples on GitHub.

CompositionToolkit

The toolkit comes with a CompositionImageFactory that allows you to read and decode images from a Uri, and use these as a SurfaceBrush for a SpriteVisual. Here’s the sample app code for loading the clock’s background image:

_background = _compositor.CreateSpriteVisual();
_background.Size = new Vector2(200.0f, 200.0f);
var _imageFactory = CompositionImageFactory.CreateCompositionImageFactory(_compositor);
CompositionImageOptions options = new CompositionImageOptions()
{
    DecodeWidth = 400,
    DecodeHeight = 400,
};
var _image = _imageFactory.CreateImageFromUri(FaceImage, options);
_background.Brush = _compositor.CreateSurfaceBrush(_image.Surface);
_root.Children.InsertAtTop(_background);

Here’s the code for the hour hand:

options = new CompositionImageOptions()
{
    DecodeWidth = 72,
    DecodeHeight = 240,
};

_hourhand = _compositor.CreateSpriteVisual();
_hourhand.Size = new Vector2(24.0f, 80.0f);
_image = _imageFactory.CreateImageFromUri(HourHandImage, options);
_hourhand.Brush = _compositor.CreateSurfaceBrush(_image.Surface);
_hourhand.CenterPoint = new Vector3(12.0f, 70.0f, 0);
_hourhand.Offset = new Vector3(88.0f, 30.0f, 0);
_root.Children.InsertAtTop(_hourhand);

Make sure that such images have a transparent background. Paint.NET is an excellent tool for this: click with the magic wand tool on the background, and press ‘delete’.  But of course you may also opt for PhotoShop, and a designer.

Here’s an example of two instances of the same clock control, each with a different set of images:

Clock_Classic

Adding some fun

When looking for clock images for the sample app, I came across this awesome DIY Silly Walk clock. It has four layers of images: the background, the two hands (well … legs in this case), and the body. Instead of calculating the individual positions, the decoding heights and widths, and the rotation center in code, I gave all four images the same size, and positioned them correctly.

The Silly Walk clock comes with a lot less code than the previous ones, but it brings a lot more fun. Here’s how it looks like on the PC:

Clock_SillyWalk

Here’s how all of the clocks in the sample app look like on a Windows Phone 10 (emulator):

Clock_Modern_Phone Clock_Classic_Phone Clock_SillyWalk_Phone

The Source

All of the source code, including image assets and a version of the C++ Composition Toolkit, lives here on GitHub.

Enjoy!