這是一種看起來很簡單但實際上沒有完美解決方案的任務(或者我沒有找到它)。第一種方法是使用價值轉換器。但它不起作用!我們需要設置轉換器無法正確完成的資源參考。所以,我認爲正確的方式是附加行爲。但是您應該瞭解限制:可以只有一個屬性將資源應用到。也許你可以根據你的要求避免這個限制。
附加的行爲,您可以參考資源與指定的命名到指定的依賴項屬性:
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>
非常感謝這個優秀的例子,你救了我的一天! :) – Dima 2012-04-09 11:18:36