goodbye, battleship grey


IE8 Beta 1 breaks Image Download in WPF applications

I ran into this issue when IE8 was first released and it doesn't seem to have gotten much visibility elsewhere. IE8 Beta 1 breaks image downloads for WPF applications when the image has a web uri. From the stack trace this seems to be caused by wininet.dll not returning the internet cache folder correctly. A typical call stack for the error message might look something like this (when the uri specified is a http uri, I haven't checked FTP)

A first chance exception of type 'System.ArgumentException' occurred in PresentationCore.dll
        System.ArgumentException: Value does not fall within the expected range.
        at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
        at MS.Win32.WinInet.get_InternetCacheFolder()
        at System.Windows.Media.Imaging.BitmapDownload.BeginDownload(BitmapDecoder decoder, Uri uri, RequestCachePolicy uriCachePolicy, Stream stream)
        at System.Windows.Media.Imaging.LateBoundBitmapDecoder..ctor
        (Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy requestCachePolicy)
        at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream
        (Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
        at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
        at System.Windows.Media.Imaging.BitmapImage.EndInit()

It seems that others have also noticed and reproduced this error on both XP and Vista. In general image downloading seems to be one of the more perilous operations for WPF to perform. I've seen a number of other process-terminating exceptions caused by images with invalid formats etc, so it is best to be cautious. For this problem caused by IE8 "manually" constructing a web request and downloading the image yourself, and then creating a BitmapImage from the downloaded stream works and does not cause the error.

Silverlight 2.0 Beta 1 and WPF Resource Management: What's the same and what's different?

Both Silverlight 2.0 and WPF support the notion of resources, which can be associated with almost any element - in both SL and WPF the widely inherited-from FrameworkElement (and in WPF the FrameworkContentElement) class exposes a Resources property of type ResourceDictionary. The Resources dictionary is a simple collection of key-value pairs. Almost anything can be stored as a resource, from brushes to templates, data sources, converters, dates, strings and any other .NET object which can be represented as XAML. The key used to retrieve resources can be anything too; however strings or static fields are used.

The current (beta 1) implementation of Silverlight 2.0 has some notable differences to WPF however. The first is that resources cannot be factored into separate files and referenced using the <ResourceDictionary.MergedDictionaries> feature of WPF resource dictionaries. This is unfortunate as it means that the App.xaml file will probably become large and unweildy (and potentially an integration pain point between developers and designers) in Silverlight.

Another notable difference is the way resources are retrieved in code. In WPF FrameworkElement and FrameworkContentElement have methods FindResource and TryFindResource which will look for a resource in the current dictionary with the key provided. If no resource is present for this key these methods traverse the logical tree to ancestor nodes looking for the resource that matches the key. Silverlight 2.0 beta 1 does not expose methods like these (possibly due to the de-emphasis of the separation between the visual and logical trees as concepts in its programming model). You can refer to resources on an object by their key, but no tree searching is performed - if the resource doesn't exist in that resource dictionary then null is returned.

As with WPF, resource retrieval in XAML is done using the {StaticResource} markup extension in Silverlight 2.0. When this markup extension is used the tree is traversed looking for a resource with the specified key. There is no {DynamicResource} markup extension in Silverlight 2.0.

In Silverlight 2.0 Resources can either be given a key (by setting the x:Key attribute) or a name (by setting the x:Name attribute) and both will work for item resolution. Attempting to add two elements with the same value (one by setting the key attribute, the other by setting the name attribute) results in a run-time error.

Silverlight 2.0 beta1 and WPF Data Binding – what’s the same and what’s different?

Silverlight 2.0 promises to bring much of the goodness of WPF to the browser. So how does one of my favourite WPF features - data binding - fare in the new Silverlight 2.0 beta 1 world? To help answer this question I drew up the following summary:

Similarities Differences
Binding Object – the Binding object is present in both SL 2.0 and WPF. Many simple binding scenarios will probably work between the two without modification, but if you’re using the more complex properties of the Binding object in WPF you’ll need to revisit that for Silverlight 2.0 code. The INotifyPropertyChanged interface is also used for change notifications on data objects to be propagated back up to the binding infrastructure. Binding Object – although the Binding object exists in SL 2.0 and WPF the SL 2.0 version is very pared-back compared to WPF, having only 5 properties: Converter, ConverterCulture, ConverterParameter, Mode and Source, in contrast to the 20 or so relevant properties the WPF binding object exposes or inherits from its base types. One of the most key properties on the WPF binding object – the path isn’t even a property at all on the Silverlight equivalent. Instead it is specified as a constructor property. Also the Path in SL 2 can’t drill down into indexes or attached properties the way it can in WPF, however you can still access sub-properties on objects. Josh has some screen-shots from Reflector showing the difference in size of the two types.
Data Context – the concept of a Data Context for a control which is propagated from a parent control down to child controls is shared between WPF and Silverlight 2 beta 1. As with WPF the FrameworkElement type adds the DataContext property in Silverlight 2.0 beta 1. Binding Markup Extension – although syntactically quite similar (albeit with less properties) bindings in Silverlight are quite different internally to their WPF counterparts because they don’t use a managed Binding Markup Extension. In fact, from what we can see of Silverlight 2.0 beta 1 there ARE no markup extensions of any kind. The Silverlight documentation discusses them here but they don’t appear anywhere in the object model. Presumably the implementations of the various markup extensions are hard-wired into the Silverlight runtime.
Converters – One of my favourite extensibility points of WPF has been completely migrated to Silverlight 2.0 beta 1 (possibly due to the simplicity of the IValueConverter interface). A converter and converter parameter can be supplied as part of a binding. Binding to Other Elements – one common scenario is to bind two pieces of WPF UI to each-other. For example binding a slider to the “zoom” on a ScaleTransform. This is done by setting the ElementName property to the name of the element in the current name scope. Silverlight 2.0 beta 1 doesn’t support ElementName as a parameter when binding. This limitation can be worked around fairly easily by creating a simple object with a single property of the type you wish to glue together (double is probably the most common scenario) and then implementing INotifyPropertyChanged on that type. This approach is described in more detail here.
Data Templates – Both WPF and Silverlight 2.0 beta 1 share the concept of templates that can be applied to data. One area where SL 2 differs is that in WPF you can specify a template by the type of object the template applies to (by setting the DataType property). If this is set and no key is supplied (and the Datatemplate is appropriately scoped) the template becomes the default appearance for that type of data item in WPF. The DataTemplate type in Silverlight 2.0 beta 1 doesn’t include this property so all data templates are “keyed” in resource dictionaries or entered in-line. Data Triggers – Data templates in Silverlight 2.0 beta 1 don’t have data triggers like their WPF counterparts. This can be worked around using a converter, but requires more code than a data trigger would. Given the changes introduced by the new Silverlight control templating model data triggers going missing are the least of your worries.
TemplateBinding – TemplateBinding is fundamental to styling of controls, and thus has also made its way over from WPF to Silverlight.
ObservableCollection - the generic collection with built-in change notification, ObservableCollection has also been included in Silverlight 2.0 beta 1. The INotifyCollectionChanged interface (the collection equivalent of INotifyPropertyChanged) is also present, and implemented by ObservableCollection.


2 Great Free Resources for WPF Developers - ElementFlow and DataGrid 2.0

Pavan Podilla has added his ElementFlow control to a suite of free open-source tools called FluidKit. ElementFlow is a layout panel that provides several carousel-like layouts, including one quite similar to the "coverflow" from Apple's iTunes application. You can check out some videos of ElementFlow here. My favourite part of ElementFlow is that it has been architected in the "wpf way" - Pavan modified it a while back to be a panel, and it uses templating for specifying how items should appear. In fact in the FluidKit.ShowCase demo that ships with FluidKit, ElementFlow is handling the item layout for an ItemsControl much like I described here. FluidKit also includes a number of other useful classes such as Pavan's drag and drop helpers and an Aero-glass style window.

FluidKit Logo

CoverFlow Layout

Component vendor xceed recently released v2 of their WPF Data Grid. It is available in both a free express version and a paid-for professional version. Both new version includes better design time support, and a greatly increased set of editors (like masked text boxes, numeric textboxes etc) for grid items and the pro version includes master-detail binding. [full disclosure: xceed are sponsors of this site].

xceed logo

Write Your Own Hardware Accelerated BitmapEffects - Coming soon to WPF

One of the interesting announcements that seemed to get lost in the flood of Silverlight news from Mix08 was a further information about future improvements to WPF. In his keynote talk Scott Guthrie re-iterated many of the things he'd detailed previously in the 3.5 client road-map. One slightly new bit of information was the opening up of BitmapEffects to people outside Microsoft. Not only that, you will be able to write hardware accelerated BitmapEffects! This means that DropShadow, Glow and Blur (some of the built-in effects) which are currently software rendered, and if used inadvisably can have nasty performance impacts will also be hardware accelerated.

During the keynote we were treated to a number of effects including ripple (see below) and fish-eye magnification.

Hardware accelerated ripple effect

Finding Memory Leaks in WPF Applications

Jossef  from the WPF Preformance Blog wrote a useful article about a month ago on diagnosing memory leaks in WPF applications. Although some of the issues shown are not WPF specific the leaks caused by command and data binding are. This article is well worth checking out if your perfromance testing seems to show a memory leak. 

Silverlight will get a DataGrid from Microsoft before WPF does

I was pouring over the Silverlight 2.0 tutorial posted by Scott Guthrie, and noticed this entry which describes the currently unreleased DataGrid for Silverlight (due for a beta1 release at Mix08 in a few weeks presumably). The new beta release will also include a calendar date-picker controls (also noticable omissions from the current default set of WPF controls) as well as integral features from WPF such as data binding, and layout management.

Scott recently also mentioned a DataGrid for WPF (in addition to a number of other improvements) as part of the Client RoadMap, although without any date commitments this looks a bit further out. This is interesting, as it shows Silverlight pulling ahead in some areas of its larger and older sibling WPF. Of course there are a number of 3rd party grids available for WPF, including a free DataGrid from XCeed.

Converting SVG to XAML - XamlTune vs. Ab2d SVG to Xaml Converter

I've mentioned before my fondness of using SVG content and converting it to XAML. Today I read about the Visio to XAML converter on Saveen's blog and about the approach taken (saving to SVG and then using a third party library XamlTune to convert to XAML). I was fairly interested in reading about this approach because I had tried this myself before (not as an add-in, just saving Visio to SVG and then manually converting) with very limited success.

After a few tests I'm very impressed with XamlTune, and recommend you try it if you need to convert from SVG to XAML. For comparison here is the original SVG file that inspired my glossy radial brushes previously.

original SVG

Here is the output from XamlTune (using the default settings)

XamlTune output

And here is the output from Ab2d SVG Reader (once again, using the default settings)

Ab2d SVG output

Glossy Brushes using Radial Gradient Brush in WPF

I recently wanted to convert some nice glossy SVG-based shapes into WPF. Here is the result.

glossy rectangles

The original brushes came from here on the site.

I attempted to convert them using WPF 3D Graphics' SVG-XAML converter, however this proved unsatisfactory for 2 reasons: firstly there was a significant loss of fidelity in the conversion to SVG (which is unusual since the converter is pretty good), and secondly the conversion approach was to create lots of Shape-derived classes absolutely positioned in Canvas elements, so instead I ported and hand-tweaked the brushes. This class uses a serise of GeometryDrawings and should be quite light-weight on tier 2 graphics hardware. On tier 1 the story is a little different, since RadialGradientBrush is NOT hardware accelerated on these platforms. Although the converted brushes are simpler than the SVG originals (for example the slight "ripple" in the reflection line), I'm still pleased with the result as they do look nice.

Download the XAML file with theese brushes in them here

I’m getting errors in the Visual Studio Designer using a custom Attached Property, help!

If you’ve written your own custom attached property in WPF you may come across the following error when you try to look at a Window, Page or UserControl that attempts to use the attached property in the WPF designer in Visual Studio 2008:

The Property '[your custom attached property name]' is read-only and cannot be changed

The puzzling thing is that you can get this error message even if your attached property is not defined as read-only, and has a setter and isn’t registered as read-only in the Property Meta-data. Even more confusingly the property can seem fine and working correctly at run-time.

So what’s going on? Although the error message is a little cryptic the error is caused by a type mismatch between the property type of the dependency property (when it is registered) and the second parameter accepted by the “Set[YourPropertyName]” method that is defined when creating an attached property. For example if you’ve registered an attached property like this: 

public static readonly DependencyProperty MyCustomProperty =
   DependencyProperty.RegisterAttached("MyCustom", typeof(MyOtherType), typeof(MyType));

The property meta-data system expects that when you set this attached property the value will be of MyOtherType (the second type parameter is the type that "owns" the dependency property, usually the type you declare the DP in). Type WPF designer is aware of this, for example if you attempt to assign this property in XAML from a string and no appropriate converter from string to MyOtherType is present it shows an error.

However as part of your attached property declaration you are also obliged to create "Get[PropertyName]" and "Set[PropertyName]" wrapper methods for getting and setting the attached properties.

public static void SetMyCustom(DependencyObject depObj, TheWrongType value)
   depObj.SetValue(MyCustomProperty, value);

If we include the wrong type as the second parameter in one of these declarations – in this case a type that is not assignable from MyOtherType - this isn’t a compile time error (because these methods aren’t part of any interface we’re implementing or generic type) and may work fine at run-time if that code path isn’t called (I believe that XAML bypasses the property wrappers). The designer does pick up on the discrepancy, and considers that type dependency property is read-only because it couldn’t find an appropriately typed "Set[YourPropertyName]” method. Of course this error is easy to resolve once you know the cause, by changing the type of the second parameter to be the same as, or assignable from the type that was used when you declared the dependency property.