Developing for Windows Mobile – XAML for Win Forms

Many years ago (2004/5?) I was given the task of writing a XAML engine for System.Windows.Forms. It was a great experience and to do the job properly (I hope) it took quite some time. It had support for most of what’s available in WPF’s XAML – namespaces, markup extensions, attached properites (IExtenderProviders in WinForms speak), type converters, late bound binding, styles, triggers etc. plus a bunch of stuff that isn’t – #include, using parameterized constructors, simplified referencing etc.

In my Windows Mobile UI Framework the idea of having the capability of defining screens in XAML was kind of an afterthought. I had truly forgotten how painful it is to define UI’s programmatically. I’ve also never been a fan of form designers – I think they are slow, in-accurate and generate hard to maintain code/XAML. To this day I do 90% of my XAML using an XML editor (VS or Kaxaml).

So as per my last post I whipped up a very simplified XAML parser/renderer to use with my Mobile UI Framework. However, the latest control that I added to the framework was FormHost which allows a System.Windows.Forms control to be hosted within a DrawingElement (my UI base class). Of course when I say “hosted” the FormHost is really just acting as a placeholder so that the hosted control can be positioned during the render pass.

Here’s the code I had to add for FormHost:

using System;
using System.Drawing;
using System.Windows.Forms;
using Spencen.Mobile.UI.Primitives;
namespace Spencen.Mobile.UI.Controls
{
public class FormHost : DrawingContainer
{
private Control _hostControl;
public FormHost( IDrawingHost host ) : base( host )
{
_hostControl = host as Control;
if ( _hostControl == null )
throw new ArgumentException(
"FormHost must have an IDrawingHost that is a Windows.Forms.Control.", "host");
// By default we have no background or border Background = new SolidBrush( Color.Transparent ); Stroke = null; } public Control HostedControl { get; set; } public override bool SupportsRotation { get { return false; } } protected override void OnRender( GraphicsContext context ) { base.OnRender( context ); var transformedBounds = TransformedBounds( context ); if ( !_hostControl.Controls.Contains( HostedControl ) ) _hostControl.Controls.Add( HostedControl ); var newLocation = new Point( transformedBounds.Left, transformedBounds.Top ); if ( newLocation != HostedControl.Location ) HostedControl.Location = newLocation; var newSize = new Size( transformedBounds.Width + 1, transformedBounds.Height + 1); if ( newSize != HostedControl.Size ) HostedControl.Size = newSize; } } }

So pretty simple – but what was extra nice was the fact that it meant I could immediately declare my hosted System.Windows.Forms controls using XAML without any changes to the XAML parser/renderer at all.

<?xml version="1.0" encoding="utf-8" ?>
<View
xmlns="http://mobileui.codeplex.com/v1"
xmlns:x="http://mobileui.codeplex.com/xaml"
  xmlns:WinForms="System.Windows.Forms,System.Windows.Forms"
DesiredSize="Unbound">

<DrawingPanel x:Name="container" DesiredSize="Unbound" Background="{null}">
<TextElement Text="Text" DesiredSize="150,60" AutoSize="True"/> 
<RectangleElement DesiredSize="50,80"/>
    <EllipseElement DesiredSize="40,70"/>
<RegularPolygonElement NumberOfSides="6" DesiredSize="80,80"/>
<RegularPolygonElement NumberOfSides="3" DesiredSize="90,70"/>
<RegularPolygonElement NumberOfSides="8" DesiredSize="80,80"/> <Star NumberOfPoints="5" DesiredSize="80,80"/> <!-- Just to spice things up - here's some WinForms controls - just don't expect them to rotate! --> <FormHost DesiredSize="240,40"> <FormHost.HostedControl> <WinForms:TextBox Text="Hello WinForms" Multiline="True" BackColor="240,255,240"/> </FormHost.HostedControl> </FormHost> <FormHost DesiredSize="240,80"> <FormHost.HostedControl> <WinFormsanel> <WinFormsanel.Controls> <WinForms:RadioButton Checked="True" Text="Is WinForms?" BackColor="255,255,223"
Dock="Top" Height="20"
/> <WinForms:RadioButton Checked="True" Text="Is MobileUI?" BackColor="255,255,223"
Dock="Fill"
/> </WinFormsanel.Controls> </WinFormsanel> </FormHost.HostedControl> </FormHost> </DrawingPanel> </View>

MobileUI_Screenshot 5

2 thoughts on “Developing for Windows Mobile – XAML for Win Forms”

  1. Do you think your framework will work with an MVVM pattern? Also, is there any memory leak that would prevent an application based on your framework from passing the Microsoft App Store submission test?

  2. Yep – framework is designed to work with MVVM. Mini-apps that I’ve tried so far have UI in XAML files only – linked to a ViewModel (Presenter) at the DataContext. ICommand interface is used to hook buttons to methods on the ViewModel. Big missing link at the moment is dynamic data-binding – e.g. data binding is currently only performed once at startup. Need to hook data binding to ValueChanged events etc.
    As for memory leaks – I don’t know. I’ve got a couple of personal apps (local commute timetable) that run without any problems – but I’m not creating lots of UI elements dynamically. I haven’t yet submitted anything to Microsoft Marketplace.

Comments are closed.