2016-08-23 97 views
0

我對WPF有一些樂趣,並決定構建一個帶有附加觸發器(類似於System.Windows.Interactivity.dll)的自定義實現的庫,但是我自己的。在wpf中設置DependencyProperty屬性 - 類型轉換

我有一個類TriggerAction它表示由觸發器調用的操作。我想從一些非常簡單的事情開始,比如在用戶點擊按鈕時設置按鈕的背景。

我已經寫了一些工作代碼,例如EventTrigger類,但我有一個問題與我的SetterTriggerAction。我有兩個依賴屬性PropertyName它代表應該設置一個Value屬性的屬性的名稱。在Invoke方法中,我嘗試使用定義的值設置屬性。

下面是代碼:

internal override void Invoke(DependencyObject obj) 
{ 
     if (obj == null) 
      return; 

     if (string.IsNullOrEmpty(PropertyName)) 
      return; 

     PropertyInfo property = obj.GetType().GetProperty(PropertyName, BindingFlags.Public | BindingFlags.Instance); 

     if (property == null) 
     { 
      Debug.WriteLine("Cannot find property {0} for type {1}.", PropertyName, obj.GetType()); 
      return; 
     } 

     MethodInfo setMethod = property.GetSetMethod(); 

     if (setMethod == null) 
     { 
      Debug.WriteLine("The property {0} does not have set method.", PropertyName); 
      return; 
     } 

     try 
     { 
      setMethod.Invoke(obj, new object[] { Value }); 
     } 
     catch(Exception ex) 
     { 
      Debug.WriteLine("Exception caught {0} with message {1}", ex.GetType(), ex.Message); 
     } 
} 

我的第二次嘗試:

internal override void Invoke(DependencyObject obj) 
{ 
     if (obj == null) 
      return; 
     if (string.IsNullOrEmpty(PropertyName)) return; 
     FieldInfo property = obj.GetType().GetField(PropertyName+"Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); 
     if (property == null) 
     { 
      Debug.WriteLine("Cannot find dependency property {0} for type {1}.", PropertyName+"Property", obj.GetType()); 
      return; 
     } 
     try 
     { 
      DependencyProperty dp = property.GetValue(obj) as DependencyProperty; 
      if(dp == null) 
      { 
       Debug.WriteLine("Cannot get DependencyProperty {0}", PropertyName + "Property"); 
       return; 
      } 
      obj.SetValue(dp, Value); 
     } 
     catch(Exception ex) 
     { 
      Debug.WriteLine("Exception caught {0} with message {1}", ex.GetType(), ex.Message); 
     } 
    } 

XAML中我寫道:

<Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Click"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="Click"> 
       <i:SetterTriggerAction PropertyName="Background" Value="Red"/> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
    </Button> 

所以,當我點擊我要做出自己的按鈕背景紅色。然而,兩種版本的Invoke方法都會遇到轉換問題,並且在我的輸出窗口中,我收到一條消息:「Red」對於屬性Background而言不是有效值(因爲它被視爲字符串而不是Brush!)。 有什麼辦法將xaml(字符串「Red」)的值轉換爲有效的Brush值?我希望有儘可能一般的方式來轉換屬性。

我認爲當xaml被解析並且控件的屬性被設置時,我想要實現的東西就完成了。

任何幫助,將不勝感激。

回答

1

將字符串轉換爲Brush,你可以使用默認的類型轉換器類BrushConverter

var redBrush = (Brush)new BrushConverter().ConvertFromString("Red"); 
+0

我已經有這個問題應對。解決方案是獲取屬性類型並檢查它是否標有TypeConverterAttribute。然後動態創建轉換器的實例並調用ConvertFrom方法。 'PresentationCore'程序集中有很多'TypeConverter'類 – bakala12