2016-08-23 94 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