Bing Maps WPF Control Beta with Surface 1.0

Microsoft surface table
Image via Wikipedia

As announced on the Microsoft Surface Blog (and elsewhere, I am sure), a Bing Maps WPF Control Beta has been released. This control targets WPF4 with functionality similar to the Bing Maps Silverlight control.

As a WPF4 control, with support for touch, it will also work in the Surface 2.0 environment. For those of us developing on the Surface 1.0 hardware, which of course runs over .NET 3.5, I wanted to see if I could make it work there.

Some time ago, Josh Blake wrote a post on how to write WPF4 applications for Surface 1.0 using his Blake.NUI library.

Using that same approach, I was able to build a simple application using the new Bing Maps Control under WPF4 on my Surface 1.0 hardware. On the downside, the app seems a little jumpy when panning, but I may be able to clean that up with some more work This is a start, though.

Displaying an XPS Document on the Microsoft Surface

As a part of an application I am prototyping, I ran into the need recently to display a document inside a ScatterViewItem on the the Microsoft Surface. Since there is (intentionally) no built-in way to display HTML content on the Surface, and displaying a Word document did not seem feasible, I settled on using an XML document, and using the WPF DocumentViewer control.

This seems pretty easy, right? Just put a DocumentViewer inside your ScatterViewItem, load the document into the DocumentViewer, and you’re done. Couldn’t be easier.

Well, displaying the XML document was indeed that easy. Unfortunately, as I expected, the DocumentViewer would not respond to touch at all. I posted a question to the MSDN Surface forums about this, and did not receive any response for several weeks.   The response I finally did receive was that I would have to develop a User Control, and handle the touch events myself.

Not being one to take advice, I decided to try another approach – I decided to see if I could hack the ControlTemplate for the DocumentViewer in such a way as to have it support touch (keep in mind that I am a relative noob when it comes to all of this WPF/Styles/ControlTemplate stuff).

So I created a simple Surface project in VS2008, and modified the SurfaceWindow1.xaml file to have a ScatterView control, containing a single DocumentViewer control, as shown below:

<s:SurfaceWindow x:Class="SurfaceDocumentViewer.SurfaceWindow1"
    xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
    xmlns:s=http://schemas.microsoft.com/surface/2008
    Title="SurfaceDocumentViewer" Loaded="SurfaceWindow_Loaded">
  <s:SurfaceWindow.Resources>
    <ImageBrush x:Key="WindowBackground" Stretch="None" Opacity="0.6" ImageSource="pack://application:,,,/Resources/WindowBackground.jpg"/>
  </s:SurfaceWindow.Resources>
    <s:ScatterView Background="{StaticResource WindowBackground}" >
        <DocumentViewer Margin=”15” Height="Auto" Name="docViewer" Width="Auto" />
    </s:ScatterView>
</s:SurfaceWindow>

Note that I added a margin around the DocumentViewer so that there would be something to grab on to in order to resize the ScatterViewItem. 

I then opened the project in Expression Blend so that I could get a copy of the “default” style/template for the DocumentViewer control. Opening the project in Blend, right click on the DocumentViewer, and select Edit Template | Edit a Copy…, as shown

2

Name the style (I used SurfaceDocumentViewerStyle), and define a location for it (I left it in the SurfaceWindow1.xaml file), as shown below.

3

Click OK, then save your changes and close Expression Blend.

Returning to Visual Studio, you will get a message that the project has been changed outside of Visual Studio. Click Reload to load the changes into Visual Studio. Opening SurfaceWindow1.xaml in design view, you should now see a <Style> element under <s:SurfaceWindow.Resources>, and within that, a ControlTemplate for the DocumentViewer. There are several parts to the ControlTemplate:

  • A ContentControl for the toolbar, that loads from an external assembly.
  • A ScrollViewer named PART_ContentHost that is the container for the actual document display
  • A DockPanel that provides background for PART_ContentHost
  • Another ContentControl names PART_FindToolBarHost where the search box is hosted

The only part important to me was the ScrollViewer. I also wanted to get rig of the toolbar and the search box in order to keep things as clean as possible. So I deleted the other parts.

Here then is the key step to making the DocumentViewer touch aware: I replaced the ScrollViewer with s:SurfaceScrollViewer. My new ControlTemplate now looks as shown below:

<Style x:Key="SurfaceDocumentViewerStyle" BasedOn="{x:Null}" TargetType="{x:Type DocumentViewer}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="ContextMenu" Value="{DynamicResource {ComponentResourceKey ResourceId=PUIDocumentViewerContextMenu, TypeInTargetAssembly={x:Type System_Windows_Documents:PresentationUIStyleResources}}}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DocumentViewer}">
                <Border Focusable="False" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" >
                    <Grid Background="{TemplateBinding Background}" KeyboardNavigation.TabNavigation="Local">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <s:SurfaceScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" x:Name="PART_ContentHost" IsTabStop="true" TabIndex="1" Focusable="{TemplateBinding Focusable}" Grid.Column="0" Grid.Row="1" CanContentScroll="true" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now, to test this, add an XPS document to your project (mine is name test.xps). Add an assembly reference to ReachFramework (XPS package support), and add using statements to SurfaceWindow1.xaml.cs as shown:


using System.IO;
using System.Windows.Xps.Packaging;

Add the following code to the end of the SurfaceWindow1 constructor to load and display the XPS document:


XpsDocument doc = new XpsDocument("test.xps", FileAccess.Read);
docViewer.Document = doc.GetFixedDocumentSequence();
docViewer.FitToWidth();
doc.Close();

Finally, to make the XPS document resize when you resize the ScatterViewItem, Add an event handler to your DocumentViewer to handle the SizeChanged event, as shown below:


private void docViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
    docViewer.FitToWidth();
}

If everything went according to plan, you should now be able to run your code and you should get a ScatterViewItem displaying your XPS file which is resizable, and which supports touch to navigate around the document.

(I think this should also work with the Surface Toolkit for Windows Touch, but I haven’t tried it yet)

Some challenges with MS Surface Development

So I have been playing with the MS Surface for a couple of weeks, and have a pretty good handle on the basics of the development model. As I said previsouly, the nice thing (for me, anyway) is that it is pretty standard .NET stuff. You can do pretty much anything you need to using Windows Presentation Foundation (WPF). That being said, it is not without its challenges, and I would like to share some of what I have seen so far. 

1) The SDK only installs on 32-bit Windows Vista. This is a challenge for me, since my T4G laptop is running XP, and all of my other computers are running 64-bit Windows 7. The big value of the SDK is that it contains a “Surface Simulator” which allows you to experiment with Surface development without actually having a Surface. I tried setting up a 32-bit Vista VM to use for the SDK, but the simulator does not work in the VM. Now the good news, after a couple of weeks of messing around, I managed to hack the .msi file for the SDK, which then allowed me to install on 64-bit Win7. All seems to work great now.  

2) WPF experience is hard to come by. I can program in WPF, and understand how it works, but when it comes to the fancy styling and more creative aspects of what you can do with XAML, I am definitely no expert. Apparently, neither is anyone else I know!

3) Changing the way you think about the user interface. This is the biggy. The UI model for the Surface is different than anything else with which I have worked. yes, it is a multi-touch platform, which is cool, but hardly unique. If all you want to do is develope multi-touch apps, you can do it much more cheaply on a multi-touch PC (both WPF and Silverlight now support multi-touch development on Windows 7). The unique aspects of the Surface are that it is social, immersive, 360-degree, and supports interaction with physical objects. In order to make full use of the Surface platform, you have to think about all of these things. You also have to break old habits regarding how the user interacts with the platform. We are used to menus, text boxes, check boxes, drop downs and all the usual UI components we have lived with for so long in desktop applications. Or the content and navigation models we are used to on the web. The Surface requires us to forget all of that, and think of interaction in a new way. In this sense, it is more like iPhone development. However, even iPhone development gives you a fairly strict environment which defines how your app ahould look. The Surface on the other hand, is wide open. You can create almost any interaction model you can imagine, supporting multiple user working either independantly or collaboratively, working from any or all sides of the screen, with or without physical objects. This requires a whole new way of thinking, at least for me.

4) Ideas. This is another big challenge. I have lots of ideas for applications for the Surface. Some of them I am pretty sure are good. Some of those are even useful. Some of my other ideas are probably downright stupid. I would like to hear your ideas. I have always believed that, the more people you have coming up with ideas, and the more ideas you come up with, the better your chances of finding great ideas. So shoot me email with any or all ideas you might have – and don’t worry, they cannot be any more silly than some of mine!

Finally, I have added a little video showing just how far you can go with the Surface UI. Hopefully in the next couple of days, I will have a video of some of what I am working on to show.

DaVinci (Microsoft Surface Physics Illustrator) from Razorfish – Emerging Experiences on Vimeo.

What Microsoft Doesn’t Want You to Know about WPF

Looking at Eric Sink’s post What Microsoft Doesn’t Want You to Know about WPF – gee, I thought I was the only person who coded on vacation (at least that is what my wife tells me).

Anyway, I agree with the observation that “beautiful” is definitely not the default for WPF – certainly not until Microsoft’s toolset catches up. Maybe then beautiful will be the default, or at least a selectable option.

I guess the point, though, is that WPF is supposed to let you separate design from coding, and enable you to let designers design, and programmers program. I have never actually seen this work in the real world, but I am forever hopeful. The fact is, though, that no technology or tool is going to protect you from creating ugly designs – the same as using the right language will not guarantee you will not produce bad code, and having the right process does not guarantee that your project will be a success. All it does is improve your odds a little. Maybe. if you are lucky.