2012-04-08 58 views
1

我在Application.xaml中定義了幾百個畫筆。這些是項目中多個用戶控件的共享資源。他們都有圖案的鍵:ch_YSD,ch_HJU,ch_IYO ...如何根據綁定在XAML中選擇畫筆

我嘗試在數據模板中使用這些畫筆。在datatemplate中,我可以訪問刷鍵的可變部分,即在數據模板中,我可以將YSD,HJU,IYO等作爲字符串獲取。

如何從xaml綁定到特定的畫筆資源?

目前我有這樣的解決方案:在樣式中使用數據觸發器根據綁定字符串(鍵的可變部分)將所需屬性設置爲指定筆刷。 我對此解決方案並不滿意,因爲Application.xaml中的畫筆列表經常會增加。

我不確定是否應該使用代碼,因爲我想在Application.xaml中使用共享資源的內存保護。

回答

2

這是一種看起來很簡單但實際上沒有完美解決方案的任務(或者我沒有找到它)。第一種方法是使用價值轉換器。但它不起作用!我們需要設置轉換器無法正確完成的資源參考。所以,我認爲正確的方式是附加行爲。但是您應該瞭解限制:可以只有一個屬性將資源應用到。也許你可以根據你的要求避免這個限制。

附加的行爲,您可以參考資源與指定的命名到指定的依賴項屬性:

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> 
+0

非常感謝這個優秀的例子,你救了我的一天! :) – Dima 2012-04-09 11:18:36