在wpf - type convertion中从反射设置DependencyProperty

时间:2016-08-23 21:35:50

标签: c# wpf xaml reflection dependency-properties

我对WPF有一些乐趣,我决定构建一个带有附加触发器的自定义实现的库(类似于System.Windows.Interactivity.dll),但我自己。

我有一个类TriggerAction,它代表Trigger调用的一个动作。我想从一些非常简单的事情开始,比如在用户点击它时设置按钮的背景。

我已经编写了一些工作代码,例如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 个答案:

答案 0 :(得分:1)

要将字符串转换为Brush,您可以使用默认类型转换器类BrushConverter

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