« Breaking the silence | Main | Attached properties in Silverlight redux »
February 10, 2010
Attached properties in Silverlight control templates
Attached properties in WPF and Silverlight are a handy way to associate extra information with a control, and a common way to use them in WPF is to create a control template which consumes the extra data via a template binding.
Unfortunately, if you do this in Silverlight, it gives you the White Screen of Death, and either no exception at all or the infamous "Error HRESULT E_FAIL has been returned from a call to a COM component” which is like getting no exception at all except more irritating. Here’s a simple repro case:
<UserControl x:Class="SilverlightFail.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightFail">
<UserControl.Resources>
<Style x:Key="Testy" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="4" Background="HotPink">
<TextBlock Text="{Binding (local:Test.TestString),
RelativeSource={RelativeSource TemplatedParent}}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot">
<TextBlock Text="Button to follow" />
<Button local:Test.TestString="Fie!" Style="{StaticResource Testy}" />
</StackPanel>
</UserControl>
Here we’ve defined a custom Button style which simply renders the attached Test.TestString property in a pink box. Run this sample (with the obvious attached property definition) and you get the White Screen of Death. You may get the COM exception – I get the exception on my home machine but nothing on my work machine, so this may be a 32/64-bit issue, I don’t know. But what you don’t get is a the word “Fie!” rendered on glorious HotPink. You don’t even get the “Button to follow” text, proving that it’s not just the button failing to render: the entire application has been taken down.
The problem is that, for some reason, Silverlight has forgotten about the local: XML namespace by the time it gets to the control template, and needs to be reminded. So you can work around the problem by redeclaring the attached property namespace on the root element of the template.
Unfortunately, it’s not quite as simple as that. If you just replicate the xmlns declaration from the root:
<Border CornerRadius="4" Background="HotPink"
xmlns:local="clr-namespace:SilverlightFail">
then you still get the White Screen of Death, though if your system gets exceptions then you’ll now get a helpful ArgumentException albeit with the less helpful message “Cannot resolve attached DependencyProperty local:Test.TestString in (local:Test.TestString).”
The trick is that you also need to explicitly specify the assembly, which you don’t normally have to do for the current assembly:
<Border CornerRadius="4" Background="HotPink"
xmlns:local="clr-namespace:SilverlightFail;assembly=SilverlightFail">
<TextBlock Text="{Binding (local:Test.TestString),
RelativeSource={RelativeSource TemplatedParent}}" />
</Border>
With this extra assistance Silverlight is finally able to resolve the attached property and your application reappears at last.
In related news, the beatings will continue until morale improves.
February 10, 2010 in Software | Permalink
TrackBack
TrackBack URL for this entry:
https://www.typepad.com/services/trackback/6a00d8341c5c9b53ef0120a8840d29970b
Listed below are links to weblogs that reference Attached properties in Silverlight control templates: