Creating touch-based rotation in Windows 8 XAML Store apps

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 casesIn 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 casesI 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

Semantic Zoom and LINQ: Better Together

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> As you see, you don’t need special infrastructure to populate a two-level semantic zoom. All bindings can be fulfilled with just your ViewModels and a little LINQ.   Here’s the code: U2UConsult.Win8.SemanticZoomWithLinq.V2.zip (531.35 kb)   Enjoy! Diederik  

Avoiding hard times with the soft keyboard

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

Printing from MVVM XAML Windows 8 Store apps - the final frontier

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  

Using Dynamic XAML in Windows 8 Store Apps

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

Building Custom Controls for Windows 8 Store apps

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

Building User Controls for Windows 8 Store apps

This article describes how to build user controls for XAML-based Windows 8 Store apps. User controls –or composite controls- are the easiest controls that you can roll yourself, since they're defined in plain XAML and come with design-time support in Visual Studio. Basically a user control is just a XAML panel on which you drag and drop a group of controls that belong together. You create a user control only if you want to reuse that XAML panel in multiple places in your app. If you want to reuse the group of controls in more than one app, then you store the user control in a separate library. Typical examples of user controls are a media player button bar (with play, pause and stop buttons), a paging control (with next, previous, goto buttons etc.) and an address panel (with labels, textboxes, and comboboxes for street, number, zip code, city, country, and so on). The sample control for this article will be a new version of my EnhancedSlider. It's a plain vanilla slider that is surrounded with some extra textblocks. The slider comes with support for direct input through a textbox that is enabled by a button. I've been using that group of controls quite often lately, so I decided to package it as a reusable user control. Here's how the original looks like, it started as a non-reusable bunch of controls on the main page of an app: Here’s how to roll your own user control. In a Windows Store app project –or a separate library- add an item of the type ‘User Control’. Visual Studio will create a class for you. It inherits from UserControl and comes with a XAML file and an associated code behind file. You can drag and drop individual controls into the XAML design surface. Here's how the simplified XAML for the enhanced slider looks like: <UserControl x:Class="U2UConsult_UserControls.EnhancedSlider"> <Grid> <TextBlock HorizontalAlignment="Left" /> <StackPanel HorizontalAlignment="Right"> <Button Style="{StaticResource EditRoundButtonStyle}" /> <TextBox /> <TextBlock /> </StackPanel> <Slider Grid.Row="1" /> <TextBlock HorizontalAlignment="Left" Grid.Row="2" /> <TextBlock HorizontalAlignment="Right" Grid.Row="2" /> </Grid> </UserControl> With a little luck the Visual Studio Designer will support you, but don't expect too much from it. In many cases you'll end up with a blank surface - but at least you have IntelliSense in the XAML and an operational properties editor: Your next step is to connect control properties through bindings. Use the ElementName property to define the source of the binding. In the EnhancedSlider, I hooked the Text property of the surrounding text controls to the corresponding properties of the central slider: <Slider x:Name="slider" /> <TextBlock Text="{Binding Minimum, ElementName=slider}" /> <TextBlock Text="{Binding Maximum, ElementName=slider}" /> The XAML is ready. Time to focus on the code behind. We embrace encapsulation, so your user control should behave as a black box to its hosting page or control. That page shouldn't see the individual controls, but only talk to the composite. In code behind, decorate your user control with the appropriate properties. Regular properties don't interact with the binding engine, you have to use Dependency Properties. The EnhancedSlider has the following properties: Minimum, Maximum, Value, Header, and ValueSuffix. ValueSuffix represents the unit measure and is displayed in a separate textblock in the upper right corner of the control. I’ve been trying very hard to use a StringFormatConverter in the textbox displaying the Value. That value should only be formatted when the texbox is disabled (when it looks like a label), not when the user is typing in it. Unfortunately, changing the converter or even the converter parameter programmatically doesn't work because bindings are immutable. So I had to pull the formatting out of the textbox and into an other control as a suffix. It will stil do the job in most scenario's... Anyway, here’s one example of a dependency property (tip: use the propdp code snippet to create these): public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(int), typeof(EnhancedSlider), new PropertyMetadata(0)); public int Minimum { get { return (int)GetValue(MinimumProperty); } set { SetValue(MinimumProperty, value); } } All you need to do now is to bind the subcontrol’s properties to the user control's dependency properties. You may be tempted to set the DataContext of the control to itself (with RelativeSource Self as binding source) to get this done, but then you loose the ability to bind it to something else (e.g. a ViewModel). It's better to give the control a name, and use yet another ElementName in the binding: <UserControl x:Class="U2UConsult_UserControls.EnhancedSlider" x:Name="userControl"> ... <Slider x:Name="slider" Minimum="{Binding Minimum, ElementName=userControl}" Maximum="{Binding Maximum, ElementName=userControl}" Value="{Binding Value, Mode=TwoWay, ElementName=userControl}" /> ... </UserControl> And there we are: we just built our own a reusable composite control. If you want to use the control inside a page or another control, all you need to do is declare the namespace in the hosting container: <Page x:Class="U2UConsult.UserControls.Sample.MainPage" xmlns:uc="using:U2UConsult_UserControls" > ... </Page> You're ready to use the control in the page. Don’t forget to set the bindings with the ViewModel: <uc:EnhancedSlider Value="{Binding Roasted, Mode=TwoWay}" Header="Roasted" Maximum="1000" Foreground="Orange" ValueSuffix=" civilizations" /> Again, don't expect too much help from the Visual Studio Designer. Here's how my main page looks at design time: Fortunately at runtime everything comes through. Here’s a screen shot of the attached sample application: The app contains two projects: a GUI, and a library with the user control. Oh, there’s something you should know about storing user controls in a separate assembly: that assembly may not have dots in its name. I assume that’s a bug that will be fixed very soon. Here’s the code for the sample solution. It was written in Visual Studio 2012 Express: U2UConsult.UserControls.Sample.zip (132.73 kb) Enjoy! Diederik

Using Behaviors in Windows 8 Store Apps

This short article explains how to write and use behaviors in Windows 8 Store apps. Behaviors were introduced a couple of yahren ago, in Blend for Silverlight 3. Later on they also found their way to WPF and WP7. Technically, behaviors are nothing but an implementation of Attached Properties. Attached properties allow you to define properties in a parent element, and then let all child elements use their own value for these properties. The classroom examples of attached properties are the Grid.Row and Grid.Column that you can assign to any XAML element. The properties themselves are defined as Dependency Properties in the Grid class, but in your XAML you can assign individual Grid.Row and Grid.Column values to every StackPanel, TextBox, or whatever control. As already mentioned, Behaviors are an implementation of Attached Properties. In a Behavior, the values of the attached properties are used to configure one or more event handlers. The Behavior then hooks these event handlers to the control to which it is attached in XAML. This way you can e.g. create an encapsulated reusable 'AutoComplete' behavior that runs code when the text in a TextBox or ComboBox changes, without creating a separate control, without writing code-behind, and without modifying your viewmodels. On top of that, Behaviors can be combined. If you would like a textbox that does validation, selects all text when it receives the focus, and auto completes user input, then it suffices to create three separate behaviors, and apply these to a regular textbox. Please don’t build your own ValidatingSelectAllOnFocusAutoCompleteTextBox custom control. I hope I just convinced you that behaviors are really useful in the XAML world. Now here’s the bad news: behaviors are not available for Windows 8 Store apps. But don't panic: @LocalJoost resurrected behaviors and made the code available through CodePlex and Nuget. If you want to use behaviors in a Windows 8 Store app, all you need to do is link the WinRTBehaviors assembly to your project. As you know, I actually prefer embedding the source code directly: Let’s create the simplest of all behaviors: one that makes a textbox select all its content when it receives the focus, so you can easily overwrite it. The behavior is configured through a SelectAllOnFocus property, a Boolean.  Here’s how it goes: Create a class and let it derive from Behavior<T> where T is the type of Control to which you want the behavior to be attached. In our sample, T is TextBox: public class SelectAllOnFocusBehavior : Behavior<TextBox> { // ... } Define and register the attached dependency properties, and provide the standard Get and Set accessors. These accessors are used to access the property values in code behind: public static readonly DependencyProperty SelectAllOnFocusProperty = DependencyProperty.RegisterAttached ( "SelectAllOnFocus", typeof(bool), typeof(SelectAllOnFocusBehavior), new PropertyMetadata(false) ); public static bool GetSelectAllOnFocus(DependencyObject obj) { return (bool)obj.GetValue(SelectAllOnFocusProperty); } public static void SetSelectAllOnFocus(DependencyObject obj, bool value) { obj.SetValue(SelectAllOnFocusProperty, value); } Override the OnAttached and OnDetaching event handlers. The decorated control is available as a strongly typed AssociatedObject of type T. Make sure you unregister event handlers in OnDetaching to avoid memory leaks: protected override void OnAttached() { base.OnAttached(); if (AssociatedObject != null) { if (GetSelectAllOnFocus(this)) { AssociatedObject.GotFocus += AssociatedObject_GotFocus; } } } protected override void OnDetaching() { if (AssociatedObject != null) { if (GetSelectAllOnFocus(this)) { AssociatedObject.GotFocus -= AssociatedObject_GotFocus; } } base.OnDetaching(); } All scaffolding is in place now. Just implement the core business logic: private void AssociatedObject_GotFocus(object sender, RoutedEventArgs e) { if (AssociatedObject != null) { AssociatedObject.SelectAll(); } } That’s all. For the sake of simplicity, I skipped the OnPropertyChanged handling in this article. You can define a handler as the second parameter of the DependencyProperty.RegisterAttached call. That handler will be called when a dependency property was modified, e.g. through data binding You’ll find some more elaborate examples here. All you now need to do is attach the behavior to a XAML element (a TextBox in this case) and set the properties. Note that you have to define a behavior collection and fill it with behavior instances, like this: <TextBox Text="Joined the Dark Side, I have." FontSize="18" Margin="8"> <WinRtBehaviors:Interaction.Behaviors> <local:SelectAllOnFocusBehavior SelectAllOnFocus="True" /> </WinRtBehaviors:Interaction.Behaviors> </TextBox> The following code does NOT work: <TextBox Text="Joined the Dark Side, I have." FontSize="18" Margin="8" local:SelectAllOnFocusBehavior SelectAllOnFocus="True" />   Here are some screenshots of the attached sample app. The first textbox has SelectAllOnFocus to true, its whole content is selected when it receives the focus: The second textbox has SelectAllOnFocus to false, no text is selected, the caret sits in front of the text: Here’s the code, it was written in Visual Studio 2012 Express: U2UConsult.WinRTBehaviors.Sample.zip (126.55 kb). Enjoy!Diederik

Input Validation in Windows 8 Store apps

This article is an introduction to input validation in Windows Store apps. That sounds ambitious. On one hand, some apps really need decent data entry validation. On the other hand, the Store app runtime does not come with Data Annotations, and it does not come with the IDataErrorInfo and INotifyDataErrorInfo interfaces. In an ideal MVVM XAML world we would just define data constraints in the ViewModel, and then let the binding mechanism automatically update the Views. Controls would display their ErrorTemplate and an informative localized message as long as their respective value is invalid. The current Store runtime supports almost nothing of this out of the box, so let's expand the box. The View Let's first test drive some existing controls that allow validation in the View layer. Filip Skakun's WinRT XAML Toolkit on CodePlex has a couple of controls and extensions that faciliate input validation:- The WatermarkTextBox is a TextBox control with a watermark. OK, it doesn't really validate, but you can use the watermark text to provide guidance to the user.- TextBoxValidationExtensions is a set of extensions that allow to specify the format of the requested text input as well as brushes to use to highlight a TextBox with valid or invalid Text.- The NumericUpDown allows you to display and manipulate a numeric value through direct text input, buttons, or cool swipe manipulations. It derives from RangeBase (like the Slider) so it’s impossible to enter an illegal value. Here's how these controls look like in full action (for the moment, just ignore the validation messages at the bottom): If -just like me- you're reluctant to link and deploy giant dll’s with your app, then I have good news. You can easily pluck the relevant classes right out of the source code, and embed these in your app. That's exactly what I did: I do the same with other frameworks and toolkits. After all, if your app only uses RelayCommand and EventAggregator, you're not going to link to the entire MVVMLight *and* Caliburn.Micro, are you ? I know there are pros and cons to this approach, but you get good code samples to learn from, you can tweak the code to better suit your app’s need, and you have the full source code in the project. To a lot of customers, dependencies to large foreign dll’s are a real showstopper. Let's come back to the topic. Since the WaterMarkTextBox inherits from TextBox, the ValidationExtensions also apply to it. Here’s an example of the ‘Age’ textbox from the sample app. It’s mandatory, numeric, and it comes with an explanatory watermark. You can’t specify a whole ErrorTemplate (yet ?), but you can specify background colors for the valid and invalid states. That's a lot better than the TextBox that ships with the runtime: <ctl:WatermarkTextBox Text="{Binding Age, Mode=TwoWay}" WatermarkText="Enter age here. Required numeric field." Extensions:TextBoxValidationExtensions.Format="NonEmptyNumeric" Extensions:TextBoxValidationExtensions.InvalidBrush="#FFCC99" /> My favorite input control of the WinRT Xaml Toolkit is the NumericUpDown. It allows you to enter a value within a range. You can type directly in a TextBox, or press the up and down buttons. But you can also change the value through manipulation: tap on the textbox (or click left mouse button) and slide/drag upward to increase, or downward to decrease. That's a very intuitive and addictive gesture! The control also has a built-in value bar (like in Excel). Here’s how the XAML looks like: <ctl:NumericUpDown Value="0" Minimum="0" Maximum="15" SmallChange="1" ValueFormat="F0" ValueBarVisibility="Collapsed" /> The ViewModel That went easy, right? Let’s switch to second gear, and define data constraints in the ViewModel. For that, we need to resurrect ye olde IDataErrorInfo: namespace System.ComponentModel { public interface IDataErrorInfo { string Error { get; } string this[string columnName] { get; } } } I implemented the interface in the ViewModel in a classic straightforward way: the Error property is populated by concatenating the error messages from the property iterator: public string Error { get { /// Note from the author: there's an opportunity for refactoring here. I know. Really. string error = string.Empty; string property = this["FirstName"]; if (!string.IsNullOrEmpty(property)) { error += property + Environment.NewLine; } property = this["LastName"]; if (!string.IsNullOrEmpty(property)) { error += property + Environment.NewLine; } property = this["Age"]; if (!string.IsNullOrEmpty(property)) { error += property + Environment.NewLine; } return error.Trim(); } } The iterator allows for the appropriate validation messages: public string this[string columnName] { get { switch (columnName) { case "FirstName": if (string.IsNullOrEmpty(firstName)) { return "First Name is required."; } return string.Empty; case "LastName": if (string.IsNullOrEmpty(lastName)) { return "Last Name is required."; } return string.Empty; case "Age": if (string.IsNullOrEmpty(age)) { return "Age is required."; } if (!IsNumeric(age)) { return "Age should be numeric."; } return string.Empty; default: return string.Empty; } } } Here you see e.g. that the Age TextBox spawns another error message than in the previous screen shot: The (re-)calculation of the Error property is triggered by an event handler on PropertyChanged: public MainPageViewModel() { this.PropertyChanged += MainPageViewModel_PropertyChanged; } private void MainPageViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName != "Error" && e.PropertyName != "HasErrors") { this.OnPropertyChanged("Error"); this.OnPropertyChanged("HasErrors"); } } A little voice keeps telling me that it may well be possible to integrate most of the code into BindableBase, to form a DataErrorInfoBase or so. But I decided to ignore that little voice for the moment. I decorated the ViewModel with an HasError property to facilitate data binding: public bool HasErrors { get { return !string.IsNullOrEmpty(this.Error); } } The ‘thank you’ message in the sample app only appears when the whole ViewModel is valid: <TextBlock Text="Thank you very much. Existence as you know it, is over now." Visibility="{Binding HasErrors, Converter={StaticResource ReverseBooleanToVisibilityConverter}}"/> Here’s how it looks like: Conclusion Frankly, I just got closer to WPF validation than I expected and with a lot less code than I expected. This is a relief. I now strongly believe we will have enterprise level input validation in a very near future. The Code Here's the code for the sample app. It was written with Visual Studio 2012 Express: U2UConsult.Win8.TextBoxSample.zip (145.85 kb) Enjoy! Diederik

Enhancing the Win8 Slider experience

This article describes a way to enhance the user friendliness of a standard slider control in a Windows 8 Store App. Problem In a touch oriented application, we often allow -or force- the user to set the value for an integer or an enumeration through a slider control. In most cases this is more comfortable and less error prone than working with the soft keyboard. Unfortunately it’s not always ideal: if the range of values becomes too huge, or the slider becomes too narrow (e.g. when in portrait or snapped mode), then it becomes too difficult for the user to position the slider at the correct value. In this scenario, a textbox is a much more appropriate input control. This article proposes a UX design –and implementation- that offers the best of both worlds, and lets the end user decide on it. Proposed solution A slider control never walks alone: it’s always surrounded by controls that display its topic, its minimum and maximum values, and its current value, like this: So there’s always a label that displays the current value. Wouldn’t it be nice to replace that simply it by a textbox? This gives the end user direct access to the desired value: Now this may look confusing, so by default we allow only input through the slider and display the current value as a label. Next to the label, we add a small button to activate the ‘direct input mode’, like this: When pressed, the button activates the direct input mode. The label transforms into a textbox, and if there's no keyboard attached, we pop up the soft keyboard (preferably a numeric one): When the user leaves the textbox by tapping somewhere else on the screen, the slider is updated - after validation of the input. This article ignores the validation part. Implementation Here's how the sample solution was implemented. I didn’t want to bring too much extra controls in the equation, so the current value is *always* displayed in the same textbox. In ‘slider input’ mode this textbox is simply disabled. It’s the style that makes it look like a textblock – default theme foreground, no border. Here's the relevant modification to the standard style: <VisualState x:Name="Disabled"> <Storyboard> <!-- ... --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationForegroundThemeBrush }" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="BorderElement"> <DiscreteObjectKeyFrame KeyTime="0" Value="0" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> The look-and-feel of the small button is also defined by a style, a copy of the standard AppBarButtonStyle - just a bit smaller, and without a label. All styles are stored in a resource dictionary customstyles.xaml. The textbox’s text is bound to the sliders value. It also favors the numeric keyboard: <TextBox x:Name="TheTextBox" Text="{Binding Value, Mode=TwoWay, ElementName=TheSlider}" InputScope="Number" IsEnabled="False" LostFocus="TheTextBox_LostFocus" KeyUp="TheTextBox_KeyUp" TextAlignment="Right" Style="{StaticResource LabelTextBoxStyle}" /> The button’s only job is to enable the textbox and give focus to it. In most cases -I've noticed some buggy behavior here- that will pop up the numeric soft keyboard immediately: private void SliderButton_Click(object sender, RoutedEventArgs e) { this.TheTextBox.IsEnabled = true; this.TheTextBox.Focus(FocusState.Programmatic); } The textbox updates the current value when it loses focus, by updating the binding. We don't have to write code for that: it's the default behavior in Modern UI. However we still need to disable the textbox: private void TheTextBox_LostFocus(object sender, RoutedEventArgs e) { this.TheTextBox.IsEnabled = false; } Although it’s not a Modern UI standard, I still expect the value to be committed by pressing the Enter key, so here’s the routine to do that. Remember, it’s optional: private void TheTextBox_KeyUp(object sender, KeyRoutedEventArgs e) { if (e.Key == Windows.System.VirtualKey.Enter) { this.TheTextBox.IsEnabled = false; } } I was also thinking of implementing some undo logic behind the Escape key, but then discovered that there is no Escape key on the soft keyboard. Sample Here’s the source code of the sample project. It was built with the free Visual Studio 2012 Express Edition: U2UConsult.Win8.ExtendedSliderSample.zip (205.01 kb) Enjoy!