Custom MarkupExtension && Nested Extensions == Bug
I’m currently working on a custom markup extension and came over a pretty nasty issue. Here’s the working XAML of a dummy extension:
<TextBox Name="txtCity" Foreground="{local:ColorExtension Color=Red}" />
This works like a charm – the fore color is set to red as expected. However – as soon as I try to set the Color property through a resource, I’m getting a compiler error:
<TextBox Name="txtCity" Foreground="{local:ColorExtension Color={StaticResource ErrorBrush}}" />
Here’s the error message: Unknown property ‘Color’ for type ‘MS.Internal.Markup.MarkupExtensionParser+UnknownMarkupExtension’ encountered while parsing a Markup Extension.
Well, the property does exist. Fortunately, Beatriz Costa referred to this bug in her blog – in October 2006. I’m working here with VS2008, targeting .NET 3.5, so I can honestly say: I’m not amused. Fortunately, there’s a workaround: Skip attribute syntax and fall back to property element syntax:
<TextBox Name="txtCity"> <TextBox.Foreground> <local:ColorExtension Color="{StaticResource ErrorBrush}" /> </TextBox.Foreground> </TextBox>
Another solution would be to assign a constructor to the ColorExtension markup extension that takes the Brush as a parameter. In that case, you could write XAML like this:
<TextBox Name="txtCity" Foreground="{local:ColorExtension {StaticResource ErrorBrush}}" />
The compiler accepts a StaticResource as a constructor parameter, but it appears it breaks the VS designer. So for now, it’s property element syntax.
Some other observations: Some extensions can be nested, others can’t. Using DynamicResource also fails to compile, while using a RelativeSource statement or something like {x:Null} works without complaints.
If somebody can shed some light on this, I’ll be happy to update this post accordingly 🙂
Hi Philipp,
How did such a fundamental problem make production 🙁
You did a great job, this damn bug cost me thw whole afternoon. I am very glad finding the real reason.
And I found out the third solution. Put your Custom MarkupExtension into a differnt project. How weird it is.
You’ll be frustrated to know this bug is still alive and well in VS2010 Beta1.. *sigh*…
Thank you for the workaround on this, and thank you also for the BindingDecoratorBase that should have come with WPF in the first place. 🙂
Hi Philipp,
Ok this cost me at least a day but I managed to get attribute syntax to work by putting the custom markup extensions into a separate assembly…
Please don’t ask me why it works for me but it does – attribute syntax and all!
HTH
Clint
Thanks for this tip! Can’t believe this is still a problem. Thought I was losing my mind.
How to parse below string using xamlreader.load() method? i am getting same exception. I am trying to do it on code behind. What can be the possible workaround of it. It does not consider to RelativeSource as extension, instead it takes BaseClass (MarkupExtention) and try to find AncestorType property in it, which is not part of ME.
Aargh I just spent hours on this myself!!
It is still a bug in vs2010 sp1! Can you believe that?
What is stupid is that the designer treats it fine. It is only during compile that it fails.
Still an issue in VS2010 SP1. Putting it in another assembly solves the issue as suggested here.
Hi
If the static resources are converters, the following article shows a workaround to the bug.
http://thejoyofcode.com/WPF_Quick_Tip_Converters_as_MarkupExtensions.aspx
VS 2013 – the bug is still there!
VS 2015 – the bug still exists in .NET 4.6.
Thanks for your workaround.