这是一种看似简单,但实际上没有完美解决方案的任务(或者我没有找到)。第一种方法是使用值转换器。但它不起作用!我们需要设置转换器无法正确完成的资源引用。所以,我认为正确的方法是依附行为。但是您应该了解限制:只能将资源应用于一个属性。也许您可以根据您的要求避免此限制。
附加行为允许您将具有指定名称的资源引用到指定的依赖属性:
public static class BrushResourceKeyBehavior
{
#region ResourceKey Property
public static readonly DependencyProperty ResourceKeyProperty = DependencyProperty.RegisterAttached(
"ResourceKey", typeof(object), typeof(BrushResourceKeyBehavior),
new FrameworkPropertyMetadata(OnResourceKeyChanged));
public static object GetResourceKey(DependencyObject dependencyObject)
{
return dependencyObject.GetValue(ResourceKeyProperty);
}
public static void SetSource(DependencyObject dependencyObject, object value)
{
dependencyObject.SetValue(ResourceKeyProperty, value);
}
#endregion
#region TargetProperty Property
public static readonly DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached(
"TargetProperty", typeof(DependencyProperty), typeof(BrushResourceKeyBehavior),
new FrameworkPropertyMetadata(OnTargetPropertyChanged));
public static DependencyProperty GetTargetProperty(DependencyObject dependencyObject)
{
return (DependencyProperty)dependencyObject.GetValue(TargetPropertyProperty);
}
public static void SetTargetProperty(DependencyObject dependencyObject, DependencyProperty value)
{
dependencyObject.SetValue(TargetPropertyProperty, value);
}
#endregion
private static void OnResourceKeyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var targetProperty = GetTargetProperty(dependencyObject);
if (targetProperty != null)
{
if (e.NewValue == null)
{
dependencyObject.ClearValue(targetProperty);
}
else
{
SetResourceReference(dependencyObject, targetProperty);
}
}
}
private static void OnTargetPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var oldValue = e.OldValue as DependencyProperty;
var newValue = e.NewValue as DependencyProperty;
if (oldValue != null)
{
dependencyObject.ClearValue(oldValue);
}
if (newValue != null)
{
SetResourceReference(dependencyObject, newValue);
}
}
private static void SetResourceReference(DependencyObject dependencyObject, DependencyProperty targetProperty)
{
var fe = dependencyObject as FrameworkElement;
if (fe != null)
{
fe.SetResourceReference(targetProperty, String.Format("ch_{0}", GetResourceKey(fe)));
}
else
{
var fce = dependencyObject as FrameworkContentElement;
if (fce != null)
{
fce.SetResourceReference(targetProperty, String.Format("ch_{0}", GetResourceKey(fce)));
}
}
}
}
行为可以在 XAML 中使用,如下所示:
<ItemsControl>
<Border local:BrushResourceKeyBehavior.Source="YSD"
local:BrushResourceKeyBehavior.TargetProperty="Border.Background"
Height="20"/>
<Border local:BrushResourceKeyBehavior.Source="HJU"
local:BrushResourceKeyBehavior.TargetProperty="Border.Background"
Height="20"/>
<Border local:BrushResourceKeyBehavior.Source="IYO"
local:BrushResourceKeyBehavior.TargetProperty="Border.Background"
Height="20"/>
</ItemsControl>
上面的代码等价于:
<ItemsControl>
<Border Background="{DynamicResource ch_YSD}"
Height="20"/>
<Border Background="{DynamicResource ch_HJU}"
Height="20"/>
<Border Background="{DynamicResource ch_IYO}"
Height="20"/>
</ItemsControl>