Damask Wallpaper in WPF

22. July 2007

"Floral" patterns seem to be the new gel button, as far as design trends go. Drawing on inspiration centuries old here are two finely crafted Damask brushes based on images from the inspiration gallery. OK, so maybe finely crafted was a bit of an over-statement (after all you can see the tiling lines in one of the brushes, but that makes it feel more "organic" or whatever). Enjoy responsibly here.

Damask Patterns

Assembling a Free WPF Development Toolset

5. July 2007

Want to get started playing around with WPF applications, but you'd rather save your cash for some SLI video cards? Never fear - we've assembled a list of free (as in gratis) tools for most facets of WPF development.

Essentials

Visual Studio Express Editions (C#/VB.NET)  and Visual Studio Extensions for .NET 3.0  will get you up and running and building "hello world".

Optional - Development

Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components - this SDK includes a number of samples, tools and documentation that can be very helpful when developing WPF applications.

Optional - Design

Inkscape is an open-source vector graphics editor. It is ideal for creating vector icons, complex paths, geometries and the like. It's native file format is SVG, an XML dialect for representing vector graphics. In order to incorporate Inkscape into your WPF tool-chain you'll need this handy SVG to XAML converter, written by Andrej Benedik from wpf-graphics.com.

Optional - 3D

Blender is the free open source 3D content creation suite. You can use it to develop 3D content, which you then export to XAML using this export script from Daniel Lehenbauer from the WPF 3D team at MS. Note - the latest release of Blender seems to have some issues running on Vista. Also, to run the export script you will need to install Python.

Optional - Components

Xceed DataGrid for WPF is a free, commercial-quality data grid offered by Xceed. WPF does not include a datagrid as one of the build-in controls, and Xceed has more than filled this gap with their grid. You can also catch an interview with Pascal Bourque, one of the senior developers from Xceed on Channel9, talking about the new approaches and opportunities for developing components for WPF.

Multi-Field Undo/Redo in WPF using Attached Properties

5. June 2007

I recently had a scenario where I wanted a number of WPF text fields to support a co-ordinated undo/redo capability. The regular undo/redo facility in WPF (and most control tool-kits) applies to a single field. Changes to that field can be undone or re-applied, but each field is very much stand-alone and independent of those around it. I wanted a facility where a number of fields could be logically grouped together for the purposes of undo and redo operations, since I thought this would more closely match the user’s mental model of how the system worked. Changes should be tracked across multiple fields, and undo and redo operations should occur in the order they are made across the different fields. I also wanted the focus to change also as undo/redo operations occurred.

Using it
Using the shared undo/redo scope I created is quite easy, and can be accomplished just using XAML. An “undo manager” is set as an attached property as shown in the code sample below. The SharedUndoRedoScope attached property on the UndoManager type I created is set for a StackPanel. The property is inherited, so it can be set on a parent element (like a panel) and applied to all the children.  In the example below the two textboxes share a common “undo/redo manager” because they are both children of the same stackpanel 

XAML Fragment
<StackPanel>
  <undo:UndoManager.SharedUndoRedoScope>
    <undo:UndoManager />
  </undo:UndoManager.SharedUndoRedoScope>

  <TextBox Text="text box 1" />
  <TextBox Text="text box 2" />
</StackPanel>

The sample application (shown below) creates two shared undo/redo scopes, and a third set of elements that don’t have any special undo/redo capabilities for comparison. You can download the sample application with full source from here.

Sample Application with multiple undo/redo scopes

Implementation
The undo manager has two main roles internally – firstly to track changes in the text boxes across all the text boxes it is managing (so they can be un-done in that order), and then actually stepping in at the right time and triggering the undo.

Tracking changes is relatively straightforward - When text changed events are fired for textboxes the undo manager is managing, it pushes the changes onto an internal undo stack. Only changes that are important are added. For example many TextChanged events will fire when someone is typing with the UndoAction of Merge, these aren’t necessary for the UndoManager to track.

Actually triggering Undo and Redo operations is slightly trickier, and I needed to work around some implementation details of the TextBox and RichTextBox controls in WPF. Both of the TextBoxBase-derived controls wire up command handlers on an internal class called the TextEditor inside their constructors. In here amongst a group of internal classes some handlers for ApplicationCommands.Undo and ApplicationCommands.Redo are created. When the WPF TextBox and RichTextBox handle these ApplicationCommands they mark them as “handled” to prevent them bubbling up to your code. While usually this is quite desirable, preventing your application code having to care about undo and redo commands being fired which the TextBox has already taken care of in this instance it causes a problem because the UndoManager needs to step in at this point and potentially do something different. Fortunately with routed events you can optionally choose to “see” routed events that have already been marked as handled, which is what I have done, by calling the AddHandler() method overload that takes a third Boolean parameter for specifying if you want to see the handled events.

C# Code
textBox.AddHandler(CommandManager.PreviewCanExecuteEvent, new CanExecuteRoutedEventHandler(manager.CanExecuteRoutedEventHandler), true);

When the UndoManager sees an Undo or Redo ApplicationCommands it pops an item off its internal undo or redo stack, and calls the Undo() or Redo() method on the text box on the stack as appropriate.

Currently the implementation only tracks changes in TextBox and RichTextBox. You could extend it to handle undo and redo of selection in lists and toggling of checkboxes etc. also.

In implementing this I was conscious of trying to create a programming model that “meshed” with the rest of WPF, in particular I thought choosing an inheritable attached property was an appropriate way to expose this kind of feature. I would be keen to hear any feedback on this aspect of the implementation, in particular how this could have been done better.

Update: Roman was kind enough to point out some embarrassingly obvious flaws in my implementation (see comments below), which are fixed in the source code you can download now.

MONO project posts preliminary documentation of its Silverlight implementation - Moonlight

11. May 2007
The MONO project - creators of an open-source, cross-platform CLR and set of base-class libraries and developer tools have indicated they will attempt to create their own implementation of Microsoft's Silverlight. The new project is currently called Moonlight.

4 Expression Blend Books Available for Pre-Order from Amazon

6. May 2007

With Expression Blend now officially released, and included as part of an MSDN subscription it seems to be an increasingly important tool for WPF developers as well as designers. Here are 4 recently announced books that can help you get up to speed with Expression Blend.

Expression Blend Unleashed by Brennon Williams is scheduled for release in October and will be around 500 pages long. Brennon runs the http://expressionblend.com community site. This is Brennon’s first book project that I know of.
Expression Blend Unleashed

Pro Expression Blend by Ryan Moore and Darren Lutz from APress is scheduled for release in late August and will be around 400 pages long. Ryan is also the author of a book on ASP.NET for flash developers.
Pro Expression Blend

Professional Expression Blend written by Shawn Livermore, Rob Ferrante, August Banks and Tony Ferreira brings together many of the “usual suspects” from Wrox’ stable of authors. It is scheduled for release in late July, and will be around 400 pages long.
Professional Expression Blend


Expression Blend Bible by Gurdy and Mary Leete from Wiley and scheduled for release in early June. It will be around 750 pages long. Gurdy has previously authored a number of books on Macromedia (now Adobe) Flash.
Expression Blend Bible

Read 'Lessons Learned' from the team at Vertigo that built the Family.Show WPF Sample

29. April 2007

The team at Vertigo that created the nice Family.Show WPF sample wrote up a summary of their key feedback and take-aways from the project, and they're well worth a read. One tip in particular that I liked was regarding data binding, and default values. They advised setting the default values in bindings to give a better design-time experience in tools like Blend, which uses the defaults when it displays the UI in the designer. The source-code is also quite tractable, consisting of about a dozen xaml files and ~20 classes.

Family.Show screen shot  

When I tab into a toolbar in WPF I can't tab out again? What can I do to change this tab behaviour?

28. April 2007

One common way of moving the focus around in a user interface on Windows is to use the Tab key to move sequentially between controls. The contents of a WPF tool-bar seem to act like a kind of tabbing black-hole. The focus goes in there but never comes out again. Try pasting this Xaml into XamlPad to see the problem:

Xaml Code (.NET 3.0)
<DockPanel>
  <ToolBar DockPanel.Dock="Top">
    <Button Content="B"
            Command="EditingCommands.ToggleBold" />
    <Button Content="U"
            Command="EditingCommands.ToggleUnderline" />
    <Button Content="I"
            Command="EditingCommands.ToggleItalic" />
  </ToolBar>
  <RichTextBox />
</DockPanel>

Fortunately this can be easily fixed by using the KeyboardNavigation attached property and changing the TabNavigation to "Continue". This allows the tab focus to move out of the toolbar and back to the other elements of the UI.

Xaml Code (.NET 3.0)
<DockPanel>
  <ToolBar DockPanel.Dock="Top"
           KeyboardNavigation.TabNavigation="Continue">
    <Button Content="B"
            Command="EditingCommands.ToggleBold" />
    <Button Content="U"
            Command="EditingCommands.ToggleUnderline" />
    <Button Content="I"
            Command="EditingCommands.ToggleItalic" />
  </ToolBar>
  <RichTextBox />
</DockPanel>

WPF/e re-named Silverlight

15. April 2007

The project formerly known as Windows Presentation Foundation everywhere (WPF/e) has been re-named Sliverlight in preparation for its final release. Prior to WPF/e it was known as Jolt. Silverlight is a cross-platform and cross-browser plugin for creating rich internet experiences and applications for the web. It uses a subset of Xaml and WPF. You can read Tim Sneath's top 10 reasons you might be interested in Silverlight here.

Silverlight Logo  

I receive an error message when trying to create an XBAP application in the Orcas March 2007 CTP - what can I do?

10. April 2007

You may receive the following error message when trying to create a new XBAP application using the Visual Studio Orcas March 2007 CTP:

"Error: this template attempted to load an untrusted component 'WinFxBrowserApplicationTemplateWizard, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a'.  For more information on this problem and how to enable this template, please see documentation on Customizing Project Templates."

This is a defect in this pre-beta version of Visual Studio that should be corrected in the next release. One simple way to get around this problem is to run "sn -Vr *,b03f5f7f11d50a3a" from the Visual Studio command prompt. This turns off strong name verification for assemblies with this public key token. This tip comes courtesy of Marco Goertz in the WPF Forums.

How can I create a great user experience when launching my WPF ClickOnce application?

8. April 2007

WPF is all about creating great user experiences, but the user experience of your application starts long before your code starts running on the end user’s machine. An important first step is launching your application and getting your code down onto the end user’s machine as quickly and simply as possible. ClickOnce makes great strides in improving this deployment experience for .NET 2 rich client applications and WPF applications, however the default publish page that is generated by visual studio can be greatly improved. In this article we discuss techniques to reduce the amount of decision-making required of the end user, and give them an experience tailored to their operating system version, browser version and system capabilities to minimize the size of the download for clients on sub-broadband network connections.

The broad approach we’ll be trying to take is:

  1. Identify potential users who can have WPF installed and can start using our application right away.
  2. Create a hyperlink to launch our application that works for their browser.
  3. For those users who need to install .NET Framework 3.0 direct them to do so and then give them a link to launch our application.
  4. For those users who we believe will not be able to run any WPF applications, give them the option of trying to install .NET Framework 3.0 and our application, but warn them that it may not work and why.

Identifying WPF-capable clients via the User Agent String

The user agent string is an optional parameter that can be sent as part of the HTTP headers when making a request to a web server. The user agent string is intended as a means for the client to identify itself to the server, so the server can optionally adjust the response if appropriate. Although the content of the user agent string is entirely free form and does not carry any guarantees regarding accuracy or authenticity, it is still broadly useful for identifying browser versions and client capabilities.

Identifying WPF-capable Clients using Internet Explorer

By default Internet Explorer includes the versions of the .NET framework present on the client in the user agent string like so:

Example Microsoft Internet Explorer 7.0 User Agent String on Windows Vista:
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)
(an exhaustive list of User Agent strings can be found here)

Fortunately the System.Web namespace contains the helpful HttpCapabilitiesBase class which can perform the task of parsing out the available CLR versions on the client. The code below assumes that WPF will be included in versions of .net framework subsequent to version 3.
C# Code
HttpCapabilitiesBase httpCapabilities = HttpCapabilitiesBase.GetConfigCapabilities("system.web/browserCaps", HttpContext.Current.Request);

Version wpfV1FinalVersion = new Version("3.0.04506");

Version[] clrVersions = httpCapabilities.GetClrVersions();

foreach (Version clrVersion in clrVersions)
{
    if (clrVersion >= wpfV1FinalVersion)
    {
        // client has WPF
    }
}

For clients that have WPF installed we can simply link directly thru to the .application file generated by ClickOnce, which will prompt the user to install our application. For clients that don’t have the .NET Framework 3.0 or better installed we can direct them to where it can be downloaded, and then prompt them to launch our application. Alternatively we could launch the ClickOnce bootstrap setup.exe which can install pre-requisites on the client’s machine.

Identifying WPF-capable Clients using Mozilla Firefox

Unlike Internet Explorer, Mozilla does not include the .NET CLR versions installed on the client computer as part of the user agent string. However since Windows Vista comes with WPF pre-installed on it we can check the Mozilla user agent string for the Windows version, and for Vista users assume they have WPF. For Windows XP and Server 2003 users we can indicate that WPF is supported, that we can’t tell if they have it or not and provide them with a two-step installation process (step 1 being to install .NET Framework 3.0, and step 2 to install our application).

Example Mozilla Firefox 2.0 User Agent String on Windows Vista
Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2

For users that don’t appear to be using Windows, or who are using an older version of windows we revert to our fallback position – tell them that we believe they won’t be able to run our application but they are welcome to try with the two steps listed above.

Serving the Right Files to Launch our Application in Mozilla Firefox

Unfortunately identifying WPF-capable clients using Firefox is only the beginning, because the .application file used to launch your ClickOnce application does not work in Firefox (although there are some add-ins for Firefox that allow them to work). Cross-browser support was de-scoped from ClickOnce between Beta 2 and RTM, but luckily there is a work-around where Mozilla users running windows can be served a .appref-ms file. A .appref-ms is a kind of ClickOnce version of a desktop shortcut, which will then correctly launch your application for them (if they have .NET Framework 3.0 installed). The easiest way to get your hands on one of these files for your application is to deploy it using IE and ClickOnce, and then copy the shortcut that is created in the start menu – that is a .appref-ms file.  You will need to deploy this file yourself. If your application is being served up by IIS you may need to add a MIME type mapping for .appref-ms files also. 

Why not just direct users to the ClickOnce bootstrap setup.exe program?

The ClickOnce bootstrap executable (setup.exe) is a useful way to launch your application installation in some cases, however there are some issues with it. Setup.exe doesn’t work with Mozilla Firefox if it is the default web browser on the client system. Also Firefox users on Vista see a moderately concerning prompt about running executables downloaded from the internet. For users who already have the pre-requisites necessary to run your application on slower network connections the 400K download of setup.exe is time and bandwidth wasted. For users on XP SP2 running IE who do not have .NET 3.0 installed setup.exe is a good choice.

A sample user control and code for detecting clients with WPF installed can be downloaded from here.