我正在实现自己的标记扩展,以确保在Visual Studio中的XAML设计器中正确显示颜色资源。基本上我有一个特殊版本的DynamicResource,它在in design mode时返回某个资源。
我的计划只是从DynamicResourceExtension派生而在ProvideValue中在设计模式下执行特殊代码,并在正常模式下调用基类。
问题是,当我从DynamicResourceExtesion继承时,似乎不会调用我重写的ProvideValue方法。
我强烈怀疑这是框架中的一个错误,但我想在这里发帖,以防我遗漏了一些明显的东西。
以下是相同扩展名的两个版本,一个有效,另一个无效:
撰写版本 - 按预期方式工作
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);
}
}
继承版本 - 这不起作用
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);
}
}
这是我用来测试它的XAML:
<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>
为了完整性,这里是我如何判断我是否处于设计模式(但无关紧要 - 即使我无条件地从Brushes.Blue
返回ProvideValue()
我得到动态查找值。 )
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;
}
}
}