I'm implementing my own markup extension to make sure color resources show up properly in the XAML designer in Visual Studio. Basically I have a special version of DynamicResource that returns a certain resource when in design mode.
My plan was simply to derive from DynamicResourceExtension and in ProvideValue do special code when in design mode and just call the base class when in normal mode.
The problem is that when I inherit from DynamicResourceExtesion, it doesn't seem like my overridden ProvideValue method gets called.
I'm strongly suspecting this is a bug in the framework but I want to post here in case I'm missing something obvious.
Here are two version of the same extension, one that works and one that doesn't:
Composition version - this works as expected
public class MyResourceComposition : MarkupExtension
{
private readonly DynamicResourceExtension m_dynamicResource = new DynamicResourceExtension();
public MyResourceComposition()
{}
public MyResourceComposition(string resourceKey)
{
ResourceKey = resourceKey;
}
public object ResourceKey
{
get { return m_dynamicResource.ResourceKey; }
set { m_dynamicResource.ResourceKey = value; }
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (Helper.IsInDesignMode)
return Brushes.Blue;
return m_dynamicResource.ProvideValue(serviceProvider);
}
}
Inheritance version - this does not work
public class MyResourceInheritance : DynamicResourceExtension
{
public MyResourceInheritance()
{}
public MyResourceInheritance(string resourceKey)
:base(resourceKey)
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (Helper.IsInDesignMode)
return Brushes.Blue;
return base.ProvideValue(serviceProvider);
}
}
This is the XAML I use to test it:
<UserControl.Resources>
<SolidColorBrush Color="Green" x:Key="MyBrush" />
</UserControl.Resources>
<StackPanel>
<!-- This will be green at design time: OK! -->
<Rectangle Fill="{DynamicResource ResourceKey=MyBrush}" Width="50" Height="50" Margin="8" />
<!-- This will be green at design time: NOT OK! -->
<Rectangle Fill="{local:MyResourceInheritance ResourceKey=MyBrush}" Width="50" Height="50" Margin="8" />
<!-- This will be green at design time: OK! -->
<Rectangle Fill="{local:MyResourceComposition ResourceKey=MyBrush}" Width="50" Height="50" Margin="8" />
</StackPanel>
For completeness, here's how I figure out if I'm in design mode (but it doesn't matter - even if I unconditionally return Brushes.Blue
from ProvideValue()
I get the dynamically looked up value.)
internal static class Helper
{
private static bool? s_isInDesignMode;
public static bool IsInDesignMode
{
get
{
if (!s_isInDesignMode.HasValue)
{
var prop = DesignerProperties.IsInDesignModeProperty;
s_isInDesignMode
= (bool)DependencyPropertyDescriptor
.FromProperty(prop, typeof(FrameworkElement))
.Metadata.DefaultValue;
}
return s_isInDesignMode.Value;
}
}
}