- Posted by Diederik Krols on May 21, 2013
This article describes how to print the contents of an ItemsControl in a XAML and MVVM based Windows 8 Store app. The code is an evolution of the printing framework that I published a couple of months ago. In a nutshell, this framework wraps the pages to be printed inside a RichTextBlock control. That is the only WinRT control that properly supports pagination, at least when you connect it to a TextBlockOverflow. Pagination is the only real problem to overcome if you want to print dynamic pages. A RichTextBlock is limited in the sense that it can only contain Paragraphs. So if you want to print an ItemsControl, then you have to make it the content of a Paragraph. That means you have to wrap it in an InlineUIContainer first. Confused? Well, here's how the body of the print page looks like in the attached sample app:
<RichTextBlock>
<Paragraph>
<InlineUIContainer>
<Image Source="ms-appx:///Assets/droids.png"
Height="400" />
</InlineUIContainer>
</Paragraph>
<Paragraph>
<InlineUIContainer>
<ItemsControl ItemsSource="{Binding Droids}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0 20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Image Source="{Binding Image}"
Height="60"
Width="60"
Margin="0 20 20 20"
Opacity="1" />
<TextBlock Grid.Column="1"
Text="{Binding Name}"
Foreground="Black"
FontSize="36"
Margin="0 20" />
<TextBlock Grid.Row="1"
Grid.ColumnSpan="2"
TextWrapping="Wrap"
Text="{Binding Description}"
Foreground="Black"
FontSize="18"
Margin="0 0 20 20" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</InlineUIContainer>
</Paragraph>
</RichTextBlock>
The first version of my printing framework rendered the paragraphs one by one to see if they fitted the print page. A paragraph that could not be fully added to the page, automatically overflowed entirely to the next print page Here’s the original code:
// Move content from print page to print template - paragraph by paragraph.
var printPageRtb = printPage.Content as RichTextBlock;
while (printPageRtb.Blocks.Count > 0)
{
var paragraph = printPageRtb.Blocks.First() as Paragraph;
printPageRtb.Blocks.Remove(paragraph);
var container = paragraph.Inlines[0] as InlineUIContainer;
if (container != null)
{
// Place the paragraph in a new textblock, and measure it.
var measureRtb = new RichTextBlock();
measureRtb.Blocks.Add(paragraph);
PrintingRoot.Children.Clear();
PrintingRoot.Children.Add(measureRtb);
PrintingRoot.InvalidateMeasure();
PrintingRoot.UpdateLayout();
measureRtb.Blocks.Clear(); // .Remove(paragraph);
// Apply line height to trigger overflow.
paragraph.LineHeight = measureRtb.ActualHeight;
}
firstPage.AddContent(paragraph);
};
Unfortunately that approach didn't allow an ItemsControl to span more than one print page, so the framework was useless if you wanted to print long lists. Recently, I had to deliver an app that needed to print out a list of records, possibly a long list. So I created a sample app to isolate the problem. Here's a screenshot of it. The list on the left doesn’t fit on the screen, but also not on a single print page:

Here are some vain attempts to solve the issue. I first tried to create an ItemsControl with a RichTextBlock as ItemsPanel and a Paragraph as Item Template root. The idea was to render this control directly (as part of the current screen, that's what the printing framework does with all controls) and then move the paragraph children to the print page. But the construction of such an ItemsControl is not allowed: RichTextBlock is not a Panel *and* Paragraph cannot be used as Item. Making an ItemsControl behave like a Paragraph is not possible, so I tried to do the opposite: creating a RepeatingParagraph control, a Paragraph with an ItemsSource property. Unfortunately the classes in the Windows.UI.Xaml.Documents namespace are sealed (whose idea is that?), and with attached properties I couldn’t get deep enough into the binding mechanisms. In the meantime, the deadline of the app was approaching. So I decided to change the core framework logic instead of the controls.
I refactored the Paragraph rendering to a separate method:
// Renders a Paragraph
private double Render(Paragraph paragraph)
{
var measureRtb = new RichTextBlock();
measureRtb.Blocks.Add(paragraph);
PrintingRoot.Children.Clear();
PrintingRoot.Children.Add(measureRtb);
PrintingRoot.InvalidateMeasure();
PrintingRoot.UpdateLayout();
measureRtb.Blocks.Clear();
return measureRtb.ActualHeight;
}
When rendering the print page, I verified for each Paragraph whether or not it was embedding an ItemsControl. These paragraphs got the new treatment. For all others the original code was called:
// Move content from print page to print template - paragraph by paragraph.
var printPageRtb = printPage.Content as RichTextBlock;
while (printPageRtb.Blocks.Count > 0)
{
var paragraph = printPageRtb.Blocks.First() as Paragraph;
printPageRtb.Blocks.Remove(paragraph);
var container = paragraph.Inlines[0] as InlineUIContainer;
if (container != null)
{
var itemsControl = container.Child as ItemsControl;
if (itemsControl != null)
{
// New code to render an ItemsControl.
// ...
}
else
{
// Original code to render a complex Paragraph
// ...
}
}
else
{
// Original code to render a simple Paragraph
// ...
}
};
After a few iterations, I came up with this algorithm to render all items in an ItemsControl as a separate Paragraph, allowing individual items to overflow to the next print page. First we have to make sure that the control reads its ItemsSource. That is done by … rendering it. Then we walk through the rendered children via the ItemContainerGenerator. We wrap each item in a new InlineUIContainer and in a new Paragraph. We render that Paragraph again, to measure it. Then we move that Paragraph to the print page. Here's the code, the whole code, and nothing but the code:
// Render the paragraph, to read the ItemsSource
this.Render(paragraph);
// Render children individually
foreach (var item in itemsControl.Items)
{
var x = itemsControl.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter;
Paragraph p = new Paragraph();
InlineUIContainer c = new InlineUIContainer();
var o = x.ContentTemplate.LoadContent() as UIElement;
(o as FrameworkElement).DataContext = item;
c.Child = o;
p.Inlines.Add(c);
p.LineHeight = this.Render(p);
firstPage.AddContent(p);
}
Here’s the result in the sample app. The list nicely spans two pages:


Here’s the code for the sample app, including the whole printing framework: U2UConsult.Win8.PrintItemsControl.zip (3.18 mb)
Enjoy!
Diederik
- Posted by Diederik Krols on May 12, 2013
Many Windows 8 Store apps require some amount of structured storage on the client. But in WinRT, local and roaming storage is limited in size, and a client-side relational database does not come out of the box yet. This article describes how to use a folder in the user’s Documents library to store serialized business objects. This gives the app an almost unlimited amount of client-side structured storage. I created a small but representative sample project (code is attached at the end of the article) to illustrate this. Its purpose is to maintain a list of Trappist beers. Here’s how the app looks like:

By default, a Windows 8 Store app runs in the smallest possible sandbox: it does not have the right to directly access the user’s Documents. If you need this capability, you have to register it through the app manifest:

Even with the capability declared, the app’s rights on the documents folder are limited to the registered file types. More on that later.
The sample app uses a specific folder to store its Trappist beers in. Store apps don’t not come with an installer à la .msi, so the app should create the working folder at run time:
private static string AppFolderName = "Trappist Beers";
public static async Task<StorageFolder> AppFolder()
{
return await KnownFolders.DocumentsLibrary.GetFolderAsync(AppFolderName);
}
public static async Task EnsureFolderExists()
{
StorageFolder folder = null;
try
{
folder = await KnownFolders.DocumentsLibrary.GetFolderAsync(AppFolderName);
}
catch (Exception)
{
// Folder does not exist, but we cannot await in a catch block, so we can not create it here.
}
if (folder == null)
{
folder = await KnownFolders.DocumentsLibrary.CreateFolderAsync(AppFolderName, CreationCollisionOption.OpenIfExists);
}
}
protected async override void OnLaunched(LaunchActivatedEventArgs args)
{
await AppModel.EnsureFolderExists();
// Rest of the app initialization
// ...
}
We now have a container to store the objects, let’s generate some content. The WinRT framework comes with a whole range of serializers that can serialize business objects to a string that can be persisted in a file and deserialize it back to an object when needed. You can choose between plain XML as explained by Iris Classon, WCF DataContract XML as explained by Sara Silva, and JSON as explained by Bart Lannoeye. I’m using the XmlSerializer in the sample app, it focuses on the public properties of the class. Here’s how to use this one to serialize and deserialize a Trappist:
// Serialize
XmlSerializer serializer = new XmlSerializer(typeof(Trappist));
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, trappist);
String xmlString = writer.ToString();
}
// Deserialize
string xml = await FileIO.ReadTextAsync(file);
XmlSerializer serializer = new XmlSerializer(typeof(Trappist));
trappist = serializer.Deserialize(new StringReader(xml)) as Trappist;
We have a folder now, and we know how to serialize and deserialize its content. Let’s see how our app can access the folder. There are actually two ways to achieve this:
• Through the classic File and Folder API. This requires asynchronous calls.
• Through the MostRecentlyUsed API. This requires less programmatic maintenance, and uses synchronous calls.
For the sample app, I’m assuming that the user will work most of the times with one of the 25 most recent objects that he manipulated. In the case of Trappist beers, that is a fair assumption: there are only 8 authentic Trappist breweries in the world, and together they have not even created 25 Trappist beers. By the way: they’re excellent, I tasted all of them (except the two from Engelszell which are hard to get outside Austria). Anyway, a scenario in which a user mainly works with his most recent business objects, is common.
Each Windows 8 Store app can maintain its own Most Recently Used file list. When registering a file in the MRU list, you are allowed to store some metadata with it. The file itself is indexed through a token (not unsurprisingly based on a GUID). The sample app stores the name of the Trappist beer in the metadata. That name is also used as the physical file name. So I’m actually treating the name of the beer as primary key. Here’s how to add a file to the MRU list:
StorageApplicationPermissions.MostRecentlyUsedList.Add(file, trappist.Name);
We execute this registration when saving a new file, and when opening an existing file. Here’s how to fetch the list of most recently used Trappist names, the most recently accessed file always comes first:
public static ObservableCollection<string> MostRecentTrappists
{
get
{
var result = new ObservableCollection<string>();
foreach (var item in StorageApplicationPermissions.MostRecentlyUsedList.Entries)
{
result.Add(item.Metadata);
}
return result;
}
}
Observe that the call is synchronous. We’re actually not accessing the folder or files themselves.
Of course, the user may add, delete, move, and rename these files with other apps, or directly with the File Explorer. After all: it is *his* Documents folder. So the app’s GUI should also expose that real situation from disk. Here’s how to get the alphabetical list of Trappist names in the app’s working folder:
public async static Task<ObservableCollection<string>> FolderTrappists()
{
var result = new ObservableCollection<string>();
var folder = await AppFolder();
var files = await folder.GetFilesAsync();
var names = from file in files
where file.FileType == AppFileExtension
orderby file.DisplayName
select file.DisplayName;
foreach (var name in names)
{
result.Add(name);
}
return result;
}
This is an asynchronous method because in WinRT we cannot access the file system synchronously.
I use a toggle switch to change between ‘MRU’ and ‘Folder’ mode. In a production app the control would end up in the app bar or the settings panel:


To save memory, the app only displays the list of Trappist names, not the list of full business objects. When saving, opening or deleting a Trappist, we need to make the link with the corresponding physical file. Therefor we first need to fetch the identification token from the MRU list. Here’s how to do this:
private static string GetMruToken(string trappistName)
{
var token = (from e in StorageApplicationPermissions.MostRecentlyUsedList.Entries
where e.Metadata == trappistName
select e.Token).FirstOrDefault();
return token;
}
Using the token, we can get the file, like this:
var token = GetMruToken(trappistName);
if (!String.IsNullOrEmpty(token))
{
try
{
// Get file through MRU list
file = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(token);
return file;
}
catch (Exception)
{
// File was probably deleted, so continue with app folder.
}
}
If something went wrong (e.g. the Trappist is not in the MRU anymore), then you should go for the physical file directly:
try
{
var folder = await AppFolder();
file = await folder.GetFileAsync(trappistName + AppFileExtension);
}
catch (Exception)
{
// Ignore
}
return file;
Now you can save, open, and delete the corresponding file for a Trappist name in the list.
So far for the Model and the Data Access Layer, let’s now take a look to the ViewModel. It has the classic CRUD commands to open, create, rename, and delete a Trappist. I’m using the RelayCommand from MVVM Light for this. To get the name for a newly created or renamed Trappist, I’m using an InputDialog control from the WinRTXamlToolkit. Here’s how to work with it:
var dialog = new InputDialog();
var result = await dialog.ShowAsync(
"Add new Trappist",
"Please enter the name:",
"Create",
"Cancel");
if (result == "Create" && !String.IsNullOrEmpty(dialog.InputText))
{
// ...
}
This is how it looks like by default:

Since some of the interactions require asynchronous calls under the hood, I decorated the ViewModel with some internal events and local event handlers to bridge the period between setting a property and notifying its change:
private event EventHandler TrappistNamesChanged;
public MainPageViewModel()
{
// Initialization
// ...
this.TrappistNamesChanged += this.MainPageViewModel_TrappistNamesChanged;
}
public ObservableCollection<string> TrappistNames
{
get
{
return this.trappistNames;
}
}
private async void MainPageViewModel_TrappistNamesChanged(object sender, EventArgs e)
{
if (this.ShowAll)
{
this.trappistNames = await AppModel.FolderTrappists();
}
else
{
this.trappistNames = AppModel.MostRecentTrappists;
}
this.OnPropertyChanged("TrappistNames");
}
I’m not evangelizing this as a best practice, but it seems to do the trick.
I already revealed one advantage of using the file system over a local database: the user can easily copy, move, rename, and delete objects through the File Explorer (admitted: that’s not always an advantage). Let’s take this one step further. Through the app manifest you can register your app as the default app to open files with the corresponding extension(s), and at the same time define a default icon for the files. The declaration of these extensions is mandatory, since it defines the files to which the app has access:

When the user is now browsing through his Documents, he’ll easily recognize the files:

You can let the app open on the selected business object when the user double clicks (or taps) the file. Here’s the code to do that (in app.xaml.cs):
protected override void OnFileActivated(FileActivatedEventArgs args)
{
if (args.Files.Count > 0)
{
var file = args.Files[0];
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
Window.Current.Content = rootFrame;
}
// MRU list
var name = Path.GetFileNameWithoutExtension(file.Name);
StorageApplicationPermissions.MostRecentlyUsedList.Add(file, name);
if (!rootFrame.Navigate(typeof(MainPage), name))
{
throw new Exception("Failed to create initial page");
}
Window.Current.Activate();
}
}
That’s it, I tried to structure the code to make it as reusable as possible. I have at least three apps waiting for this pattern.
Here’s the code: U2UConsult.Win8.documentLibrarySample.zip (643.43 kb)
Enjoy!
Diederik
- Posted by Diederik Krols on April 21, 2013
This article describes how you can use naming conventions to hook a XAML Data Template to a ViewModel or a Model in a Windows 8 Store app. The last couple of years, convention-based coding became more and more popular in the .NET world. The MVC framework was one of the first managed environments where the constituents of an application (in this case Models, Views, and Controllers) were automatically linked to each other based on their name, instead of letting a developer create references and interfaces. The latest version of the Managed Extensibility Framework –a.k.a. MEF- also comes with a convention-based programming model: the RegistrationBuilder and PartBuilder classes provide an alternative for MEF attributes: they let you specify the rules to infer Parts, Imports, and Exports from the names of your classes and properties. Also in the XAML world, convention-based coding is not new. Most of the popular MVVM frameworks rely heavily on naming conventions to link components together. Caliburn.micro has several classes to lookup the View for a ViewModel (and vice-versa) and to generate data bindings solely based on class and property names: ViewLocator, ViewModelLocator, and ViewModelBinder.
This article presents a way to link a XAML DataTemplate in a View to its corresponding Model or ViewModel data context class. Here are some screenshots of the attached sample project: it shows a FlipView control (with an associated FlipViewIndicator) that has a different type of Model for each item, so each page should look differently:


In ye olde XAML platforms, you could specify the default data template for a class with the DataType property. In Windows 8 Store app XAML, that property is not supported anymore. So when you want an ItemsControl to display a list of objects of different types, you have to use a DataTemplateSelector. I already explained the mechanisms in this blog post.
The following class defines a data template selector that looks up a data template in the app’s resources, based on the name of the data context class. It just adds “Template” to the name of the data context class, so if you want to display an instance of “Person”, you just have to provide a data template with as x:Key “PersonTemplate”:
/// <summary>
/// Convention-based DataTemplate Selector.
/// </summary>
public sealed class DynamicDataTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
DataTemplate result = null;
string typeName = item.GetType().Name;
try
{
result = App.Current.Resources[typeName + "Template"] as DataTemplate;
}
catch (Exception)
{
Debug.Assert(false, string.Format("No data template found to display '{0}' instances.", typeName));
}
return result;
}
}
The try-catch block is necessary because the resource manager throws an exception when a resource is not found.
Here’s how to apply the selector in an ItemsControl. It is declared as a resource:
<Page.Resources>
<templates:DynamicDataTemplateSelector x:Key="DynamicDataTemplateSelector" />
</Page.Resources>
And then applied to the FlipView:
<FlipView x:Name="TheFlipView"
ItemsSource="{Binding Models}"
ItemTemplateSelector="{StaticResource DynamicDataTemplateSelector}" />
Here are some of the data templates from the resource dictionary:
<!-- Biography -->
<DataTemplate x:Key="BiographyTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
Foreground="Yellow"
FontSize="28"
HorizontalAlignment="Center"
Margin="0 48 0 0" />
<TextBlock Text="{Binding Description}"
Grid.Row="1"
FontSize="20"
TextWrapping="Wrap"
Margin="0 48 0 0" />
</Grid>
</DataTemplate>
<!-- Powers And Abilities -->
<DataTemplate x:Key="PowersAndAbilitiesTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
Foreground="Yellow"
FontSize="28"
HorizontalAlignment="Center"
Margin="0 48 0 0" />
<ItemsControl ItemsSource="{Binding Powers}"
Grid.Row="1"
Margin="0 48 0 0"
HorizontalAlignment="Center">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="20">
<Run Text="● " />
<Run Text="{Binding}" />
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="Weaknesses"
Grid.Row="2"
Foreground="Yellow"
FontSize="28"
HorizontalAlignment="Center"
Margin="0 48 0 0" />
<ItemsControl ItemsSource="{Binding Weaknesses}"
Grid.Row="3"
Margin="0 48 0 0"
HorizontalAlignment="Center">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock FontSize="20">
<Run Text="● " />
<Run Text="{Binding}" />
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
When a data template is not found in the resources, the selector returns a Null value. The data binding engine then applies a default template, with the fully qualified type name in a text box. Here’s how this looks like:

During debugging, the Assert statement writes an exception to the output window when the template is not found, like this:

That’s all there is. Actually, the title of this article was longer than its source code. Here is the sample app: U2UConsult.Win8.DataTemplating.zip (692.39 kb)
Enjoy!
Diederik
- Posted by Diederik Krols on March 28, 2013
This article illustrates two ways of using touch or mouse input to rotate a UI element in a XAML-based Windows 8 Store app. I’m sharing this code because I believe that the corresponding official MSDN sample is too complex. Don't get me wrong: the Windows 8 gestures sample looks nice and gives a complete overview of all gestures and their mouse equivalent. But it uses three entire classes to do something that you can literally do in three lines of code. In this article, I’ll describe the guidelines-compliant way of rotating an element using a two-finger gesture, but I also provide a one-finger alternative. Since not everyone has a touch screen (yet), I also give you two ways for using the mouse to rotate an element. As usual, the article comes with a downloadable sample app. It just displays two round rotatable images. Here’s a screenshot of it:

Multi Touch Rotation
A UI Element can register for rotation by setting its ManipulationMode to Rotate, optionally adding inertia. Multiple manipulation modes can be set in XAML through a comma-separated list. Just ignore Intellisense and don’t use the property editor:
<Image ...
ManipulationMode="Rotate,RotateInertia" />
Setting the manipulation mode causes the corresponding manipulation events (starting, inertiaStarting, started, delta, and completed) to fire. You find the complete list of events and event argument classes in the Touch Input Quickstart.
You still have to code what should happen in your app. Typically that boils down to configuring the element’s RenderTransform. To simplify the code in the event handlers, I gave the image a named rotation transformation:
<Image x:Name="Left"
ManipulationMode="Rotate,RotateInertia"
ManipulationDelta="Left_ManipulationDelta">
<Image.RenderTransform>
<RotateTransform x:Name="LeftRotateTransform" />
</Image.RenderTransform>
</Image>
All you have to do to manually rotate the image, is to subscribe to the ManipulationDelta event, and add the delta's rotation to the element’s rotation transform:
// Called when rotate by touch.
private void Left_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
this.LeftRotateTransform.Angle += e.Delta.Rotation;
}
[Tip: You could use the ManipulationCompleted event to implement snap points.]
The pivot point of the rotation is set to the center of the element. For images you can do this in the ImageOpened event. It’s the first event that guarantees that ActualHeight and ActualWidth are set. I must say that every now and then I still get zero values here.
// Called when the image is ready to be rendered. ActualHeight and ActualWidth are known.
private void Image_Opened(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
Image img = sender as Image;
RotateTransform rt = img.RenderTransform as RotateTransform;
rt.CenterX = img.ActualWidth / 2;
rt.CenterY = img.ActualHeight / 2;
}
The standard touch-based rotation requires two touch points or more:

In Visual Studio's Touch Simulator, you can test it with the ‘Rotation touch mode’ button. Press it, hover over the UI element on the page, and scroll the mouse wheel:

On a non-touch device, the guidelines for common user interactions prescribe that a rotation gesture should be triggered by the mouse wheel, with ctrl and shift buttons pressed. So we add an event handler for PointerWheelChanged:
<Image x:Name="Left"
Grid.Row="1"
Margin="64 36"
Source="../Assets/Wheel_of_Fortune.png"
ManipulationMode="Rotate,RotateInertia"
ManipulationDelta="Left_ManipulationDelta"
ImageOpened="Image_Opened"
PointerWheelChanged="Left_PointerWheelChanged">
<Image.RenderTransform>
<RotateTransform x:Name="LeftRotateTransform" />
</Image.RenderTransform>
</Image>
In the handler, we check whether the shift and control buttons are pressed, and then apply the MouseWheelDelta to the rotation angle. Look at the weird code to get that mouse wheel delta:
// Called when rotate by mousewheel.
private void Left_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
bool shift = (e.KeyModifiers & VirtualKeyModifiers.Shift) == VirtualKeyModifiers.Shift;
bool ctrl = (e.KeyModifiers & VirtualKeyModifiers.Control) == VirtualKeyModifiers.Control;
if (shift && ctrl)
{
var delta = PointerPoint.GetCurrentPoint(e.Pointer.PointerId).Properties.MouseWheelDelta;
// With my mouse, delta is a multiple of 30.
this.LeftRotateTransform.Angle -= delta / 15;
}
}
Use cases
In scenarios where inertia is needed (e.g. spinning a wheel) the two finger touch rotation is the right match. That manipulation is also very useful for rotating larger elements, with a high precision. For rotating a small element, I wouldn’t recommend this gesture, simply because you don’t see what you’re doing with two or more fingers on it.
For non-touch environments, I’m not sure that the shift-control-mousewheel combination will become popular.
Single Touch Rotation
As an alternative, you can allow a user to put a finger on the element and start dragging. You just need to transform the translation into a rotation with a pinch of trigonometry. It’s easy to build, intuitive, and the code immediately works for the mouse too: click and start dragging. Just enable the TranslateX and TranslateY manipulation modes (and optionally add inertia), register a handler for ManipulationDelta, and initialize the RenderTransform:
<Image ...
ManipulationMode="TranslateX,TranslateY,TranslateInertia"
ManipulationDelta="Right_ManipulationDelta"
ImageOpened="Image_Opened">
<Image.RenderTransform>
<RotateTransform x:Name="RightRotateTransform" />
</Image.RenderTransform>
</Image>
In the ManipulationDelta handler, you transform the translation into a rotation by calculating the angle of the delta. Add this angle to the angle of the element’s RotateTransform. I took some time to make a small drawing to illustrate this. Alpha is the angle to be calculated:

From a performance standpoint, I assume that the law of cosines would be the most appropriate solution here. But I have the right to be lazy sometimes, so I went for the “least C#” option: calculate Alpha as the difference of Alpha1 and Alpha2 on the image. Here’s that code:
// Called by touch and mouse.
private void Right_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
// Alternatively, use Triangle Cosines Law.
// It uses just one trigonometric function (Acos), but you first need to calculate the lengths of all sides.
var x = this.RightRotateTransform.CenterX - e.Position.X;
var y = this.RightRotateTransform.CenterY - e.Position.Y;
double a1 = Math.Atan(y / x);
double a2 = Math.Atan((e.Delta.Translation.Y - y) / (x - e.Delta.Translation.X));
this.RightRotateTransform.Angle += a1 - a2;
}
Use cases
I would definitely recommend this type of rotation in non-touch scenarios: it reacts naturally and it does not require the shift and control buttons (or the user’s recollection to press these). In a touch environment, it does not occlude the element you're manipulating. There’s a lag in reaction time, and it’s easy to outpace the algorithm by moving too fast. So I would not use single point rotation to e.g. spin a wheel. The roulette wheel in the sample app is a bad choice - it just looked nice next to that wheel of fortune. 
Code
Here’s the full code: U2UConsult.RotationManipulation.Sample.zip (587.17 kb)
Enjoy!
Diederik
- Posted by Diederik Krols on March 18, 2013
This article describes two behaviors of the native XAML Slider control that reduce the joy of using it in MVVM Windows 8 Store apps. We all agree that XAML is one of the nicest technologies to develop Windows 8 Store apps, right? We all agree that you should use MVVM to build XAML apps, right? No, we don’t: unfortunately some of the native controls strongly disagree with us. The most well-known example of an MVVM-unfriendly XAML control is the radio button. A radio button is cleared by selecting another radio button in the same group. That’s OK, but at that moment it also clears its binding. It breaks the link to the viewmodels to which it was bound. This classic MVVM problem is generally solved by assigning a unique GroupName to each radio button, and deal with the mutual exclusiveness programmatically on the viewmodels’ side. Ouch!
Recently I observed that the native slider control has a similar issue. Even worse: two issues. Ouch! Ouch!
Seeing is believing, so I created a small demo app to illustrate these issues. The app shows two sliders that display temperature values from a viewmodel. The user may switch between Celsius and Fahrenheit scales using a data bound toggle switch. [My shoulder devil tried to convince me to use radio buttons instead of a toggle switch. It was a close fight, but the angel won.]
Here’s a screenshot of the app:

Here are the two issues, and their impact on the MVVM app:
A Slider dies when its Minimum becomes greater than its Maximum
Whenever a slider control –even temporarily- reaches a state where its Minimum value becomes greater than is Maximum, it simply blocks. So when you create a slider of which the range is bound to values in the viewmodel, you could be in trouble. The sliders in the sample app show a range from 0 °C to 28 °C, that’s (more or less) from 32 °F to 82 °F. These values are provided by the viewmodel, and they’re updated when the settings change. Here are the bindings for one of the sliders:
<Slider Value="{Binding SomeTemperature, Mode=TwoWay}"
Minimum="{Binding MinimumTemperature}"
Maximum="{Binding MaximumTemperature}" />
In a regular MVVM app, we would safely rely on the data binding engine to propagate the modifications from the viewmodels to the controls. Well, that does not work if there are sliders involved: whenever the sample app reaches a sub state where the MinimumValue is in Fahrenheit (32) and the MaximumValue is still or already in Celsius (28), the sliders simply die with an unmovable thumb docked to the maximum end, like this:

As a work around, you can take control of the order in which the property changes are notified, just to make sure there’s always a valid range. Here’s an example; this is part of the code that is triggered by the temperature unit toggle switch:
// Workaround: control change propagation order.
if (this.isCelsius)
{
this.OnPropertyChanged("MinimumTemperature");
this.OnPropertyChanged("MaximumTemperature");
}
else
{
this.OnPropertyChanged("MaximumTemperature");
this.OnPropertyChanged("MinimumTemperature");
}
If we switch to Celsius, we first change the MinimumValue (from 32 to 0) and then the MaximumValue (from 82 to 28), and the other way around when we switch to Fahrenheit. We should never be forced to write this kind of code, but it does the trick.
Let’s move to another issue:
A Slider modifies its Value to keep it in its Range
While the first issue is just an inconvenience, I perceive the second issue as a real disaster: while you are changing the boundaries of the slider range, the slider will update its Value property to keep it in this range. Here’s a scenario. Start the app and set both temperatures to 57°F (that’s in the middle of the range).

Then switch to Celsius and observe the value in the top slider:

The slider Value went down to 0 instead of the expected 14 °C. This is what happened: when the range moved from (32 -> 82) to (0 -> 28), the slider ‘adjusted’ the value before the viewmodel had a chance to calculate the new value. So the slider changes the value, and then the viewmodel used that wrong value to apply the conversion to. Somewhere in that process, the slider also broke its binding. So its value is at zero, where the viewmodel is at -2. Both are wrong. Staggering, isn’t it? And by the way: unit tests on your viewmodel will NOT reveal these bugs. 
On a more positive note: you can circumvent the problem by making a backup of the value on the start of the change propagation, like this:
var temp = this.anotherTemperature;
// Obsolete algorithm to update slider range
// ...
// This would be standard code. Unfortunately it does not work.
if (this.isCelsius)
{
this.SomeTemperature = UnitConverter.FahrenheitToCelsius(this.SomeTemperature);
}
else
{
this.SomeTemperature = UnitConverter.CelsiusToFahrenheit(this.SomeTemperature);
}
// Workaround: backup value.
if (this.isCelsius)
{
this.AnotherTemperature = UnitConverter.FahrenheitToCelsius(temp);
}
else
{
this.AnotherTemperature = UnitConverter.CelsiusToFahrenheit(temp);
}
Can you imagine how the complexity would increase if we had multiple sliders, some of them with more than two possible ranges (e.g. liters, US gallons, and UK gallons)? Well I can, here’s an example of such a page. This view will be part of the next release of this app. It does what it's supposed to do, but its viewmodel is bloated with logic to keep all sliders up and running:

Call to action
This small sample shows that even one simple slider in a view could dramatically increase the complexity of your code, even up to a point where it threatens the MVVM architecture. It really should not be necessary to apply modifications to the viewmodels (and/or models), just to work around the inappropriate behavior of one single type of control. I strongly believe that XAML developers deserve a better solution, in the form of more MVVM-friendly native controls. So Microsoft: please fix this. And while you’re there: fix the radio button too.
Maybe I should make an appeal to the community? Why not:
Dear open source MVVM framework builders,
We have enough property change propagators, dependency injectors, service locators and event aggregators. Could you please spend some time in creating or fixing some controls to actually work with it?
Thanks,
a XAML developer
That almost sounded like a rant, didn't it? Don't worry: I'm fine.
Code
Here’s the sample project: U2UConsult.WinRT.MVVMSlider.zip (117.08 kb).
Enjoy!
Diederik
- Posted by Diederik Krols on March 4, 2013
With this short article, I want to show you the easy way to provide data to a semantic zoom in a Windows 8 Store app. I’ve seen too many developers trying to massage their business data to make it consumable for a semantic zoom, by pulling it through custom implementations of ISemanticZoomInformation or through other data adapter classes. You see this pattern even in the official XAML GridView grouping and SemanticZoom sample. All you need to remember from this article, is that such infrastructure is not necessary: the grouped data source for the CollectionViewSource that populates the two zoom levels of a semantic zoom control, can be generated by a simple LINQ query that your ViewModel can pull straight out of your Models.
As usual, I built a simple MVVM app to illustrate my point. It comes with two Model classes: Item and Category, where each item has a category. I do realize that this will not help me win the Oscar for the most original scenario. The data access layer provides a list of both. The only View in the app just shows a semantic zoom that pulls its data (items with a category) from a property in the main ViewModel.
Here’s how the two levels of the semantic zoom look like at runtime.
Zoomed in:

Zoomed out:

The CollectionViewSource is defined as a resource in XAML, and bound to the zoomed-in view of the semantic zoom:
<Page.Resources>
<CollectionViewSource x:Name="collectionViewSource"
IsSourceGrouped="True"
Source="{Binding ItemsByCategory}" />
</Page.Resources>
<!-- ... -->
<SemanticZoom x:Name="semanticZoom">
<SemanticZoom.ZoomedInView>
<GridView ItemsSource="{Binding Source={StaticResource collectionViewSource}}"
SelectionMode="None">
<!-- ... -->
</GridView>
</SemanticZoom.ZoomedInView>
<!-- ... -->
</SemanticZoom>
 |
The CollectionViewSource gets its data from the viewmodel through a LINQ query that yields the items, grouped by category:
itemsByCategory = from item in Items
orderby item.Name
group item by item.Category into g
orderby g.Key.Name
select g;
By the way, this is how that same query looks like in the official sample:
internal List<GroupInfoList<object>> GetGroupsByCategory()
{
List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();
var query = from item in Collection
orderby ((Item)item).Category
group item by ((Item)item).Category into g
select new { GroupName = g.Key, Items = g };
foreach (var g in query)
{
GroupInfoList<object> info = new GroupInfoList<object>();
info.Key = g.GroupName;
foreach (var item in g.Items)
{
info.Add(item);
}
groups.Add(info);
}
return groups;
}
|
That's a lot of obsolete code. For the sake of simplicity, I spare you from the definition of the -also obsolete- GroupInfoList class. Looking at this code, one can only agree when a tweet like this one pops up in his timeline:

Enough ranting, let's go back to the sample.
The LINQ query returns an IEnumerable<IGrouping<Category, Item>>. And that’s enough to provide a source for all semantic zoom bindings.
The zoomed-out view of the semantic zoom has several templates. The item template is bound to each item, so the binding expressions are straightforward:
<GridView.ItemTemplate>
<DataTemplate>
<!-- Bound to an Item -->
<StackPanel>
<Image Source="{Binding Image}"
... />
<Border ... >
<TextBlock Text="{Binding Name}"
... />
</Border>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
Each grouping (= category) has a group style header, of which the template is bound to an IGrouping. That interface only provides a Key attribute, but that's enough to provide the title:
<GroupStyle.HeaderTemplate>
<DataTemplate>
<!-- Bound to an IGrouping with Category as Key-->
<Grid Margin="0">
<TextBlock Text='{Binding Key.Name}'
... />
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
The zoomed-in view of the semantic zoom is bound to the collection of groups in the data source. We (still) have to do this in code behind:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// IObservableVector<IGrouping<Category, Item>>
(this.semanticZoom.ZoomedOutView as ListViewBase).ItemsSource = collectionViewSource.View.CollectionGroups;
}
This is an ICollectionViewGroup, so it comes with Group and GroupItems properties. These properties come in handy to provide binding expressions. Group.Key returns the category instance, but you could also choose to just follow the links in the viewmodel from the items' perspective:
<GridView.ItemTemplate>
<DataTemplate>
<!-- Bound to an ICollectionViewGroup -->
<StackPanel>
<Border>
<TextBlock Text="{Binding Group.Key}"
... />
</Border>
<Image Source="{Binding GroupItems[0].Category.Image}"
... />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
- Posted by Diederik Krols on February 5, 2013
Developers who submit a Windows 8 XAML-based Store app that involves data entry, should always test their app on a real touch device. Otherwise they might see their app rejected because of the soft keyboard blocking the screen. This article illustrates some of my personal experiences and issues regarding the behavior of the soft keyboard in Windows 8 Store apps. Don’t worry: none of these issues is really blocking, and I’ll show you some workarounds.
When and why the soft keyboard opens and closes, is described in this white paper. If you’re building Windows 8 Store apps that have data entry pages, this white paper is a must read. The behavior of the soft keyboard is well documented and justified, at least in theory. In practice however, I came across some issues. Here they are:
The soft keyboard never closes automatically
The keyboard cannot be opened programmatically. That’s a good thing. The keyboard opens only when the user taps on a text entry control (mostly a TextBox). Unfortunately the only way to indicate that he’s finished entering data, is to ‘tap somewhere else on the screen’. Depending on that ‘somewhere else on the screen’ the soft keyboard will remain open, or it will disappear. Now some controls know very well when data entry is finished and should not require that extra tap. E.g. a box to enter a year or birth could (and in my opinion should) leave edit mode automatically when four digits are entered. In other controls, hitting the ‘Enter’ key would be an intuitive action to indicate the end of data input. I implemented the latter behavior in my EnhancedSlider, that’s a slider that comes with an extra TextBox to allow direct input. That TextBox becomes disabled when the user hits the ‘Enter’ key in it. I believe that tapping that key on the keyboard is a lot more user friendly than letting the user search for a safe spot on the semi-obscured screen (remember: the soft keyboard covers half the screen) to close the keyboard.
The ‘tap outside the control’ philosophy also makes it impossible to make a full-screen text input control. Here's what happens if the screen is entirely filled by one or more textboxes:

The user can enter some tekst, but he can't close the keyboard anymore. If the Windows8 App store testers get stuck in this scenario, they will not approve your app.
The next edit control is automatically focused
When the TextBox in the EnhancedSlider becomes disabled, the keyboard remains open if there are other text input controls on the page. I’m OK with that: we’re in edit mode, so it doesn’t make sense to distract our user by constantly flipping the keyboard up and down. But not all screens require the use to enter the data in a specific order. Allow me to illustrate this with an example. This is a screenshot of a user changing the weight of some business object through an EnhancedSlider (middle of the screen):

Here’s what happens by default when the user finishes editing by hitting ‘Enter’. The keyboard remains open with the focus on the category ComboBox (I’m complaining about the focus here, not the ugly blue color – the inappropriate color is clearly my fault):

There are no relationships between the fields, so there’s no required input order. The user just modifies what he needs to modify in any chosen order. There’s absolutely no need to automatically give the focus to any of the controls. It’s not like the user is going to use the soft keyboard to tab through the controls on the page. On the other hand: a user with a real keyboard may just want to tab through the screen, so setting the IsTabStop property to false is not a viable solution. I believe that it should be possible for a developer to specify that the keyboard may remain open without a particular control getting the focus. I have the impression that the soft keyboard paradigm in Windows 8 is based on archaic fill-out form logic.
Up until now, you could say: “Hey, it’s your own fault. You’re using a custom control that violates the UX standards”. OK, I agree with that. But here’s an issue that has nothing to do with me trying to deliver user friendly controls:
The keyboard remains open on ListBoxItem
When the soft keyboard is open and the focus moves to another text input control, the keyboard remains open. I already mentioned that I’m OK with that. I just have a problem with the definition of ‘text input control’. This is the list from the mentioned white paper: Check box, Combo box, Radio button, Scroll bar, Tree, Tree item, Menu, Menu bar, Menu item, Toolbar, List, List item.
That last control is the one that bothers me. In a tile-based store app –and that’s the large majority- everything is hosted inside a ListItem. A lot of pages do nothing more than displaying a collection of business objects in an ItemsControl (ListView, VariableSizedGridView, SemanticZoom, etc.) The main navigation hub of single page apps (like the finance and weather app) uses a GridView as main navigation panel. Here’s another example of a real app that has a horizontally scrolling page with several topics. That's a very common concept. Unfortunately, things go wrong when you request the user to type in some tekst in such an app. I just wrote something in the text box at the bottom of the page, and tapped inside the border:

There’s nothing special to see, except a blinking cursor in the text box (and the screenshot does not even show that). The app looks fully operational. But that’s only because I took the screenshot when a physical keyboard was attached to the tablet. This is how the same screen looks like in full touch mode:

The keyboard remains open because the controls are hosted in a GridViewItem, which is a ListItem, which is in the keep-the-keyboard-open list. Tapping on the page does not close the keyboard, and the main navigation buttons are off-screen. The UI is blocked now, the app will be rejected. #FAIL
Easy work arounds
OK, here’s the good news: all these issues can be solved by adding one or two simple XAML controls on your data entry page. When fighting with the soft keyboard, you just give one of these controls programmatically the focus, and the keyboard will obey your will.
The first problem solver is a focusable control of the text input kind, without a user interface. When you give this one the focus, the keyboard will open without focusing one of the visible controls. That sounds easy: just create a text box with Visibility set to Collapsed, or Height or Width at zero. Unfortunately that does not the trick: the runtime will not give the focus to a control that does not consume screen infrastructure. But we know that templatability is a key concept in XAML, so let’s leverage it. The next control successfully fools the Windows RT runtime:
<!-- Opens the soft keyboard when it gets the focus -->
<TextBox x:Name="KeyboardOpener">
<TextBox.Template>
<ControlTemplate />
</TextBox.Template>
</TextBox>
You can give this control the focus programmatically like this:
this.KeyboardOpener.Focus(FocusState.Programmatic);
Or you could just place it at the right position. In the above screen I just added a KeyboardOpener next to the Enhanced Slider:
<local:EnhancedSlider Value="{Binding GrainGift.Weight.Value, Mode=TwoWay}"
Header="Weight"
ValueSuffix="{Binding GrainGift.Weight.UnitMeasure.Name, Converter={StaticResource StringFormatConverter}, ConverterParameter=' {0}'}"
Minimum="0"
Maximum="{Binding GrainGift.MaxWeight}"
StepSize="5" />
<TextBox x:Name="FocusGrabber">
<TextBox.Template>
<ControlTemplate />
</TextBox.Template>
</TextBox>
The Combo box does not turn blue anymore.
If for some reason you want to programmatically close the soft keyboard, give this control the focus:
<!-- Closes the soft keyboard when it gets the focus -->
<Slider x:Name="KeyboardCloser">
<Slider.Template>
<ControlTemplate />
</Slider.Template>
</Slider>
In the above example, I set the focus to this control in the Tapped event of the GridViewItem:
<GridView SelectionMode="None">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<Grid Tapped="Page_Unfocus">
<!-- Content, including edit controls -->
</Grid>
<!-- Other pages -->
</GridView>
private void Page_Unfocus(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
this.FocusGrabber.Focus(Windows.UI.Xaml.FocusState.Programmatic);
}
A Close-the-keyboard Button
The problem in the first screenshot of this article can only be solved by adding a button to the page, a button to close the soft keyboard when it's open. That's exacly what I did. Here's the XAML:
<Button x:Name="KeyboardCloser"
Visibility="Collapsed"
Style="{StaticResource HideKeyboardAppBarButtonStyle}" />
By default it is invisible. It should only appear when the soft keyboard is open. To achieve this, just register to the InputPane.Showing event. Here's the code from the constructor of the page:
var inputPane = InputPane.GetForCurrentView();
inputPane.Showing += InputPane_Showing;
inputPane.Hiding += InputPane_Hiding;
And here are the two event handlers:
private void InputPane_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
this.KeyboardCloser.Visibility = Visibility.Visible;
}
private void InputPane_Hiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
this.KeyboardCloser.Visibility = Visibility.Collapsed;
}
That's it. When soft keyboard pops open, we show a button to close it. The button itself does not require a click event handler. Tapping it gives it the focus, and that's enough to close the keyboard:

Demo time
As usual, I built a small sample project to illustrate these focus-and-keyboard issues. It shows that you can easily open and close the soft keyboard, and that not every ListboxItem keeps the keyboard open. Just check the comments in the code. Here are some screenshots:


If you're not on a touch device, run the code in the simulator. Otherwise there's really not much to observe...
Code
Here’s the full code of the sample. It was written with the free Visual Studio 2012 Express Edition: U2UConsult.Keyboard.Sample.V2.zip (391.60 kb)
Enjoy!
Diederik
- Posted by Diederik Krols on January 20, 2013
This article describes a reusable way of implementing print support in a Windows 8 MVVM-and-XAML based Store app. I noticed on the MSDN forum that many developers have a problem with the XAML version of the official printing sample app. They find it too complex. So I originally wanted to create a simpler version of it. I realized very rapidly that these developers are actually wrong. The print sample is not too complex. On the contrary: the printing sample is missing many features that would make it useful in a production app:
• It does not support multiple types of print pages.
• The printed page only has flat text and images.
• The printed page does not support data binding.
• The printed page contains a mix of content (text) and template (header, footer, margins) elements - the template elements are not nicely encapsulated.
• The printed pages have no page number.
So I put that sample on steroids to address these issues and make it work in a larger MVVM context, and here’s the result. O, I also simplified it a bit: I removed the need for having two different print page classes: I merged HeaderPage and ContinuationPage into a single PrintPage (see comments below). Let me tell you upfront: the code works, but I’m not proud of it. I sincerely hope that I missed a useful XAML feature or two, because the overall complexity level is just too high for something as basic as printing. I have a hunch that I did boldly go where nobody should have gone before.
Here’s how my sample app looks like. It has a main page with two buttons that talk to the print provider, and a ComboBox that’s populated by a ViewModel:

That's a simple start. Now hear the rest of the story.
The Framework
This is the object model of the lightweight printing framework:

Most of the reusable functionality is encapsulated in the PrintServiceProvider. It has methods to register and unregister the app for printing with Windows. If you don’t register, then the devices charm remains empty. It also has the required event handlers that are called by Windows to generate the pages to be displayed in the preview pane and the actual pages to be printed. Just like in the official printing sample, the class inherits from Page. That allows it to make use of its Dispatcher.
The printing framework also comes a ‘real’ page: the PrintPage instances appear in the preview pane and are sent to the device. It's just an empty page with a header, a footer, and a RichTextBlockOverflow. That overflow is crucial to the framework, because the biggest problem when printing XAML is pagination. On top of the print page there's a RichTextBlock that receives all print content, but it's invisible itself. It lives in a Grid Row with Height 0, so all print content -except a dummy first paragraph- will be sent to the overflows.
The responsibilities of these core classes in the framework are based on the original printing sample and further elaborated in this excellent article from the popular 31 days of Windows 8 series.
The last class in the framework is an EventArgs class that carries a message to the subscribers of the StatusChanged event.
The Caller
Although the framework is reusable, there are some constraints on the caller. Any page in a Store app that wants to be printed should have a printable version of it. Typically a page on paper will look different from its version on screen (starting with size and orientation). The print page only contains a RichTextBlock with paragraphs. Some of these contain just text, but most of these will host an InlineUIContainer which can contain anything – including a databound control. You should prefer a Grid inside the inlines to layout the content, other controls -like StackPanel- will be truncated. This is how a print page looks like:
<Page>
<RichTextBlock>
<Paragraph>Some Text</Paragraph>
<Paragraph />
<Paragraph>
<InlineUIContainer>
<!-- Any (data bound) Control-->
</InlineUIContainer>
</Paragraph>
<!-- ... -->
</RichTextBlock>
</Page>
Since the PrintServiceProvider needs to make use of real screen infrastructure to physically measure the elements, we require each printable page to come with an (invisible) Canvas in its visual tree. That canvas should be called ‘printingRoot’. Alternatively, the printing framework itself could inject this element into the page. Here’s how the PrintingRoot of the main page in the sample app looks like:
<Grid>
<Canvas x:Name="printingRoot"
Opacity="0" />
<!-- Real content -->
<!-- ... -->
</Grid>
The process
When you navigate to a page in an app that supports printing, you call the RegisterForPrinting method of the PrintServiceProvider. This can be done in the OnNavigatedTo, or from a Button (like in the sample). The Visual Studio templates deliberately don’t have a PrintAppBarButtonStyle, and the Segoe Symbol UI font does not come with a print icon. That's because Micrsosoft wants you to use the Device Charm to start printing. I agree with that, but just in case, here’s a print button style:
<Style x:Key="PrintAppBarButtonStyle"
TargetType="ButtonBase"
BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId"
Value="PrintAppBarButton" />
<Setter Property="AutomationProperties.Name"
Value="Print" />
<Setter Property="FontFamily"
Value="Wingdings 2" />
<Setter Property="Content"
Value="x36;" />
</Style>
I used a button event handler instead of a command binding to the ViewModel. In most apps, printing is a GUI responsibility, so I don't feel guilty about the code behind. When registering, the page should provide a reference to itself (to find the PrintingRoot), and it should provide the type of print page as well as the viewModel or Model that will be bound to the print pages, like this:
this.printServiceProvider.RegisterForPrinting(this, typeof(MainPrintPage), this.DataContext);
The PrintServiceProvider first checks the presence of a PrintingRoot, then prepares the print output, and finally hooks event handlers to the events that will be raised by Windows to create the preview pages and to start printing, as explained in the Printing Quickstart.
The beef of the code is in the PreparePrintContent method. Here’s a detailed overview of what’s happening over there.
First it creates an instance of the print page, and applies the (view-) model to it:
var printPage = Activator.CreateInstance(this.printPageType) as Page;
printPage.DataContext = this.DataContext;
The forst page is created, and an empty paragraph is injected into an invisible RichTextBlock. That makes sure that all ‘real’ print content will overflow to the RichTextBlockOverflow:
firstPage = new PrintPage();
firstPage.AddContent(new Paragraph());
Then we loop over all paragraphs in the print page. We remove each paragraph, and hook it in the PrintingRoot to be measured. The actual height of the element will be used as LineHeight of the paragraph, because that’s the property that defines whether or not the element still fits on the current page. Then the paragraph is added to the first page.
// Move content from print page to print template - paragraph by paragraph.
var printPageRtb = printPage.Content as RichTextBlock;
while (printPageRtb.Blocks.Count > 0)
{
var paragraph = printPageRtb.Blocks.First() as Paragraph;
printPageRtb.Blocks.Remove(paragraph);
var container = paragraph.Inlines[0] as InlineUIContainer;
if (container != null)
{
// Place the paragraph in a new textblock, and measure it.
var measureRtb = new RichTextBlock();
measureRtb.Blocks.Add(paragraph);
PrintingRoot.Children.Clear();
PrintingRoot.Children.Add(measureRtb);
PrintingRoot.InvalidateMeasure();
PrintingRoot.UpdateLayout();
measureRtb.Blocks.Remove(paragraph);
// Apply line height to trigger overflow.
paragraph.LineHeight = measureRtb.ActualHeight;
}
firstPage.AddContent(paragraph);
};
Update: a Performance Analysis session on a remote Surface RT machine revealed that ARM devices have a big problem with the following line of code in the previous script:
measureRtb.Blocks.Remove(paragraph);
You should replace it by this:
measureRtb.Blocks.Clear();
End of Update.
When the user opens the print charm -by swiping on the right or by pressing the button- the printers are added to the list of devices in the devices charm. When the user taps on a device, the OS asks the app to generate its print (preview) pages. This is done by the PrintDocument_Paginate method. It produces output pages by adding these one by one to the collection as long as there’s content that overflows to the next page.
while (lastRTBOOnPage.HasOverflowContent && lastRTBOOnPage.Visibility == Windows.UI.Xaml.Visibility.Visible)
{
lastRTBOOnPage = AddOnePrintPreviewPage(lastRTBOOnPage, pageDescription);
}
The core logic of the loop is in the AddOnePrintPreview method. It applies a physical size to the print content by assigning a margin, and then sends it to the PrintingRoot to be measured. This triggers the overflow mechanism. Elements that don’t fit the page, are routed to the next one.
// Set paper width
page.Width = printPageDescription.PageSize.Width;
page.Height = printPageDescription.PageSize.Height;
Grid printableArea = (Grid)page.FindName("printableArea");
// Get the margins size
// If the ImageableRect is smaller than the app provided margins use the ImageableRect
double marginWidth = Math.Max(printPageDescription.PageSize.Width - printPageDescription.ImageableRect.Width, printPageDescription.PageSize.Width * HorizontalPrintMargin * 2);
double marginHeight = Math.Max(printPageDescription.PageSize.Height - printPageDescription.ImageableRect.Height, printPageDescription.PageSize.Height * VerticalPrintMargin * 2);
// Set-up "printable area" on the "paper"
printableArea.Width = page.Width - marginWidth;
printableArea.Height = page.Height - marginHeight;
// Add the (newly created) page to the printing root which is part of the visual tree and force it to go
// through layout so that the linked containers correctly distribute the content inside them.
PrintingRoot.Children.Add(page);
PrintingRoot.InvalidateMeasure();
PrintingRoot.UpdateLayout();
// Find the last text container and see if the content is overflowing
textLink = (RichTextBlockOverflow)page.FindName("continuationPageLinkedContainer");
This routine also adds a page number to each page:
this.pageNumber += 1;
TextBlock pageNumberTextBlock = (TextBlock)page.FindName("pageNumber");
if (pageNumberTextBlock != null)
{
pageNumberTextBlock.Text = string.Format("- {0} -", this.pageNumber);
}
Example
Here’s an example of the framework in action. I created a ListBox bound to a list from the ViewModel. It renders nice, even in a more advanced version with a data template and a converter:
<!-- Databound content with data template and converter -->
<Paragraph>
<InlineUIContainer>
<Border BorderBrush="Green"
BorderThickness="2"
Margin="0 4">
<ListBox ItemsSource="{Binding TrekkieQuotes}">
<ListBox.Resources>
<local:StringFormatConverter x:Key="sfc" />
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource sfc}, ConverterParameter='* {0}'}"
Margin="0" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</InlineUIContainer>
</Paragraph>
Here you see at the bottom of the print preview page that the ListBox is overflown to the next one, and the resulting XPS document:



Strange new worlds, still to explore
I know that there are still a couple of issues with this code. If a single inline element is higher than the printed page, then it’s not rendered and you end up with an empty page. A future version of the PrintServiceProvider should e.g. wrap it in a Grid. In the current version, the measurement is done very early in the workflow: when registering. So when the user, before he prints, changes a bound value that has an impact on the height of the element, then the new height is probably ignored. I've written the code this way, because calls to the PreparePrintContent in the event handlers (e.g. during pagination) were causing cross-threading issues (probably caused by the fact that the print service provider is actually a DependencyObject since it inherits from Page).
The current version however seems to cover all printing needs for the Store apps I’m currently working on. That's good enough. After all, I just lost two weeks to do something that I expected to deliver in two hours. Anyway, I promise to update the code here whenever I have a new version.
Code
Here’s the code, it was written with Visual Studio 2012 Express (well, except for the class diagram): U2UConsult.Win8.PrintingSample.v2.zip (170.55 kb)
Enjoy and ... live long and prosper,
Diederik
- Posted by Diederik Krols on January 8, 2013
This article describes a couple of techniques that you can apply to dynamically change the look-and-feel of data-bound XAML controls in a Windows 8 Store App. You’ll be introduced to value converters, style selectors, template selectors, and the XamlReader class. I created a light-weight MVVM app that displays a list of beers. Although all items belong to the same class –Beer- they will be displayed differently. Here’s how the sample app looks like:

Using a Value Converter
Dependency properties of a XAML control can be directly bound to properties of the ViewModel. Sometimes a conversion of value and/or data type needs to take place; and that’s exactly what a ValueConverter does. A value converter is a class that implements the IValueConverter interface, with just Convert and ConvertBack functions. Here's an example of a string-to-string converter that translates official beer colors into HTML named colors (the Beer Color Meter app in the Windows Store has a much more advanced version of this):
public class BeerColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
switch (value.ToString())
{
case "Yellow":
return "LemonChiffon";
case "Straw":
return "Wheat";
case "Gold":
return "GoldenRod";
case "Amber":
case "LightCopper":
case "Copper":
return "Peru";
case "LightBrown":
return "Chocolate";
case "Brown":
return "Brown";
case "DarkBrown":
return "darkRed";
case "VeryDarkBrown":
return "SaddleBrown";
case "Black":
return "Black";
default:
return "Lime";
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
Just define an instance of the converter as a resource:
<Page.Resources>
<local:BeerColorConverter x:Key="BeerColorConverter" />
</Page.Resources>
And use it in the Binding:
<DataTemplate>
<TextBlock Foreground="{Binding Color, Converter={StaticResource BeerColorConverter}}"
FontWeight="SemiBold"
Margin="2">
<Run Text="{Binding Name}" />
<Run Text=" is "
Foreground="Silver"
FontWeight="Normal" />
<Run Text="{Binding Category}"
Foreground="Silver"
FontWeight="Normal" />
</TextBlock>
</DataTemplate>
Unfortunately the Store App Runtime doesn't ship with MultiBinding, and bindings don't come with a StringFormat option. That restricts the usage of a value converter, at least when compared to WPF. When populating a TextBlock, you can avoid some of these restrictions by cutting it up in individual Run elements.
Using a Style Selector
One way of dynamically styling items in a XAML items control, is with a StyleSelector. This allows you to apply a style for each item in a collection, based on custom logic. This seems to be the only way to create a dynamic style in Metro, due to the absence of DataTriggers. All you need to do is create a subclass of the StyleSelector class and implement the SelectStyleCore method. The bound item is the first parameter, the item's style is the return value. Here's a small example on how to modify the style for a list view item. Belgian beers (category name contains ‘Belgian’ or ‘Flemish’) will be decorated with a golden border:
public class BeerStyleSelector : StyleSelector
{
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Beer beer = item as Beer;
// Default Style
if (!(beer.Category.Contains("Belgian") || beer.Category.Contains("Flemish")))
{
return null;
}
// Custom Style
Style style = new Style(typeof(ListViewItem));
style.Setters.Add(new Setter(ListViewItem.BorderBrushProperty, new SolidColorBrush(Colors.Gold)));
style.Setters.Add(new Setter(ListViewItem.BorderThicknessProperty, new Thickness(2.0)));
return style;
}
}
Again, the class containing the logic should be defined as a resource:
<Page.Resources>
<DataTemplate x:Key="DefaultDataTemplate">
<StackPanel Background="DimGray"
Height="160"
Width="160"
Margin="4">
<TextBlock Text="{Binding Name}"
Foreground="{Binding Color, Converter={StaticResource BeerColorConverter}}"
FontWeight="SemiBold"
FontSize="18"
HorizontalAlignment="Center"
Margin="4" />
<TextBlock Text="{Binding Category}"
Foreground="Silver"
FontSize="18"
HorizontalAlignment="Center"
TextAlignment="Center"
TextWrapping="Wrap"
Margin="2" />
</StackPanel>
</DataTemplate>
<local:BeerStyleSelector x:Key="BeerStyleSelector" />
</Page.Resources>
You can then assign the ItemContainerStyleSelector to an instance of it:
<ListView ItemsSource="{Binding BelgianBeers}"
ItemContainerStyleSelector="{StaticResource BeerStyleSelector}">
<!-- ... -->
</ListView>
When using a Style Selector, you’re restricted to modifying Dependency Properties.
Using a Data Template Selector
With a DataTemplate you can assign a look-and-feel to an item based on its type. Sometimes that’s just not good enough. Using a DataTemplateSelector you can choose or generate a DataTemplate based on the entire data object and its container – not just on its type. To create a template selector, create a class that inherits from DataTemplateSelector and override the SelectTemplateCore method. Once your class is defined you can assign an instance of the class to the template selector property of your element.
The business logic could be as simple a selecting an existing template from a resource, like this.DefaultTemplate in the following code snippet. But the entire template could also be generated on the spot through a XamlReader. This class allows you create a XAML element by concatenating it into a string; in many cases that’s a lot more convenient than talking to the object model in C#. The following code creates a colored stackpanel including a Belgian flag for the Belgian beers, and applies the default template to the rest. It also shows how to use a value converter programmatically:
public class BeerTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
Beer beer = item as Beer;
// Default Template
if (!(beer.Category.Contains("Belgian") || beer.Category.Contains("Flemish")))
{
return this.DefaultTemplate;
}
// Custom Template
BeerColorConverter converter = new BeerColorConverter();
string backGroundColor = converter.Convert((item as Beer).Color, null, null, null).ToString();
string template = @"
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
<Grid Background='" + backGroundColor + @"' Width='160' Height='160' Margin='4'>
<StackPanel>
<TextBlock Text='{Binding Name}' FontWeight='SemiBold' FontSize='18' Margin='4' Foreground='White' HorizontalAlignment='Center' />
<TextBlock Text='{Binding Category}' Margin='2' FontSize='18' Foreground='White' HorizontalAlignment='Center' />
</StackPanel>
<Image Source='../Assets/belgianFlag.png' Margin='4' HorizontalAlignment='Right' Stretch='None' VerticalAlignment='Bottom' />
</Grid>
</DataTemplate>";
return XamlReader.Load(template) as DataTemplate;
}
}
Again, register the class containing the logic as a resource:
<Page.Resources>
<local:BeerTemplateSelector x:Key="BeerTemplateSelector"
DefaultTemplate="{StaticResource DefaultDataTemplate}" />
</Page.Resources>
Then use an instance as ItemTemplateSelector:
<ItemsControl ItemsSource="{Binding BelgianBeers}"
ItemTemplateSelector="{StaticResource BeerTemplateSelector}">
<!-- ... -->
</ItemsControl>
Source Code
Here’s the sample project, it was written with Visual Studio 2012 Express Edition: U2UConsult.Win8.DynamicXaml.zip (89.56 kb)
Enjoy!
Diederik
- Posted by Diederik Krols on December 6, 2012
This article explains how to build custom controls for Windows Store apps, using XAML and C#. Custom controls are the most powerful controls in the XAML department. Once you know how to design and build these, you’ll have no problems with their alternatives: user controls, derived controls, and extended controls. Let’s start with a definition: a custom control is a reusable templatable control that comes with a generic.xaml file and some code behind. Generally a custom control is stored in its own assembly to make it reusable in multiple apps. As a developer, you decorate a custom control with properties, methods, events, and a default style. The users of the control –developers who use your custom control in their apps- should live with the code behind, but are free to completely restyle the XAML part.
Hello again, Simple Slider
Almost a year ago, I built a custom slider control in an earlier version of Visual Studio and the Windows Runtime. A lot has changed since then – fortunately for the better. For this article, I decided to redo that slider. I’ll stick to its original anatomy: a horizontal slider is just a draggable Thumb in a Border. While dragging, a Rectangle is drawn to fill the space at the left side of the Thumb:

Getting Started
Recent versions of Visual Studio 2012 –including the free Express edition- come with a template to create a custom control. All you need to do to get started is adding a new item of the type ‘Templated Control’ to your project:

It will create the code behind file as well as the generic.xaml in the Templates folder.
Properties
A custom control directly inherits from Control itself, the mother of all controls. It immediately comes with a couple of useful properties like Height, Width, and Visibility. Of course you would want to add your own properties. A slider control e.g. should have at least properties to represent its minimum, maximum and current value. Since we’re interested in data binding, we will implement these as DependencyProperty instances. Using the propdp code snippet, you can rapidly define a property and provide its name, type, default value, and the function that will be called when the value changes. In the case of our slider, we are definitely interested in knowing when the value changed: it’s the sign to redraw the control. Here’s how the definition of the Value property looks like:
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(double), typeof(Slider), new PropertyMetadata(0.0, OnValueChanged));
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static void OnValueChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
// Recalculate part sizes.
// ...
}
Styling
The generic.xaml file will contain the default style for the control. While typing in that code, you have intellisense but no designer support. Here’s how the basic slider style looks like in XAML.
<Style TargetType="local:Slider">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:Slider">
<Grid>
<Border Height="40"
VerticalAlignment="Stretch"
Background="Gray"
Margin="0"
Padding="0"
BorderThickness="0" />
<Canvas Margin="0"
Height="40">
<Rectangle x:Name="PART_Rectangle"
Height="38"
Fill="SlateBlue"
Margin="0 1" />
<Thumb x:Name="PART_Thumb"
Background="LightSteelBlue"
Width="40"
Height="40"
Margin="0" />
</Canvas>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The default style is assigned to the control in its constructor:
public Slider()
{
this.DefaultStyleKey = typeof(Slider);
}
This is a screenshot of the custom slider:

In the style definition, the Thumb and Rectangle controls were given an x:Name value. This is because we need to manipulate them when (re)drawing the slider from code behind. That puts some constraints on the ‘templatability’ of the custom control: no matter how the designer wants to make the control look like, he or she needs to make sure that the template contains a Thumb and a Rectangle with the expected name. Fortunately you have some ways to notify these constraints to the designer. First there is a naming convention that specifies that the element’s name should start with ‘PART_’. More important is the fact that you can decorate the class with TemplatePart attributes. These will be recognized by tools like Expression Blend. Here’s the definition in C#:
[TemplatePart(Name = ThumbPartName, Type = typeof(Thumb))]
[TemplatePart(Name = RectanglePartName, Type = typeof(Rectangle))]
public sealed class Slider : Control
{
private const string ThumbPartName = "PART_Thumb";
private const string RectanglePartName = "PART_Rectangle";
// ...
}
You find the named parts with the GetTemplateChild method. When using your control, a designer could have ignored the expected parts, so make sure you look them up defensively:
protected override void OnApplyTemplate()
{
this.thumb = this.GetTemplateChild(ThumbPartName) as Thumb;
if (this.thumb != null)
{
this.thumb.DragDelta += this.Thumb_DragDelta;
}
// ...
base.OnApplyTemplate();
}
This code is typically written in an override of the OnApplyTemplate method. Don’t use the Loaded event. The visual tree of a templated control might be still incomplete at that stage.
Visual State Management
Depending on its state (enabled, disabled, focused, snapped, etc.) a control will look and feel slightly or drastically different. This is where the VisualStateManager comes in action. The visual state manager invokes transformations when the state of the control changes. E.g. if the control is disabled, it will recolor it in fifty shades of gray. The states and transformations can be described declaratively in XAML:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Thumb"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="LightSteelBlue" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Rectangle"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0"
Value="SlateBlue" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Thumb"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0"
Value="LightGray" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Rectangle"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0"
Value="DimGray" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
When the control is used inside a LayoutAwarePage, then it will listen automagically to state changes. But we can’t make assumptions on how and where our control is going to be used. Fortunately, in code behind it is possible to trigger the visual state manager programmatically. Here’s an example where we disable the control from C#:
private void Slider_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.IsEnabled)
{
VisualStateManager.GoToState(this, "Normal", true);
}
else
{
VisualStateManager.GoToState(this, "Disabled", true);
};
}
Here's the result when the app is running:

Again, this puts some constraints on the templatability of the control: the designer has to make sure that the visual states that we invoke programmatically exist in the overridden style. Again we as developer can document these constraints by decorating the class with TemplateVisualState attributes:
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
public sealed class Slider : Control
{
// ...
}
Templating
The style in the generic.xaml is just a default style. It can be completely overridden, as long as the TemplatePart and VisualState constraints are respected. Here’s an example of how to give the default slider a brand new jacket:
<cc:Slider>
<cc:Slider.Template>
<ControlTemplate TargetType="cc:Slider">
<Grid>
<Border Height="80"
VerticalAlignment="Stretch"
Background="Transparent" />
<Line VerticalAlignment="Center"
X1="0"
Y1="0"
X2="3000"
Y2="0"
StrokeThickness="7"
Stroke="White"
StrokeDashArray="1" />
<Canvas Margin="0"
Height="80">
<Rectangle x:Name="PART_Rectangle"
Height="12"
Canvas.Top="34"
Fill="DarkSlateBlue" />
<Thumb x:Name="PART_Thumb"
Width="80"
Height="80">
<Thumb.Template>
<ControlTemplate>
<Image Source="Assets/Pacman.png"
Height="80" />
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Canvas>
</Grid>
</ControlTemplate>
</cc:Slider.Template>
</cc:Slider>
Here’s how it looks like:

Events
To add an event to your control, just declare it and raise it at the appropriate time. I have decorated the slider with an event ‘BoundHit’ that is raised when the value hits minimum or maximum:
public event EventHandler BoundHit;
private void OnBoundHit(EventArgs e)
{
if (this.BoundHit != null)
{
this.BoundHit(this, e);
}
}
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
{
// ...
this.OnBoundHit(EventArgs.Empty);
// ...
}
The page that hosts the slider can now react to it:
<cc:Slider BoundHit="ccSlider_BoundHit" />
This is what it does in the attached sample project:

Admit it: you never saw a slider do this ;-)
From Slider to Gauge
This is basically all you need to know to roll your own custom controls. If you don’t believe me, feel free to dive into the attached source code of the following Radial Gauge control. It’s a new version of a control I built some months ago: you find its story here. Since then the .NET framework improved and so did my code. Now the radial gauge may be a bit more complex than the slider: there are some animations and converters involved. But apart from that, it only contains stuff we covered in this article: a default style in generic.xaml, an override of OnApplyTemplate, and a TemplatePart - no visual states. Functionally all that a radial gauge does is rotating a needle when its value changes. That basically makes it a templated … slider. Anyway if you’re looking for a basic radial gauge with a color scale, here you have one:

Alternatives
User Controls
Custom controls are the most powerful controls to build, although not always the most developer-friendly: you don’t have support from Visual Studio’s designer when defining the style. Fortunately this is not the case with User Controls. For more details, check my previous blog item.
Derived Controls
Another alternative is to create a Derived Control, by creating a subclass of an existing control. You can then add properties, methods, and events at will, or override some of its methods. You find examples of derived controls in the Callisto framework. Among other useful controls, that framework contains the DynamicTextBlock control, a textblock that does trimming at word boundary. It inherits from ContentControl:
public class DynamicTextBlock : ContentControl
{
// ...
}
Another example of a derived control can be found in the WinRT XAML Toolkit: the WatermarkTextBox inherits from the native TextBox, and adds a watermark.
Extended Controls
Using Attached Properties, you can add extra properties to existing instances, e.g. of controls. This allows you to create new controls without defining control subclasses. Again Callisto as well as WinRt XAML Toolkit have examples of such extensions. You’ll remember the TextBoxValidationExtensions from my blog post on input validation. These extensions allow you to add validation logic to a native textbox:
<TextBox ext:TextBoxValidationExtensions.Format="NonEmptyNumeric"
ext:TextBoxValidationExtensions.InvalidBrush="Salmon" />
You can take the concept of attached properties one step further to create a Behavior, like the ‘select-all-on-focus’ from another previous blog post:
<TextBox Text="Eh~ Sexy lady. Op op op op oppan Gangnam Style.">
<WinRtBehaviors:Interaction.Behaviors>
<local:SelectAllOnFocusBehavior SelectAllOnFocus="True" />
</WinRtBehaviors:Interaction.Behaviors>
</TextBox>
The attached solution contains the source code for all mentioned alternative controls. Here’s how the corresponding sample page looks like:

Code Code Code
Here’s the full source code of all the featured controls in this article (o, and a free forward-button style). It was written in Visual Studio 2012 Ultimate, without SP1: U2UConsult.CustomControls.Sample.zip (256.78 kb).
Enjoy!
Diederik