Windows Phone 7 Series – notes from launch
Feb 16th
Microsoft announced Windows Phone 7 today. It looks pretty amazing. The only negative point is that it won’t be out until the fourth quarter of 2010.
Below are my notes from the launch:
Approach
- WP7 changed approach, focused on end users, business and otherwise
- visual design is called “metro” graphical intense, high motion ui
- home screen is called the “start bar”
- focuses on tasks rather than apps – tasks form a hub
- Syncing to social networks seems to be a hands-off experience, sign in and it does the rest
- Microsoft want to maintain stricter control of the look & feel of the device while still allowing for third-party innovation
Hardware
- three hardware buttons (back, start, search)
- require capacitive touch (minimum 4 point touch)
- WVGA screen
- FM (or digital?) radio
Search
- context sensitive – different results based on where you are in the phone (contacts, email etc.)
- automatically uses GPS
- search can be of three types, attempts to choose the most appropriate one automatically (local, news, web)
Web Browser
- based on PC code for maximum compatibility
- pinch zoom
- tap to zoom (zoom to column on page)
- sub pixel positioning for text)
- recognizes phone numbers and addresses and makes them linkable
- supports tabs
People Hub
- Aggregates all your contacts from social networks (no twitter yet by the looks, I imagine this will change)
- Shows people you have communicated with recently
- “What’s new” feed: feed from all your social networks
Office Hub
- Access to Microsoft Office apps like OneNote, Excel, Word etc.
Games hub
- Syncs with Xbox live
- Focus on social gamer experience
- earn gamer score, achievements
Me tile
- Simultaneously update your social networking status to multiple sites
- Supports all common providers including gmail, yahoo as well as Exchange (of course)
- Never see a loading bar, works against a local cache (very fast experience)
Text
- Supports SMS, MMS
- Supports portrait/landscape typing modes
Calendar
- Automatically merges your personal and work calendars
Pictures
- gallery lets you browse all pictures
- “mosaic” shows recent or favourite pictures
- “What’s new” feed shows latest pictures from your social networking sites (Facebook, Windows Live etc)
- Album view combines folders from photos synced from Zune software on your PC with albums from Facebook, Windows Live
- Social networking comments are displayed when you view a picture
Music and Video
- Full Zune HD experience
- Supports Zune pass/subscription
Other
- toolbar is always available at the bottom to access “enhanced” commands
- UI is not completely done (especially some of the buttons you see)
- one press to correct words you’ve messed up in keyboard mode
More information:
http://channel9.msdn.com/posts/LauraFoy/First-Look-Windows-Phone-7-Series-Hands-on-Demo/
Document and report generation using XAML, WPF data binding and XPS
Feb 6th
Generating printable documents or reports containing dynamic data is a common requirement of most business systems. In this post I will show you how to create XPS documents dynamically using WPF templates loaded from the file system and populated with data binding. This technique is especially powerful when the output document needs to be either highly dynamic or has lots of design elements. The example document we will create looks something like this:
The document template
For a fixed format document the <FixedDocument/> is a logical starting point. The template needed to make our document is as follows:
<FixedDocument
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="en-au">
<FixedDocument.Resources>
<BooleanToVisibilityConverter x:Key="visConverter"/>
</FixedDocument.Resources>
<PageContent>
<FixedPage Width="793.76" Height="1122.56">
<!-- Page 1 Begins Here -->
<StackPanel Margin="50">
<Border BorderThickness="5" BorderBrush="Gray" CornerRadius="10"
Padding="20" Width="690">
<StackPanel Orientation="Horizontal" Margin="0 0 0 0">
<Image Source="truck.jpg" HorizontalAlignment="Left"/>
<TextBlock Margin="30 0 0 0" FontSize="50"
Text="{Binding Path=Heading}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
<TextBlock Margin="0 30 0 0"
Text="{Binding Path=CurrentDate, StringFormat='{}{0:d MMMM yyyy}'}"/>
<TextBlock Margin="0 30 0 0"
Text="{Binding Path=Name, StringFormat='Dear {0},'}" />
<ItemsControl Margin="30 20 0 0" ItemsSource="{Binding Path=DotPoints}"
HorizontalAlignment="Left">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" >
<TextBlock Text="• " />
<TextBlock Text="{Binding}" TextWrapping="Wrap" Width="400"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Margin="0 30 0 0"
Text="Congratulations, you are entitled to a 50% discount!"
Visibility="{Binding Path=GiveDiscount,
Converter={StaticResource visConverter}}"/>
</StackPanel>
</FixedPage>
</PageContent>
<PageContent>
<FixedPage Width="793.76" Height="1122.56">
<!-- Page 2 Begins Here -->
<TextBlock Margin="50" Text="Nothing to see here."/>
</FixedPage>
</PageContent>
</FixedDocument>
This includes the namespace imports that should be familiar to any WPF developer. One thing of interest in this template is the hard coded width and height of the <FixedPage/>. These values have specified an A4 page in portrait orientation. These have been based on the DPI of WPF (96) and the dimensions of an A4 page.
The XAML template includes standard WPF binding expressions which will be used to populate the document with dynamic data. It also makes use of the BooleanToVisibilityConverter to make easy show/hide functionality through data binding.
Loading the template from the file system
System.Windows.Markup.XamlReader provides an easy way of parsing XAML markup into objects:
public static object LoadTemplate(string templatePath)
{
object template;
// get the needed template paths
string absolutePath = Path.GetFullPath(templatePath);
string directoryPath = Path.GetDirectoryName(absolutePath);
using (FileStream inputStream = File.OpenRead(absolutePath))
{
var pc = new ParserContext
{
// It is critical to have the trailing backslash here
// will not work without it!
BaseUri = new Uri(directoryPath + "\\")
};
template = XamlReader.Load(inputStream, pc);
}
return template;
}
It’s critical here to setup the ParserContext so that resources can be referenced from the XAML. In our example we reference an image, but you can also reference things like fonts and other XAML files.
Injecting data into the document with data binding
For our example we will use basic object data binding. However this technique would work equally well with other WPF binding sources such as XML. The object we will bind to has properties which correspond to the binding expressions in the template:
public class Data
{
public string Heading { get; set; }
public DateTime CurrentDate { get; set; }
public string Name { get; set; }
public string[] DotPoints { get; set; }
public bool GiveDiscount { get; set; }
}
public static void InjectData(FixedDocument document, object dataSource)
{
document.DataContext = dataSource;
// we need to give the binding infrastructure a push as we
// are operating outside of the intended use of WPF
var dispatcher = Dispatcher.CurrentDispatcher;
dispatcher.Invoke(
DispatcherPriority.SystemIdle,
new DispatcherOperationCallback(delegate { return null; }),
null);
}
In this code we set the DataContext for the FixedDocument to be the object containing the data. The strange thing is the dispatcher code. In a normal WPF application the dispatcher is used to marshal calls from worker threads to the UI thread. It seems that data binding outside of the UI context is not triggered unless the dispatcher is woken from its sleepy state. To do this we give it an arbitrary task.
Save our document to XPS
The ugliest code is left for last. Below is what is required to convert a FixedDocument to an XPS format file ready to be viewed and printed by the user:
public static void ConvertToXps(FixedDocument fixedDoc, Stream outputStream)
{
var package = Package.Open(outputStream, FileMode.Create);
var xpsDoc = new XpsDocument(package, CompressionOption.Normal);
XpsDocumentWriter xpsWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
// xps documents are built using fixed document sequences
var fixedDocSeq = new FixedDocumentSequence();
var docRef = new DocumentReference();
docRef.BeginInit();
docRef.SetDocument(fixedDoc);
docRef.EndInit();
((IAddChild)fixedDocSeq).AddChild(docRef);
// write out our fixed document to xps
xpsWriter.Write(fixedDocSeq.DocumentPaginator);
xpsDoc.Close();
package.Close();
}
When working with XPS files you will find that you always have to work within a Package. The other interesting part of this code is the cast to IAddChild which is needed to add the DocumentReference as content within the FixedDocumentSequence.
Exception: the calling thread must be STA
WPF controls can only be used in STA threads. This isn’t usually something you have to consider when you are using WPF in a GUI application. However, if you are attempting to use this XPS code deep within some class library then the apartment state of the calling thread cannot be guaranteed. Instead of putting this requirement onto the consumer of your class you can use code like the following:
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
{
var t = new Thread(() =>
{
// do work here when calling thread is not STA
});
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = false;
t.Start();
t.Join();
}
else
{
// do work here when calling thread is STA
// this removes the overhead of creating
// a new thread when it is not necessary
}
Final comments
This XPS generation technique is extremely flexible. Some key strengths:
- Allows for the full power of WPF, enabling attractive documents
- You can use user controls as well as third party components such as charting libraries
- Your own custom ValueConverters in combination with data triggers can be used for almost any dynamic requirement (this is probably worth another post)
- Conversion to PDF is possible with third party libraries
Visual Studio 2008 Solution – XpsDocumentGenerator.zip

