« January 2010 | Main | March 2010 »

February 11, 2010

Attached properties in Silverlight redux

I wrote yesterday about fixing the White Screen of Death when binding to an attached property in a Silverlight control template.  The fix was to repeat the xmlns declaration for the attached property namespace on the root element of the control template.

I ran into this again today and this time inserting the xmlns declaration only gave me an exciting new error: “Exception from HRESULT: 0xC00CEE64.”

Translated from the Silverlighty, this means “Today I am not going to let you redeclare the local: XML namespace on your root element.  Instead, I require you to use a different prefix.”  Thus, instead of writing:

<Border CornerRadius="4" Background="HotPink"
        xmlns:local="clr-namespace:SilverlightFail;assembly=SilverlightFail">

as in yesterday’s example, you would have to write:

<Border CornerRadius="4" Background="HotPink"
        xmlns:fail="clr-namespace:SilverlightFail;assembly=SilverlightFail">

and adjust the property prefix accordingly.

In addition, it appears that the xmlns redeclaration has to be on the immediate parent of the element where you want to use the attached property.

I don’t know why Silverlight sometimes accepts the redeclaration and sometimes does not.  My scenario today used an attached property as the binding target rather than the binding source but the 0xC00CEE64 error occurred just from inserting the xmlns declaration, not even using it, so I don’t think it was that.  Just another mystery.

February 11, 2010 in Software | Permalink | Comments (0) | TrackBack

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 | Comments (0) | TrackBack

February 04, 2010

Breaking the silence

I find this simply amazing: “With one [vegetative state] patient – a Belgian man injured in a traffic accident seven years ago – they asked a series of questions.  He was able to communicate ‘yes’ and ‘no’ using just his thoughts.  The team told him to use ‘motor’ imagery like a tennis match to indicate ‘yes’ and ‘spatial’ imagery like thinking about roaming the streets for a ‘no’.”

February 4, 2010 in Science | Permalink | Comments (1) | TrackBack