Diederik Krols

The XAML Brewer

The Radial Gauge goes UWP

The Modern Radial Gauge that I built a couple of years ago for Windows 8 Store, Windows 8 Phone, and Windows 8.1 Universal Apps, recently made it to the Universal Windows Platform. It was designed by Arturo Toledo, built by myself, and then Filip Skakun embedded it in the WinRT XAML Toolkit, initially on CodePlex, now on GitHub.

I created a small sample app to test drive the new UWP version of the control. Here’s how it looks like on the PC:

gaugepc

The gauge is very customizable without the need for templating – although it *is* templatable. And as you see, it looks crisp in any size.

You bring the gauge in your apps through NuGet:

RadialGaugeNuGet

Here’s the control’s structure and its list of configurable properties:

taxonomy

  • Minimum: minimum value on the scale (double)
  • Maximum: maximum value on the scale (double)
  • Value: the value to represent (double)
  • 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 (Brush)
  • TickBrush: color of the outer ticks (Brush)
  • ScaleWidth: thickness of the scale in pixels – relative to the control’s default size (double)
  • ScaleBrush: background color of the scale (Brush)
  • ScaleTickBrush: color of the ticks on the scale (Brush)
  • TrailBrush: color of the trail following the needle (Brush)
  • ValueBrush: color of the value text (Brush)
  • UnitBrush: color of the unit measure text (Brush)

All colored components are configurable with a Brush instead of just a Color, so you can play with gradients, opacity, images, and so on. Here’s a page from the sample app to demonstrate this. It also demonstrates binding (using x:Bind):

gaugepc2

Here’s the XAML for the Dollar Bill Gauge:

<controls:Gauge Value="{x:Bind ViewModel.Expense, Mode=OneWay}"
                Unit="expense"
                ScaleTickBrush="Transparent"
                TickBrush="Transparent"
                ScaleWidth="40">
    <controls:Gauge.ScaleBrush>
        <ImageBrush ImageSource="ms-appx:///Assets/money.jpg" />
    </controls:Gauge.ScaleBrush>
    <controls:Gauge.NeedleBrush>
        <LinearGradientBrush EndPoint="1,0">
            <GradientStop Color="Transparent" />
            <GradientStop Color="Goldenrod"
                          Offset="0.5" />
            <GradientStop Color="Transparent"
                          Offset="1" />
        </LinearGradientBrush>
    </controls:Gauge.NeedleBrush>
    <controls:Gauge.TrailBrush>
        <SolidColorBrush Color="Green"
                         Opacity=".25" />
    </controls:Gauge.TrailBrush>
</controls:Gauge>

Here’s how the sample app shines on the phone:

gaugephone1 gaugephone2

The sample app is here on GitHub. It uses the NuGet package for the gauge. The official source code for the Radial Gauge is here on GitHub.

Enjoy!

XAML Brewer

Calendar integration in UWP apps

In this article I describe some typical calendar integration requirements and hold these against the Windows 10 Universal Windows Platform API’s. I tried to build an app that:

  • opens the calendar at a specific date and time,
  • creates a new appointment,
  • saves an appointment in the calendar,
  • displays a list of the appointments that it created,
  • opens a selected appointment from the list,
  • deletes a selected appointment from the list, and
  • deletes all its appointments,
  • uses roaming, and
  • adhere to MVVM principles.

Here’s how that app looks like - the mega-GUID is an appointment identifier from the list:

 calendar1

A while ago, I wrote a blog post about using the Calendar in Universal Windows 8.1 apps. I observed that Windows Phone and Windows Runtime required a totally different –in terms of object model as well as functionality- client side API to talk to the Calendar. I then decided to not implement calendar integration in my apps, at least not in the Windows 8.* versions. So let’s see if there’s some improvement. Apparently the API that in Windows 8 only worked on the phone, now really became universal. All members of the Windows.ApplicationModel.Appointments namespace are usable on desktop and tablet (and probably other devices). In the sample app, I wrapped all calendar interaction in an MVVM-inspired service:

calendar2

Opening the user’s Calendar

It makes sense for an app to open the user’s calendar at a specific date and time, e.g. to check availability. This is done with the AppointmentManager.ShowTimeFrameAsync method. Here’s the call in the service:

public async static Task Open(DateTimeOffset dto, TimeSpan ts)
{
    await AppointmentManager.ShowTimeFrameAsync(dto, ts);
}

And here’s how the viewmodel calls the service:

private async void Open_Executed()
{
    var tomorrow = DateTime.Now.AddDays(1);
    var duration = TimeSpan.FromHours(24);
    await Calendar.Open(tomorrow, duration);
    Toast.ShowInfo("Your calendar app should be open now.");
}

This is the result at runtime:

calendar3

Creating a new appointment

All you need to do in your app to create an appointment … is create an Appointment. This is a very rich class that allows you to completely configure a calendar entry: date and time, location, description, sensitivity, recurrence, invitees, reminders and what not:

var appointment = new Appointment();
appointment.StartTime = DateTime.Now.AddDays(1);
appointment.Duration = TimeSpan.FromHours(1);
appointment.Subject = "Five Cents Session";
appointment.Location = "Lucy's psychiatric booth";
// Warning: you don't get an ID back with these:
// appointment.Invitees.Add(new AppointmentInvitee());
// appointment.Invitees[0].DisplayName = "Lucy van Pelt";
// appointment.Invitees[0].Address = "lucy@peanuts.com";
// appointment.Organizer = new AppointmentOrganizer();
// appointment.Organizer.DisplayName = "Lucy van Pelt";
// appointment.Organizer.Address = "lucy@peanuts.com";
appointment.Sensitivity = AppointmentSensitivity.Private;
appointment.BusyStatus = AppointmentBusyStatus.OutOfOffice;
appointment.Details = "I need to discuss my fear of the Kite-Eating Tree with someone I can trust.";
appointment.Reminder = TimeSpan.FromMinutes(15);

Adding an appointment to the calendar

When your app instantiates an appointment, it’s not in the calendar yet. This is done with a call to AppointmentManager.ShowAddAppointmentAsync. One of the parameters in this call is the rectangle “around which the operating system displays the Add Appointment UI”. That was useful in Windows 8 where that Appointment UI was a dialog. In Windows 10 the entire Calendar app is launched, so I guess that the rectangle parameter is just there for backward compatibility – and to annoy MVVM developers who are forced to deal with UI coordinates in a viewmodel Annoyed. The call opens an entry form in the calendar app. When the user saves the appointment, then a local identifier is returned.

Here’s the MVVM service code. When an identifier is returned, it is immediately added to a list that is roamed for the app:

public async static Task<string> Add(Appointment appt)
{
    var selection = new Rect(new Point(Window.Current.Bounds.Width / 2, Window.Current.Bounds.Height / 2), new Size());
    return await Add(appt, selection);
}

public async static Task<string> Add(Appointment appt, Rect selection)
{
    var id = await AppointmentManager.ShowAddAppointmentAsync(appt, selection, Placement.Default);
    AddAppointmentId(id);

    return id;
}

public static void AddAppointmentId(string appointmentId)
{
    if (String.IsNullOrEmpty(appointmentId))
    {
        return;
    }

    string ids = ApplicationData.Current.RoamingSettings.Values["AppointmentIds"] as string;
    if (String.IsNullOrEmpty(ids))
    {
        ids = appointmentId;
    }
    else
    {
        ids += ";" + appointmentId;
    }

    ApplicationData.Current.RoamingSettings.Values["AppointmentIds"] = ids;
}

warning Meetings are no Appointments

The Appointment class allows you to add an Organizer and Invitees. When you do this, then the appointment becomes a meeting. When you hit the ‘send’ button in the UI, then ShowAddAppointmentAsync return with an exception. This behavior is documented in the API:

calendar4

Here’s the call from the client viewmodel, including exception handling and notification:

try
{
    var appointmentId = await Calendar.Add(appointment);

    if (appointmentId != String.Empty)
    {
        this.OnPropertyChanged(nameof(AppointmentIds));
        Toast.ShowInfo("Thanks for saving the appointment.");
    }
    else
    {
        Toast.ShowError("You decided not to save the appointment.");
    }
}
catch (Exception ex)
{
    Log.Error(ex.Message, nameof(Add_Executed));
    Toast.ShowError("I'm not sure if this appointment was added.");
}

When you want to allow the user to fine tune the new Appointment in the Calendar app before saving, then you should call the AppointmentManager.ShowEditNewAppointmentAsync method. That makes the Calendar UI editable (at least on the phone – on the desktop it seems to be always editable). Here’s how adding a non-editable appointment looks like on the Windows Phone emulator:

calendar6

Showing, editing, and deleting an appointment

There are three things your app can do with a local identifier for an appointment:

The Calendar MVVM service in the sample app just passes these calls. Here’s the Display method:

public async static Task Display(string appointmentId)
{
    await AppointmentManager.ShowAppointmentDetailsAsync(appointmentId);
}

The Delete method is more complex, since it does exception handling and needs to update the roaming list of appointments. Oh, and it needs to hick up that rectangle again:

public async static Task<bool> Delete(string appointmentId, bool ignoreExceptions = false)
{
    var selection = new Rect(new Point(Window.Current.Bounds.Width / 2, Window.Current.Bounds.Height / 2), new Size());
    try
    {
        var success = await AppointmentManager.ShowRemoveAppointmentAsync(appointmentId, selection);
        if (success)
        {
            RemoveAppointmentId(appointmentId);
        }

        return success;
    }
    catch (Exception)
    {
        if (!ignoreExceptions)
        {
            throw;
        }
        else
        {
            RemoveAppointmentId(appointmentId);
            return true;
        }
    }
}

public static void RemoveAppointmentId(string appointmentId)
{
    var remainingAppts = AppointmentIds;
    remainingAppts.Remove(appointmentId);
    var newIds = string.Join(";", remainingAppts);
    ApplicationData.Current.RoamingSettings.Values["AppointmentIds"] = newIds;
}

And here’s one of the service calls in the view model:

private async void Delete_Executed()
{
    try
    {
        await Calendar.Delete(SelectedAppointmentId);
        this.OnPropertyChanged(nameof(AppointmentIds));
    }
    catch (Exception ex)
    {
        Log.Error(ex.Message, nameof(Delete_Executed));
        Toast.ShowError("I'm not sure if the appointment was deleted.");
    }
}

Here’s the UI – which is always similar: the Calendar app is opened op top of your app.

calendar5

warning Replacing is not Editing

When you modify an appointment (change data or reschedule) that was created with your app, the local identifier remains the same. Even if you edit that appointment from another device. A call to AppointmentManager.ShowReplaceAppointmentAsync, however, will return a brand new identifier value when you changed the appointment. It will return null if you didn’t modify the appointment. After all, the method is not called ShowEditAppointmentAsync

Some final remarks

The Universal Windows 10 Platform Calendar API is an improvement over the Windows 8.1 Universal App version, in the sense that it’s finally Universal: the API is the same for all device types. There is however still some room for improvement.

  • The only thing that your app really knows about a appointment that it created, is its identifier. It’s not possible to get the details of an appointment. I may have missed something, but unless you start creating custom calendars the following code –against existing API’s- doesn’t work:

var store = await AppointmentManager.RequestStoreAsync(AppointmentStoreAccessType.AppCalendarsReadWrite);
var appt = await store.GetAppointmentAsync(appointmentId);
  •  I can’t confirm that the roaming works (simply because I don’t have enough hardware to test it out). The Windows 8.1 documentation consistently described the appointment identifiers as ‘device specific’ (so it did not make sense to roam these). That mention is gone now, and the comments in the code samples in the new documentation seem to suggest that the identifiers may be used from other devices. That would be absolutely nice, but –as I already stated- I can’t confirm it yet. By the way, Appointment comes with a read/write RoamingId property. But when I assign a value to, I get an exception.

Code

The entire source code for the sample app is here on GitHub. If you want another working example, then check out the official Appointment Calendar Sample by Microsoft.

Enjoy!

XAML Brewer

Extend your UWP apps with Lua scripting

Sometimes we need an app to be updated, extended, patched, or customized in unexpected ways and we don’t want to redeploy a new version of it. In the strongly typed world –especially the one in which Reflection.Emit() is not available- that generally requires some kind of scripting infrastructure. The app will be extended by adding flat files to it that may come from anywhere (mail, disk drive, web service, in app purchase, or manual input). So we have to invent a scripting language and build a parser. In my (long) career I’ve done that a couple of times: designing a scripting languages with a parser and a way to serialize and deserialize scripts to and from XML or JSON.

Well, these days are over. Thanks to Lua and MoonSharp.

The Lua scripting language

Lua is a programming language, originally designed for extending software applications to meet an increasing demand for customization. It provides the basic facilities of most procedural programming languages. Complicated or domain-specific features are not included; instead, it includes mechanisms for extending the language, allowing programmers to implement such features. It is used in Adobe products, Mercedes cars, MediaWiki sites, space vehicles, and Angry Birds. There���s a much longer list right here. For more details on the language, check this crash course, a lot of sample code, and even a whole book.

The MoonSharp interpreter

MoonSharp is a Lua interpreter that is written entirely in C#. It runs on .NET 3.5, .NET 4.x, Mono, Xamarin, Unity3D, and PCL compatible platforms. It has a very lightweight API and no external dependencies. The supported syntax covers 99% of Lua 5.2. The intention is NOT to reach 100%, allow me to quote from the MoonSharp rationale:

The purpose is offering scripting facilities to C# apps at the fastest speed possible. The entire purpose of MoonSharp is to sacrifice Lua raw execution speed in order to gain performance on Lua/C# cross calls. Lua serves the dual purpose of being a stand-alone language AND an embeddable scripting language. MoonSharp takes choices which favors the embeddable scenario at the expense of the stand-alone one.

So the focus lies on extending apps, and MoonSharp does this through

  • easy and fast interop with CLR objects,
  • interop with methods, extension methods, overloads, fields, properties and indexers,
  • interop with async methods,
  • easy to use error handling (script errors are thrown as .NET exceptions),
  • and much more.

For those who want an overview: the per-platform list of features that is covered by MoonSharp is right here.

There is a NuGet package available, but it does not yet contain Windows 10 dll’s. So I cloned the source, added the Windows 10 target to the Portable Class Library project, and recompiled everything. The new dll runs on the Universal Windows Platform, so now we can run Lua scripts from apps on the desktop, tablet, phone, x-box, surface hub, hololens, MS drone and MS car. With that new dll in hand, it was time to build a sample app. That app is built as a playground: it allows you to type in and execute some Lua scripts yourself.

Running MoonSharp on the Universal Windows Platform

All you need to do is add a reference to the PCL dll (I put it in the Libs folder of my Visual Studio solution). In the very near future it will most probably suffice to just add the NuGet package to your app.

Evaluating Lua expressions from C#

Here’s the first page of the sample app. It allows you to type in any Lua expression, and evaluate it:

LuaExpression

The source code is strikingly simple (Expression is the input text box, Result is the text block that displays the result):

var script = "return " + Expression.Text;

try
{
    // Run the script and get the result.
    DynValue result = Script.RunString(script);

    Result.Text = result.ToString();
}
catch (Exception ex)
{
    Result.Text = ex.Message;
}

We just create an executable chunk of Lua by prefixing it with “return”, and run it through the Script class. The result is returned as an instance of the DynValue class, which represents all data structures that are marshalled between Lua and C#.

Calling Lua functions from C#

Let’s take it one step further, and define a function with parameters, call it, and get the result back:

LuaFunction

Here’s the source code for this scenario (Chunk is the input text box – Chunk is also the name for the unit of compilation in Lua):

string scriptCode = "function f(a,b) " + Chunk.Text + " end";

var script = new Script();

try
{
    script.DoString(scriptCode);

    DynValue luaFunction = script.Globals.Get("f");

    // Type conversion for the parameters is optional
    DynValue res = script.Call(
                            luaFunction, 
                            DynValue.NewString(ParameterA.Text).CastToNumber(), 
                            Double.Parse(ParameterB.Text));

    // Check the return type.
    if (res.Type != DataType.Number)
    {
        throw new InvalidCastException("Invalid return type: " + res.Type.ToString());
    }

    // Type conversion swallows exceptions.
    Result.Text = res.Number.ToString();
    // Result.Text = res.CastToNumber().ToString();
}
catch (Exception ex)
{
    Result.Text = ex.Message;
}

Again we only need the Script and the DynValue classes: Script to ‘compile’ the script and call it, and DynValue to do the marshalling and type casting.

Calling C# functions from Lua

As already mentioned, MoonSharp focuses on interoperability. You can expose C# methods –even asynchronous ones- to the interpreter and have these called by Lua scripts. The sample app defines the following two methods:

public async static void Say(string message)
{
    var d = new MessageDialog(message);
    await d.ShowAsync();
}

public static string Reverse(string tobereversed)
{
    char[] charArray = tobereversed.ToCharArray();
    Array.Reverse(charArray);
    return new string(charArray);
}
Here’s what happens when you run a Lua script that calls these methods (print is a Lua function that writes to the output stream):

C#Function

Here’s the full script. You expose C# methods to a Lua script by adding a delegate to the global script environment:

string scriptCode = Chunk.Text;

Script script = new Script();

try
{
    // Expose the C# methods.
    script.Globals["say"] = (Action<String>)(Say);
    script.Globals["reverse"] = (Func<String, String>)(Reverse);

    script.DoString(scriptCode);

    Result.Text = "done";
}
catch (Exception ex)
{
    Result.Text = ex.Message;
}

Sharing C# objects to Lua

You can not only register methods to the Lua environment, but also whole instances of classes. The sample app contains a –simple- business object:

public class BusinessObject
{
    private double vatRate = 20.0;

    public double VatRate
    {
        get { return vatRate; }
        set { vatRate = value; }
    }

    public Double CalculateVAT(double amount)
    {
        return amount * vatRate / 100;
    }
}
Here’s a screenshot of a running Lua script that accesses an instance of this class:

ObjectSharing

The types that can be accessed by the Lua environment must be registered – you definitely want to be in control of that. One option is to decorate the class with an attribute:

[MoonSharpUserData]
public class BusinessObject
{
    // ...
}

and then call RegisterAssembly to register all decorated types in the assembly:

UserData.RegisterAssembly();

Unfortunately that didn’t work for me, not in UWP and not in WPF.

Here’s how to explicitly register a type (the attribute is not needed for this to work):

UserData.RegisterType<BusinessObject>();

By the way, here’s the lazy (and potentially dangerous) way to expose the whole C# and .NET environment to Lua:

UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;

Sharing instances of these classes is done the same way as sharing methods – by adding these to the global script environment:

var obj = UserData.Create(new BusinessObject());

// Actually, this also works:
// var obj = new BusinessObject();

script.Globals["obj"] = obj;

// Alternatively:
//script.Globals.Set("obj", obj);

The script can now access the obj instance: fields, properties, methods, events. MoonSharp supports extension methods, asynchronous calls, byRef parameters, indexers, operators, … basically everything. You can even alter the visibility of class members to make private members accessible to Lua scripts or hide sensitive public members from it.

Event Handling

For the last scenario in this introduction –and in the sample app- I decorated the BusinessObject with an event and a helper method to call it:

public event EventHandler SomethingHappened;

public void RaiseTheEvent()
{
    if (SomethingHappened != null)
        SomethingHappened(this, EventArgs.Empty);
}

Here’s how a Lua script registers and unregisters its own event handler to this event, and the result of raising the event from within the script and from C#:

EventHandling

The source code should look very familiar now. We just need an extra registration of the EventArgs type. Here’s the complete code for this scenario:

string scriptCode = Chunk.Text;

// Register types to be used in the script.
UserData.RegisterType<BusinessObject>();
UserData.RegisterType<EventArgs>();

Script script = new Script();

try
{
    var obj = UserData.Create(bus);
    script.Globals.Set("obj", obj);

    script.DoString(scriptCode);

    Result.Text = "done";
}
catch (Exception ex)
{
    Result.Text = ex.Message;
}

Honestly: I am impressed with this.

Visual Studio Support

The next step is to dive deeper into the Lua language itself, and start writing some test scripts (.lua files) in Visual Studio. Well, you can extend VS 2012/2013 and 2015 with Babelua. This extension comes with code highlighting, auto-completion, syntax checking, formatting, file previewing, and debugging capabilities. Here’s a screenshot Babelua in action. And yes, MoonSharp executes this script –based on the mentioned crash course- perfectly:

BabeLua

The Source

As usual the sample app is on GitHub. It’s an app for the Universal Windows Platform. The screenshots in this article were taken from the desktop, but it also runs on the phone:

PhoneVersion

Enjoy!

XAML Brewer

User input validation with Prism and data annotations on the UWP

Captain’s blog, stardate 2015.09.30. All the crew's Tricorders were successfully upgraded to Windows 10. We are eager to continue to seek out new life and new civilizations. At the moment, the registration app for new intelligent life forms is being rewritten for the Universal Windows Platform. Here’s how the prototype looks like:

 PrismValidation

As you see, the app is complaining whenever the user types or selects an illegal value in one of the input controls. Here's how we do this.

The System.ComponentModel.DataAnnotations members

The engineering team of the .NET core put the old System.ComponentModel namespace in it. This namespace hosts the classic series of Data Annotations - a set of attributes that apply to properties of models and describe validation rules. Here’s a list of data annotations that may be useful in UWP apps. The names speak for themselves:

  • Required
  • CreditCard
  • EmailAddress
  • PhoneNumber
  • Range
  • MinLength
  • MaxLenght
  • RegularExpression
  • Enumeration
  • URL

These attributes go back a long time: classes such as ScaffoldColumn and UIHintAttribute were created for ASP.NET WebForms (the Dynamic Data feature in Visual Studio 2008). Later these annotations were used in the validation infrastructure for the Entity Framework (that’s were the attributes like Key, Association, ConcurrencyCheck and DisplayColumn come from). In the current era, data annotation attributes are often referred to as MVC Validation. But –as already recorded- they’re available for the Universal Windows Platform now. Here’s an example of using some of the out-of-the-box data annotations in a viewmodel. The Name property should be filled, and the Location should consist of a Quadrant (A, B, C, or D) plus a Sector (2 to 5 digits), so they're decorated with a [Required] and a [RegularExpression] respectively:

[Required(ErrorMessage = "Name is required.")]
public string Name
{
    get { return name; }
    set { SetProperty(ref name, value); }
}

[RegularExpression(@"[ABCD]\d{2,5}", ErrorMessage="Location is Quadrant (A -> D) and Sector (2 -> 5 digits)")]
public string Location
{
    get { return location; }
    set { SetProperty(ref location, value); }
}

The Prism 6 validation infrastructure

Just putting this code in your UWP app is like sending the first away team to a newly discovered planet: nothing will return. The data annotations are part of the class definition, but at runtime there’s actually nothing looking at them. UWP lacks the infrastructure to listen for property changes and immediately validate the new values against the rules that were defined by the attributes. That infrastructure is defined, it's called the Validator, and a corresponding class exists on the UWP. But it only serves as a base class, waiting for your own implementation. So there is room for an engine, but no actual engine.

Well, here's the good news: the UWP Prism 6 team has built us a Warp Drive. It's called the BindableValidator. It applies validation rules that are encoded as data annotation attributes on the entities’ properties. That's just what we were looking for. You’ll need two beam up two NuGet packages to get the entire infrastructure on board: the Prism.Core and Prism.Windows packages.

Prism6Core

That was the good news, here's the bad news: the Prism.Windows package is still in the spacedock - not officially released. Now I'm not known for my patience, so I copied the source –we have replicators- of the relevant classes directly into the sample app. Here’s an overview of these classes:

  • BindableBase: an implementation of INotifyPropertyChanged.
  • BindableValidator: runs validation rules of an entity, and stores a collection of errors of the properties that did not pass validation.
  • IValidatableBindableBase: describes validation support for (view)model classes that contain validation rules.
  • ValidatableBindableBase: a default implementation of IValidatableBindableBase.

You hook into this validation framework by letting your viewmodels implement the IValidatableBindableBase interface. The easiest way to do do that is to inherit from ValidatableBindableBase:

internal class CivilizationViewModel : ValidatableBindableBase
{
    // ...
}

Your class now gets an Errors property, which actually refers to the validator itself. The validation is run on each property change or whenever the ValidateProperties method is called. The Validator also provides an indexer property, that uses the property names as keys and the error list for each property as values. That’s a complex structure, but the XAML syntax allows us to use indexes in binding expressions. Here’s how Starfleet’s new app binds a textbox to the Name property, and a textblock to the first error in its corresponding error list:

<TextBox Text="{Binding Name, Mode=TwoWay}"
         Header="Name" />
<TextBlock Text="{Binding Errors[Name][0]}"
           Foreground="Red"
           HorizontalAlignment="Right" />

Whenever the Name property is changed (by the user through the TextBox, or programmatically), it is validated. If it’s not filled, then Errors[Name] will be updated and appear in the TextBlock. Fascinating.

If you prefer a central errors summary somewhere on the page, then just bind an ItemsControl to Errors.Errors:

<ItemsControl x:Name="ErrorList"
              ItemsSource="{Binding Errors.Errors}" />

This is the blue list at the bottom of the app's page.

Building a custom property validator

The list of out-of-the-box validation rules is short, but it’s easy to create your own validation attributes: all you need is to subclass ValidationAttribute and provide an implementation for the IsValid method. Here’s a sample NumericAttribute that checks whether the input can be mapped to an integer value:

/// <summary>
/// Sample custom validation for Integer values.
/// </summary>
public class NumericAttribute: ValidationAttribute
{
    public override bool IsValid(object value)
    {
        // The [Required] attribute should test this.
        if (value == null)
        {
            return true;
        }

        int result;
        return int.TryParse(value.ToString(), out result);
    }
}

Here’s how the attribute is used in the viewmodel of the New Civilization Registration Form:

[Numeric(ErrorMessage = "Population should be numeric.")]
public string EstimatedPopulation
{
    get { return estimatedPopulation; }
    set { SetProperty(ref estimatedPopulation, value); }
}

Observe that the property in that viewmodel is of type String, not Integer. You have to make sure that the binding between the property and the textbox's text in the view doesn’t break.

Comparing two properties

Data annotations are set at property level. What if you want to compare two properties, e.g. to validate a date range? Out of the box, there is only one attribute that compares two properties: Compare. Unfortunately it only checks for equality of two values. You can use it to verify the confirmation of passwords or email addresses.

Here's an example of a validation attribute that compares two DateTime properties, and verifies whether it is a valid range (the validated DateTime should be later than the other one). That 'other' property's name is stored in a property, and looked up at validation time through reflection.Logically speaking, the property with the attribute is compared to the property in the attribute:

/// <summary>
/// Checks whether a DateTime is later than another Property.
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class LaterThanPropertyAttribute : ValidationAttribute
{
    string propertyName;

    public LaterThanPropertyAttribute(string propertyName)
    {
        this.propertyName = propertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext obj)
    {
        if (value == null)
        {
            return ValidationResult.Success;
        }

        var propertyInfo = obj.ObjectInstance.GetType().GetProperty(this.propertyName);

        if (propertyInfo == null)
        {
            // Should actually throw an exception.
            return ValidationResult.Success;
        }

        dynamic otherValue = propertyInfo.GetValue(obj.ObjectInstance);

        if (otherValue == null)
        {
            return ValidationResult.Success;
        }

        // Unfortunately we have to use the DateTime type here.
        //var compare = ((IComparable<DateTime>)otherValue).CompareTo((DateTime)value);
        var compare = otherValue.CompareTo((DateTime)value);

        if (compare >= 0)
        {
            return new ValidationResult(this.ErrorMessage);
        }

        return ValidationResult.Success;
    }
}

Unfortunately I had to use the DateTime type in the code. If you want to compare two integers, then you have to create a new class…

Here’s how the attribute is used to check if the date that a new civilization joined Starfleet comes after the date that it was discovered:

[LaterThanPropertyAttribute("DiscoveryDate", ErrorMessage="Affiliation date should come after date of first contact.")]
public DateTime MembershipDate
{
    get { return membershipDate; }
    set { SetProperty( ref membershipDate, value); }
}

Observe that this rule is defined on MembershipDate, so it is NOT triggered when the user changes the DiscoveryDate. If you want this to happen, then you have to hook up the validation call in the property’s setter:

public DateTime DiscoveryDate 
{ 
    get { return discoveryDate; } 
    set 
    { 
        SetProperty(ref discoveryDate, value); 

        // This is the right way to link property validations. 
        Errors.ValidateProperty("MembershipDate"); 
    } 
} 

What if you want to use more than two properties in a validation rule (like “the date that a new civilization joined Star Fleet should come after the date that it was discovered, unless they are time travelers”)? Well, technically it’s possible, but your source code would look more like Klingon than C#. We're close to the limits of the property-based validation infrastructure here. If you want more (like comparing with properties of other viewmodels), then you’re in for a Kobayashi Maru [that means: you have to change the source code]. Anyway, by modifying the BindableValidator or by creating a brand new one, you will be able to boldly go where no man has gone before. The current Prism infrastructure provides a solid base for that.

The code

The source code of the sample app is here on GitHub. At this moment it contains a copy of some source files of Prism 6. I will remove these when the official NuGet packages are released.

Live long and prosper!

XAML Brewer

Using Lex.Db on the Universal Windows Platform

This article explains how to get started with Lex.Db on the Universal Windows Platform. Lex.Db is a file-based database written in .NET by Lex Lavnikov as a fast, light-weight alternative for SQLite. It does not require you to install a Visual Studio Extension on your development machine, to reference C++ libraries, or to separately compile your app for each target platform. Lex.Db runs on any .NET flavor:

  • Universal Windows 10 Platform
  • Xamarin.iOS & Xamarin.Android
  • Universal Windows Store 8.* Apps
  • .NET 4.*
  • Silverlight 5.*
  • Windows Phone 8.*
  • WinRT.

For more info, check the official documentation and the author’s blog.

As usual, I wrote a small sample app. It started with a copy of my previous sample app on SQLite. Obviously the data access layer was changed, but I also modified the CoverFlow-based UI to better deal with landscape oriented pictures. The menu at the left hand side is visually inspired by the SplitView Pane in compact mode, but it’s just the first column of the page’s main grid:

AppBrowse

Lex.Db comes to you through NuGet:

LexDbNuget

The Lex.Db namespace has a small number of classes in it. The DbTableAsync class hosts the asynchronous table calls:

LexDbNamespace

Here’s a class diagram of the two main classes – representing a database instance and a table:

LexDb

With Lex.Db you define your entities in C# and then create a table for each type. Attributes are not supported, so we start with a POCO class. Here’s my definition of a VintageMuscleCar:

/// <summary>
/// Represents a vintage muscle car.
/// </summary>
public class VintageMuscleCar
{
    /// <summary>
    /// Gets or sets the identifier.
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Gets or sets the name.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets the description.
    /// </summary>
    public string Description { get; set; }

    /// <summary>
    /// Gets or sets the day of birth.
    /// </summary>
    public DateTime ReleaseDate { get; set; }

    /// <summary>
    /// Gets or sets the picture.
    /// </summary>
    /// <remarks>Is a blob in the database.</remarks>
    public byte[] Picture { get; set; }
}

Every table is stored as two files (data and index). Each time your app starts up, you have to tell to Lex.Db where the files are and what they represent:

private static DbInstance db;

static Dal()
{
    // Create database
    db = new DbInstance("Storage", ApplicationData.Current.RoamingFolder);

    // Define table mapping
    // * 1st parameter is primary key
    // * 2nd parameter is autoGen e.g. auto-increment
    db.Map<VintageMuscleCar>().Automap(p => p.Id, true);

    // Initialize database
    db.Initialize();
}

Here’s the code to clear and repopulate the VintageMuscleCar table. For this kind of operations, Lex.Db provides some extra-fast operators like Purge, BulkRead, and BulkWrite:

public async static Task ResetCars()
{
    // Clear
    db.Purge<VintageMuscleCar>();

    // Repopulate
    var cars = await Dal.DefaultCars();
    await Dal.SaveCars(cars);
}

public async static Task<List<VintageMuscleCar>> DefaultCars()
{
    var cars = new List<VintageMuscleCar>();

    var car = new VintageMuscleCar();
    car.Name = "1965 Corvette C2 Stingray";
    // (... more properties ...)
    cars.Add(car);

    car = new VintageMuscleCar();
    car.Name = "1965 Pontiac GTO";
    // (... more properties ...)
    cars.Add(car);

    // More cars...

    return cars;
}

Lex.Db also comes with overloads for all CRUD operators that take a list instead of a single entity. Here’s the rest of the Dal.cs class from the sample app, illustrating some quintessential database calls:

public static IEnumerable<VintageMuscleCar> GetCars()
{
    return db.Table<VintageMuscleCar>();
}

public static VintageMuscleCar GetCarById(int id)
{
    return db.Table<VintageMuscleCar>().LoadByKey(id);
}

public static int SaveCar(VintageMuscleCar car)
{
    db.Table<VintageMuscleCar>().Save(car);
    return car.Id;
}

public async static Task SaveCars(IEnumerable<VintageMuscleCar> cars)
{
    await db.Table<VintageMuscleCar>().SaveAsync(cars);
}

public async static Task<int> DeleteCars(IEnumerable<VintageMuscleCar> cars)
{
    return await db.Table<VintageMuscleCar>().DeleteAsync(cars);
}

Here’s the sample app in Edit-mode:

AppEdit

Its source code lives on GitHub, it was written with Visual Studio 2015.

Enjoy!

XAML Brewer

Using SQLite on the Universal Windows Platform

This article explains how to get started with SQLite in an UWP XAML app. SQLite is a cross-platform single-user public-domain (read: ‘free’) embedded relational database engine. It doesn’t require a server and it doesn’t require configuration, but it still provides all essential relational database features including SQL syntax, transactions, indexes, and even common table expressions. I created an UWP sample app that

  • creates and populates a new SQLite database, and
  • demonstrates all SQL CRUD operations: select, insert, update, and delete, and
  • is a more or less representative for a business app.

Here’s how the app looks like in browse mode:

SQLite_Browse

Before you can use SQLite in a UWP app, you need to install the VSIX package for Universal App Platform development using Visual Studio 2015 from the SQLite download page:

DownloadSqLiteVsix

Then add a reference to the engine and to the C++ runtime on which it depends (Visual Studio will warn you if you forget the latter):

AddSqLiteReference

Your code now has access to the SQLite engine, but it makes sense to install a .NET wrapper to facilitate this. At the time of writing this article, it looks like most of the Windows 8.1 wrappers on NuGet are broken. The problems are caused by changes in NuGet. In NuGet 3.1 a package cannot add source code files to a project anymore. The original SQLite.NET package uses this feature, so it cannot be used in Visual Studio 2015. Fortunately a spin-off from this package, the SQLite.NET PCL package and also its asynchronous version still do the trick:

SqLiteNetPclNuget

SQLite.Net-PCL exposes a rich API to your code:

SQLite_ObjectModel

Here’s the entire signature of the SQLiteConnection class:

ClassDiagram

The SQLiteConnection constructor takes the platform type and the path to the file that hosts the database. Here’s how the methods in the data access layer of sample app get a connection:

private static SQLiteConnection DbConnection 
{ 
    get 
    { 
        return new SQLiteConnection(
            new SQLitePlatformWinRT(), 
            Path.Combine(ApplicationData.Current.LocalFolder.Path, "Storage.sqlite"));
    } 
}

For debugging and/or auditing, you can assign a TraceListener to the connection. It will expose all SQLite related messages:

// Create a new connection 
using (var db = DbConnection) 
{
    // Activate Tracing 
    db.TraceListener = new DebugTraceListener(); 
    // Database stuff.
    // ...
}

You just need to implement the ITraceListener interface. Here’s the listener in the sample app that sends all SQLite info to the Debug window:

/// <summary> 
/// Writes SQLite.NET trace to the Debug window. 
/// </summary> 
public class DebugTraceListener : ITraceListener 
{ 
    public void Receive(string message) 
    { 
        Debug.WriteLine(message); 
    } 
}

The code-first approach works very well in SQLite: the easiest way to create tables is by first defining your model classes. I created a Person class, with some properties of simple atomic data types, but also some more challenging data types: a Picture (a Blob in the database, a byte array in the model, an ImageSource in the viewModel) and a DateTime (a typical show stopper in many cross platform environments). The model class members are decorated with attributes to indicate keys, value generation algorithms, and validation constraints:

internal class Person
    {
        /// <summary>
        /// Gets or sets the identifier.
        /// </summary>
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        [MaxLength(64)]
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Gets or sets the day of birth.
        /// </summary>
        public DateTime DayOfBirth { get; set; }

        /// <summary>
        /// Gets or sets the picture.
        /// </summary>
        public byte[] Picture { get; set; }
    }

To create the table, just call … CreateTable … and provide the model type. For those who want to inspect the table structure programmatically, GetMapping reveals the entire table definition (columns, keys, indices, mappings):

// Create the table if it does not exist 
var c = db.CreateTable<Person>(); 
var info = db.GetMapping(typeof(Person));

Records can be saved to the table by InsertOrReplace. The Id property was set to AutoIncrement, so it’s not mandatory for new records. But you can provide a value if you want. This is what I do in the initial load of the table:

// Populate the database
Person person = new Person();
person.Id = 1; 
person.Name = "Sean Connery"; 
// (more property assignments here) 
var i = db.InsertOrReplace(person);

Here’s the code behind the Save button of the sample app – the Insert method will generate the primary key of the new record:

// Save a Person (from UI)
if (person.Id == 0) 
{ 
    // New 
    db.Insert(person); 
} 
else 
{ 
    // Update 
    db.Update(person); 
}

Records can be selected using LINQ. You don’t have to know the table names, Table<T>() returns the table in which you store entities of type T:

// Retrieve all Persons
List<Person> people = (from p in db.Table<Person>() 
                       select p).ToList();
// Fetch a Person by Id
Person m = (from p in db.Table<Person>() 
            where p.Id == Id 
            select p).FirstOrDefault();

Finally, the Delete method can be called to remove records. If you want, you can use SQL syntax for all operations, instead of working with model instances:

// Delete a Person
// Using the object model: 
db.Delete(person); 
 
// Using SQL syntax: 
db.Execute("DELETE FROM Person WHERE Id = ?", person.Id);

All SQLite related code in the sample app is consolidated in the Dal.cs class. The rest of the app tries to mimic a MVVM business app. Here it is in Edit mode, with all TextBlocks replaced by TextBoxes, DatePicker, and Buttons that open FilePickers:

SQLite_Edit

There’s a converter between the DatePicker’s Date property (of type DateTimeOffset) and the Person’s DayOfBirth (of type DateTime). If you don’t do that, then the user’s time zone is taken into account, and that can give nasty surprises:

public class DateTimeToDateTimeOffsetConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            try
            {
                DateTime date = (DateTime)value;
                return new DateTimeOffset(date);
            }
            catch (Exception ex)
            {
                return DateTimeOffset.MinValue;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            try
            {
                DateTimeOffset dto = (DateTimeOffset)value;
                return dto.DateTime;
            }
            catch (Exception ex)
            {
                return DateTime.MinValue;
            }
        }
    }

To make the date of birth independent from the time zone (which it actually isn’t), all programmatically created DateTime values are defined using the UTC format:

person.DayOfBirth = new DateTime(1930, 8, 25, 0, 0, 0, DateTimeKind.Utc);

Otherwise -on my machine- a value of DateTime(2015, 25, 12) would appear as ‘24 DEC 2015’ after the subtraction of one hour for the time zone and one hour for daylight savings time. That’s the kind of confusion you want to avoid, I guess. Anyway, here’s how the UWP DatePicker looks like on a tablet:

SQLite_DatePicker

That’s it. As you see, SQLite is feature rich and easy to use on any platform, including the Universal Windows Platform.

As usual, the source code of the sample app lives on GitHub. It was written in Visual Studio 2015.

Enjoy!

XAML Brewer

A CoverFlow control for the Universal Windows Platform

In this article I present a UWP implementation of a CoverFlow control. CoverFlow is an animated, 3D graphical user interface to browse through a list of visual items. Here's how it looks like:

CoverFlowScreenshot

It’s implemented as an ItemsControl, so all you need to do is give him an ItemsSource and an ItemTemplate.

 

History

CoverFlow is an example of skeuomorphic design, it’s look-and-feel is based on a physical object: the sleeve display of a jukebox.

SleeveDisplay 

 

It was designed by Andrew Coulter Enright, you can get more info on the design process on his old blog. Here’s the designer’s opinion on the interface:


Not only does it convey more information in the less space, it makes the information presented easier to understand. Additionally amazing, this natural and subtle visual trick requires a minimal amount of processing, as it employs 2D effects to create the illusion of a 3D space.

The CoverFlow design was bought by Apple, who used it in iTunes, Safari and other products for visually flipping through snapshots of documents, website bookmarks, album artwork, or photographs.
Apple was granted a design patent on the Cover Flow interface. Here’s an illustration out of that patent:

CoverFlowPatent

In 2009, a SilverLight version of a CoverFlow control –together with a complete iTunes movie browser sample app- appeared on CodePlex. Jeff Prosise migrated this to the WinRT platform, and added touch manipulation in the process. The UWP version that I present here, is derived from these two implementations.


The design has not been very popular in the Windows world: 3D effects with gradients and shadows in a skeuomorphic design were considered very un-Metro. But in the iOS and Android world, it’s still popular – although Apple itself don’t use it anymore. Also in web sites, you very often encounter a CoverFlow UI. For the sake of completeness, you find a JQuery and CSS implementation here.

Anyway, the CoverFlow design is universal and platform neutral. On top of that, it scales to any dimension – just start the sample app, and resize it to whatever height and width. You’ll notice that the control looks good at any size; no visual state triggers needed for this one:

CoverFlowScreenshotNarrow  

Manipulation

You can browse through the items by using

  • the keyboard: arrows, home and end key, etc.
  • the mouse scroll wheel,
  • touch manipulation: horizontal translation, and/or
  • binding its SelectedIndex dependency property to another control, such as a Slider.

Look & feel

The sample app just shows the control with its default UI settings, but you can do quite some tweaking. You can configure
  • the space between items,
  • the space between the selected item and the other items,
  • the angle non selected items are at,
  • the depth of non selected items,
  • the scale of non selected items,
  • the duration it takes to switch selected item,
  • the easing function of the animations, and
  • the sensitivity of touch manipulation, i.e. the number of pixels to slide before a new item is selected.

Usage

As already mentioned, CoverFlow is just an ItemsControl. Here’s how it’s defined in the sample app. The slider is not part of the control itself, but the CoverFlow exposes a SelectedIndex property (as well as a SelectedItem property) you can bind to:

<!-- CoverFlow --> 
<controls:CoverFlow x:Name="CoverFlow"> 
   <controls:CoverFlow.ItemTemplate> 
       <DataTemplate> 
           <Image Source="{Binding}" /> 
       </DataTemplate> 
   </controls:CoverFlow.ItemTemplate> 
</controls:CoverFlow> 
 
<!-- Slider --> 
<Slider Value="{Binding SelectedIndex, ElementName=CoverFlow, Mode=TwoWay}" />

In the sample app, the ItemsSource is assigned in code behind, but the control is not afraid of data binding. Don’t forget to update the slider’s maximum value:

CoverFlow.ItemsSource = await GetUrls(); 
Slider.Maximum = CoverFlow.Items.Count() - 1;

Source

The control and sample app live on GitHub. The solution was written with Visual Studio 2015.

Enjoy!

XAML Brewer

An ImageCropper control for the Universal Windows Platform

This article introduces an image cropping XAML control for UWP that

  • is populated through a SourceImage dependency property, of type WriteableBitmap,

  • has a templatable UI that allows you to select a region by

    • dragging a corner,

    • dragging the entire selection, and

    • scaling the selection through a pinch gesture,

  • exposes the result as a CroppedImage dependency property, of type WriteableBitmap, and

  • provides helper methods to load and save a WriteableBitmap from and to different image formats.

The sample app shows how to use the control, restyle the control, and capture an image from the camera. Here’s a screenshot of it. It shows the control in its default UI on the left, and the cropped image on the right:

CropperNative

This control is an upgrade of the Windows RT version that I wrote a couple of years ago, with some improvements and bug fixes.

 

Default usage

To use the control, all you need to do is drop it on a page:

<controls:ImageCropper x:Name="ImageCropper" />

It will look like a dull grey rectangle, until you assign a value to its SourceImage property. Here’s how to do that through a file picker (note that the LoadAsync extension method comes with the package):

FileOpenPicker openPicker = new FileOpenPicker();
// ... picker config ...
StorageFile imgFile = await openPicker.PickSingleFileAsync();
if (imgFile != null)
{
    var wb = new WriteableBitmap(1,1);
    await wb.LoadAsync(imgFile);
    this.ImageCropper.SourceImage = wb;
}

The ImageCropper will now show the image, and the UI elements that allow you to select and highlight a region. That selected region is exposed by the control as the CroppedImage property. This is also a WriteableBitmap, so you can use it as a source for an image control:

<Image x:Name="CroppedImage"
       Source="{Binding CroppedImage, ElementName=ImageCropper}"/>

Here’s how to save that cropped image to a file, again through a file picker (and again: the SaveAsync extension method comes with the package):

FileSavePicker savePicker = new FileSavePicker();
// ... picker config ...
var file = await savePicker.PickSaveFileAsync();
if (file != null)
{
    await (this.CroppedImage.Source as WriteableBitmap).SaveAsync(file);
}

All common image formats are supported: *.bmp, *.gif, *.jpg, *.png, *.tiff and more. 

 

Customizing the UI

The entire control is templatable, but the corner of the selected region is the ideal candidate for customization. If you don’t like the default ellipse, then you can go for a more angular look:

CropperTemplated

You have to provide only the template for the upper left corner, the control’s default style reuses it and applies a rotation. Here’s the code for the upper right corner:

<ContentControl ContentTemplate="{StaticResource CornerTemplate}"
                x:Name="PART_TopRightCorner"
                Tag="TopRightCorner"
                Canvas.Left="{Binding Path=BottomRightCornerCanvasLeft,Mode=OneWay}"
                Canvas.Top="{Binding Path=TopLeftCornerCanvasTop,Mode=OneWay}">
    <ContentControl.RenderTransform>
        <RotateTransform Angle="90" />
    </ContentControl.RenderTransform>
</ContentControl>

Here’s the custom template for the corner element. I’s a group of two RectangleGeometry instances, that is translated out of the selected region. Since these are hard to hit by touch, there’s a transparent ellipse on top of them:

<DataTemplate x:Key="CornerTemplate">
    <Grid>
        <Path Fill="{StaticResource ApplicationPageBackgroundThemeBrush}"
              Stroke="{StaticResource ApplicationForegroundThemeBrush}"
              StrokeThickness="0">
            <Path.Data>
                <GeometryGroup FillRule="Nonzero">
                    <RectangleGeometry Rect="0 0 8 40" />
                    <RectangleGeometry Rect="0 0 40 8" />
                </GeometryGroup>
            </Path.Data>
            <Path.RenderTransform>
                <CompositeTransform TranslateX="-12"
                                    TranslateY="-12" />
            </Path.RenderTransform>
        </Path>

        <!--To get a better grip-->
        <Ellipse Height="40"
                  Width="40"
                  Fill="Transparent"
                  StrokeThickness="0">
            <Ellipse.RenderTransform>
                <CompositeTransform TranslateX="-12"
                                    TranslateY="-12" />
            </Ellipse.RenderTransform>
        </Ellipse>
    </Grid>
</DataTemplate>

 

Capturing the camera view

A common use case for this type of control is the selection of a portion of the image from a camera built into the device or attached to it. For this scenario, I placed a CaptureElement on top of the ImageCropper, to display the stream from the (back) camera:

<controls:ImageCropper x:Name="ImageCropper" />
<CaptureElement x:Name="CameraPreview" />

I refactored the code of the new Camera Preview Frame sample (see Credits) into a reusable MVVM-ish CameraService class. When the user navigates to the corresponding page, the service looks up the camera, configures it, and hooks its image stream to the CaptureElement:

private CameraService cameraService;

public CameraPage()
{
    this.InitializeComponent();

    cameraService = new CameraService(this.CameraPreview);
}

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    await cameraService.InitializeCameraAsync();
    base.OnNavigatedTo(e);
}

When the user takes the picture, a temporary file is created, and the current camera frame is saved to it. The file is then loaded again, and provided to the ImageCropper:

StorageFolder temp = ApplicationData.Current.LocalCacheFolder;
StorageFile file = await temp.CreateFileAsync("current_image.png", CreationCollisionOption.ReplaceExisting);

await cameraService.MediaCapture.CapturePhotoToStorageFileAsync(ImageEncodingProperties.CreateJpeg(), file);

file = null;
file = await temp.GetFileAsync("current_image.png");

var wb = new WriteableBitmap(1, 1);
await wb.LoadAsync(file);
this.ImageCropper.SourceImage = wb;

await cameraService.StopPreviewAsync();
this.CameraPreview.Visibility = Visibility.Collapsed;

[The file = null is necessary, to unlock the file between the overriding and the reading.]

Here’s the ImageCropper control cropping some flowers from my garden:

CameraCapture

 

Credits

The ImageCropper control was originally written according to the Hackathon Design Pattern: it was quickly assembled from different non-related resources on the Internet, just to win a device. But don’t worry: I took the time to refactor and debug it properly. Here are some of the resources:

 

Source Code

The control and the sample app live here on GitHub. The solution was written using Visual Studio 2015 RC, and then manually upgraded to Visual Studio 2015 RTM.

Enloy!

XAML Brewer

A lap around Adaptive Triggers

When you’re building a XAML app for the Universal Windows Platform (UWP) you’ll end up with just one package to be deployed to all the different Windows 10 devices. They’re all served with the same C# and the same XAML views. Fortunately XAML has been extended with a load of features to support adaptive/responsive design:

  • Native controls that adapt to the device,
  • the new RelativePanel control,
  • a new common navigation UI with the SplitView control,
  • extensions to the Visual State infrastructure with Adaptive Triggers and Property Setters, and as a last resort
  • XAML views per device.

I already covered the RelativePanel and SplitView controls, so let’s dive into Adaptive Triggers.

The new AdaptiveTrigger class is used in XAML to describe the conditions to move to a visual state. At runtime, the adaptive triggers are evaluated, and the most appropriate will determine the visual state. All of this happens without any code behind from your part.

An adaptive trigger comes with two properties: the minimum width and height of the app’s window to trigger the state change: MinWindowHeight and MinWindowWidth.

Here’s the list of trigger declarations from the small sample app that I wrote. I defined four visual states:

  • Wide: larger than 900 effective pixels,
  • Square: between 720 and 899 effective pixels,
  • Narrow: between 548 and 719 effective pixels, and
  • Snapped: less than 548 effective pixels.
<!-- Responsive Visual States -->
<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>

        <!-- VisualState to be triggered when window width is >=900 effective pixels -->
        <VisualState x:Name="Wide">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="900" />
            </VisualState.StateTriggers>
          
            <!-- Setters and Storyboards come here -->
            <!-- ... -->          

        </VisualState>

        <!-- VisualState to be triggered when window width is >=720 and <900 effective pixels -->
        <VisualState x:Name="Square">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="720" />
            </VisualState.StateTriggers>

            <!-- Setters and Storyboards come here -->
            <!-- ... -->  
        
        </VisualState>
                
        <!-- VisualState to be triggered when window width is >=548 and <720 effective pixels -->
        <VisualState x:Name="Narrow">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="548" />
            </VisualState.StateTriggers>

            <!-- Setters and Storyboards come here -->
            <!-- ... -->          
        
        </VisualState>

        <!-- VisualState to be triggered when window width is >=0 and <548 effective pixels -->
        <VisualState x:Name="Snapped">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>

            <!-- Setters and Storyboards come here -->
            <!-- ... -->          
    
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Of course it’s up to you to define your own boundaries. These depend on your app and on the devices that you target with it.

In the pre-UWP world, the content of a Visual State was one Storyboard that was executed when the control entered the corresponding state - generally through a call to VisualStateManager.GoToState in code behind. The UWP Visual State also comes with an optional storyboard, but also with a list of setters. That’s the same Setter that you know from within a Style definition. Basically it modifies the value of a property, without animation. The Setter is extended with a new property -Target- that contains the path to the property that you want to update, including the target element. It also works for any type of property, including attached properties.

If you had a hamburger button in your UI and wanted to hide it in a particular visual state, then this would do the trick:

<Setter Target="HamburgerButton.Visibility" Value="Collapsed" />

Which brings us to the sample app, which has a Shell with a SplitView, and a MainPage – reused from my SplitView sample.

 

Applying Visual States to a SplitView control

In the Wide state, I’m showing the splitview panel in full width and in Inline mode – not overlapping the content. The hamburger button does not add any value in that case, so I’m hiding it:

<!-- VisualState to be triggered when window width is >=900 effective pixels -->
<VisualState x:Name="Wide">
    <VisualState.StateTriggers>
        <AdaptiveTrigger MinWindowWidth="900" />
    </VisualState.StateTriggers>
    <VisualState.Setters>
        <!-- Keep SplitView pane always showing inline -->
        <!-- Hide the Hamburger, it's useless here -->
        <Setter Target="MySplitView.DisplayMode"
                Value="Inline" />
        <Setter Target="MySplitView.IsPaneOpen"
                Value="True" />
        <Setter Target="HamburgerButton.Visibility"
                Value="Collapsed" />
    </VisualState.Setters>
</VisualState>

The shell looks like this in Wide mode:

SplitView_1000

For the Square state, we just switch to Overlay mode. That saves 150 effective pixels. I also try to keep the pane open, but it collapses automatically on any screen resize, and there does not seem to be a way to keep it sticky. In overlay mode the user would want to close and reopen the menu, so we bring the hamburger button back. We don’t have to do anything for that: the adaptive trigger nicely undoes all the setters it executed. So we only need to update the splitview:

<VisualState.Setters>
    <!-- SplitView pane shows as overlay -->
    <!-- Splitview pane will close however :-( -->
    <Setter Target="MySplitView.DisplayMode"
            Value="Overlay" />
    <Setter Target="MySplitView.IsPaneOpen"
            Value="True" />
</VisualState.Setters>

And here’s the result:

SplitView_0850

Here are the setters for Narrow mode, we switch to Compact Inline mode, and keep the pane open:

<Setter Target="MySplitView.DisplayMode"
        Value="CompactInline" />
<Setter Target="MySplitView.IsPaneOpen"
        Value="False" />

Unsurprisingly, this is the result:

SplitView_0650

Al last we switch to back to Overlay mode, but we close the pane. I guess you have an idea now how the setters look like.

To allow the window to be resized to such a small size, I’ve overridden the minimum size in App.cs:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    // Override default minimum size.
    var view = ApplicationView.GetForCurrentView();
    view.SetPreferredMinSize(new Size { Width = 320, Height = 320 });
        
    // ...
}

Here’s the narrow screen:

SplitView_0350

 
Applying Visual States to a Relative Panel control

In the MainPage of the sample app I defined the same visual states and adaptive triggers as in the Shell. I’m using Setters to update regular properties:

<Setter Target="LinksPanel.Visibility"
        Value="Collapsed" />
<Setter Target="Title.FontSize"
        Value="36" />
<Setter Target="Title.Padding"
        Value="4" />

But I’m also moving elements around by updating the properties that were attached to them by the RelativePanel, using the parentheses syntax:

<Setter Target="Title.(RelativePanel.AlignLeftWith)"
        Value="Illustration" />
<Setter Target="Title.(RelativePanel.AlignBottomWith)"
        Value="Illustration" />
<Setter Target="Title.(RelativePanel.RightOf)"
        Value="" />
<Setter Target="Title.(RelativePanel.AlignTopWith)"
        Value="" />

The last two setters actually remove attached properties. That’s to avoid circular references in the elements’ positioning and to avoid concurrent alignments (more details in my Relative panel sample).

You’re not just stuck to the new setters inside a visual state, there’s still an optional storyboard available for the property changes that can be animated. Here’s an example of a full visual state from the sample app:

<VisualState x:Name="Narrow">
  <VisualState.StateTriggers>
    <AdaptiveTrigger MinWindowWidth="548" />
  </VisualState.StateTriggers>
  <VisualState.Setters>
    <!-- Make illustration smaller, place title in it, and description at the bottom. -->
    <!--<Setter Target="Illustration.MaxWidth"
                        Value="300" />-->
    <Setter Target="Illustration.Margin"
            Value="0" />
    <Setter Target="Title.(RelativePanel.AlignLeftWith)"
            Value="Illustration" />
    <Setter Target="Title.(RelativePanel.AlignBottomWith)"
            Value="Illustration" />
    <Setter Target="Title.(RelativePanel.RightOf)"
            Value="" />
    <Setter Target="Title.(RelativePanel.AlignTopWith)"
            Value="" />
    <Setter Target="Title.FontSize"
            Value="36" />
    <Setter Target="Title.Padding"
            Value="4" />
    <Setter Target="Description.(RelativePanel.Below)"
            Value="Illustration" />
  </VisualState.Setters>
  <Storyboard>
    <DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.MaxWidth)"
                      Storyboard.TargetName="Illustration"
                      Duration="0:0:0.5"
                      To="300"
                      EnableDependentAnimation="True" />
  </Storyboard>
</VisualState>
 
Defining Visual States in Blend

The new Blend 2015 will be an excellent tool for previewing and recording visual states. On the left you can see and modify the list the states, the center is a preview of the state, and at the right you can modify the properties that define the state:

BlendExperience

At the time of writing this article, Blend 2015 RC is not yet entirely ready for this. All property changes are recorded in the storyboard (not in setters), the attached properties don’t show up in the properties to the right. And if you already had setters in a visual state, they will be ruined. Blend apparently has an other idea of the Setter class than Visual Studio: it will remove your Target properties, and add an empty PropertyPath property. I’m assuming that this problem will disappear in –literally- just a couple of days from now.

 

The final results

Here’s how the sample app elegantly scales down.

Wide mode:

MainView_1000

Square mode:

MainView_0850

Narrow mode:

MainView_0650

 Snapped mode:

MainView_0350

In case you didn’t notice: I didn’t have to write a single line of C# for this, it’s all in the XAML.

 
What’s next ?

The current adaptive triggers only define a visual state by the height and width of the app’s window. Microsoft has promised to enhance the class or release more trigger types. If you can’t wait for this, take a look at the rich collection of Custom Visual State Triggers by Morten Nielsen or start rolling your own. After all, it’s just a matter of inheriting from StateTriggerBase and implementing its SetActive method.

 
Code

The source of the sample app is on GitHub. It was written with Visual Studio 2015 RC and Blend 2015 RC on a Windows 10 fast ring tablet.

Enjoy!

XAML Brewer

A lap around the RelativePanel Control

The RelativePanel is a new XAML layout control for the Universal Windows Platform (UWP). It allows you to decorate its elements with attached properties to position them relative to each other, and align them relative to each other or to the panel itself. That allows for a flexible graph-like layout instead of the current strictly tabular or list layouts.

Here’s the list of new attached properties:

  • Positioning of an element relative to another:
    • Above
    • Below
    • LeftOf
    • RightOf
  • Alignment of an element with another:
    • AlignBottomWith
    • AlignHorizontalCenterWith
    • AlignLeftWith
    • AlignRightWith
    • AlignTopWith
    • AlignVerticalCenterWith
  • Alignment of an element with the panel itself:
    • AlignBottomWithPanel
    • AlignHorizontalCenterWithPanel
    • AlignLeftWithPanel
    • AlignRightWithPanel
    • AlignTopWithPanel
    • AlignVerticalCenterWithPanel

It’s pretty clear what these properties stand for, so let’s dive into code.

The basics

I created a small sample app around this new panel. Here’s how it looks on startup:

RelativePanel_1

Cute, but … nothing spectacular, right?

Indeed any XAML layout or items control can draw this: Grid, StackPanel, ListView, … you name it. True, but these controls would require you to do an upfront design and configuration step where you define the number of rows and columns, orientation, and data templates. A RelativePanel doesn’t require this.

Here’s what I had in mind for the layout in the sample app:

  • Draw an empty relative panel
  • Draw Bob
  • Draw Kevin to the right of Bob
  • Align the images at their bottom
  • Draw Stuart to the right of Kevin
  • Align the images at their bottom
  • Draw Bob’s name under the image
  • Center the name under the image
  • Repeat the previous two steps for Kevin and Stuart

And this is the corresponding declarative XAML:

<RelativePanel x:Name="MinionPanel">

    <!-- Images -->
    <Image x:Name="Bob"
           Source="Assets/Bob.png" />
    <Image x:Name="Kevin"
           Source="Assets/Kevin.png"
           RelativePanel.RightOf="Bob"
           RelativePanel.AlignBottomWith="Bob" />
    <Image x:Name="Stuart"
           Source="Assets/Stuart.png"
           RelativePanel.RightOf="Kevin"
           RelativePanel.AlignBottomWith="Kevin" />

    <!-- Labels -->
    <TextBlock Text="BOB"
               RelativePanel.Below="Bob"
               RelativePanel.AlignHorizontalCenterWith="Bob" />
    <TextBlock Text="KEVIN"
               RelativePanel.Below="Kevin"
               RelativePanel.AlignHorizontalCenterWith="Kevin" />
    <TextBlock Text="STUART"
               RelativePanel.Below="Stuart"
               RelativePanel.AlignHorizontalCenterWith="Stuart" />
</RelativePanel>

Very straightforward, right? Well, there are a couple of things to consider.

The pitfalls

Circular dependencies

Under the hood, the layout algorithm builds up a directed graph (I guess). That graph doesn’t allow direct or indirect circular dependencies. The following definition would create such a dependency (I aligned Bob to Stuart, instead of Stuart to Kevin:

<Image x:Name="Bob"
        Source="Assets/Bob.png" 
        RelativePanel.AlignBottomWith="Stuart"/>
<Image x:Name="Kevin"
        Source="Assets/Kevin.png"
        RelativePanel.RightOf="Bob"
        RelativePanel.AlignBottomWith="Bob"/>
<Image x:Name="Stuart"
        Source="Assets/Stuart.png"
        RelativePanel.RightOf="Kevin" />

So “X AlignWith Y” may behave different than “Y AlignWith X”, and “X LeftOf Y” does never imply “Y RightOf X” (that would definitely create a direct circular dependency).

When you create a circular dependency in XAML, the Visual Studio designer will warn you. It’s not an error however: your code will compile, start to run, and then crash…

Elements not showing

Elements that don’t have the attached properties filled out, will be placed at the upper left corner of the panel. If you use these as anchor, some elements might be pushed out of the panel.

My first idea for the sample app layout was:

  • Draw Kevin (after all he’s the leader)
  • Draw Bob to the left of him
  • Draw Stuart to the right of him

This was my initial XAML:

<Image x:Name="Kevin"
       Source="Assets/Kevin.png"/>
<Image x:Name="Bob"
       Source="Assets/Bob.png"
       RelativePanel.LeftOf="Kevin"/>
<Image x:Name="Stuart"
       Source="Assets/Stuart.png"
       RelativePanel.RightOf="Kevin" />
This draws Kevin at the left side of the panel, and pushes poor Bob out of it. [And it took me way to long to figure out what was happening here.]
Conflicting relationships

When you define conflicting relationships, the panel alignment relationships (AlignTopWithPanel, AlignLeftWithPanel, …) have priority over the element alignment relationships (AlignTopWith, AlignLeftWith, …), which in turn have priority over the element positional relationships (Above, Below, RightOf, LeftOf). The following example has conflicting properties for Kevin; I defined him at the left of the panel, but to the right of Bob:

<Image x:Name="Bob"
       Source="Assets/Bob.png" />
<Image x:Name="Kevin"
       Source="Assets/Kevin.png"
       RelativePanel.RightOf="Bob"
       RelativePanel.AlignLeftWithPanel="True" />
<Image x:Name="Stuart"
       Source="Assets/Stuart.png"
       RelativePanel.RightOf="Kevin" />

The AlignLeftWithPanel wins, so Bob is again pushed out of the panel.

My 2 cents

Defining a layout based on the RelativePanel does require some upfront design. Here are some tricks that may help you:

  • Consider the UI inside the panel as a set of directed graphs that each start with an anchor element.
  • If appropriate, align the anchors with the panel itself.
  • Align the non-anchor elements (graph nodes) relative to each other, not to the panel.
  • Make a simple drawing of the positional and alignment relationships to detect cycles.

Here’s the final layout of the sample app. I have two nodes, the ‘Boo’ button –more on that later- and the XAML Brewer logo. Both are aligned with the panel. All minion elements are positioned (red arrows) and aligned (blue dotted lines) relative to each other and to the button, but never to the panel:

RelativePanel_1b

The true power

The static layout of a RelativePanel’s elements can be easily achieved by other panels and controls. But the RelativePanel really shines at runtime, when you start modifying the graphs. Let’s put some code behind the ‘Boo’ button to insert a new element right between Kevin and Stuart.

In all XAML platforms, attached properties can be programmatically assigned by static Set* methods, and UWP is not an exception. The RelativePanel class comes with methods such as SetAbove, SetAlignLeftWithPanel, SetAlignTopWith and so on. Here’s the logic to add a new image to the graph:

  • Create the image
  • Define all graph edges that start from the image
  • Add the image to the graph
  • Relay all edges that arrive in the new image

This is the corresponding C# code:

// Create Boo
var boo = new Image()
{
    Source = new BitmapImage(new Uri("ms-appx:/Assets/Boo.png")),
    Width = 300,
    Tag = "Boo"
};

// Prepare Boo
RelativePanel.SetRightOf(boo, Kevin);
RelativePanel.SetAlignBottomWith(boo, Kevin);

// Add Boo
MinionPanel.Children.Add(boo);

// Relay the graph edge
RelativePanel.SetRightOf(Stuart, boo);

That last statement can only be executed after the new image was added to the panel, since the panel does not allow you to define relationships towards elements outside of it.

This is the result:

RelativePanel_2

Again, this is cute. But this time it's also spectacular. If you programmatically add a column in the middle of an existing grid, you would be forced to modify all column widths, and the Column attached property on everything to the right of Boo (including Stuart’s name field). Not really flexible.

For the sake of completeness, here’s the code to remove Boo from the Panel. RelativePanel also comes with static Get* methods to retrieve the value of its attached properties, such as GetRightOf:

// Check if Stuart is right of Boo.
var theRightStuff = RelativePanel.GetRightOf(Stuart);
if ((theRightStuff as Image)?.Tag?.ToString() == "Boo")
{
    // Reconnect Stuart to Kevin.
    RelativePanel.SetRightOf(Stuart, Kevin);
    // Remove Boo
    MinionPanel.Children.Remove((UIElement)theRightStuff);
}

Last but not least, the attached properties of RelativePanel can also be modified at runtime through the new UWP Adaptive Triggers, to create a responsive design. But I’m keeping that for a next blog post.

The code

The code for the sample app is on GitHub. It was written with Visual Studio Enterprise 2015 RC on a Windows 10 fast ring box.

Enjoy!

XAML Brewer