按名称获取Excel属性

时间:2014-01-02 15:28:59

标签: c# .net excel charts

我正在使用c#,我将图表属性作为json字符串传递,例如:

{'chart':{
'series':{
    'count':3,
    'style':'3 Series Scaled Bars',
    'data':[
        {'x':'Brand','y':'Avg Comments','type':'barScaled','position':1}
        {'x':'Brand','y':'Avg Likes','type':'barScaled','position':2}
        {'x':'Brand','y':'Avg Shares','type':'barScaled','position':3}
    ]
}}}

我希望能够做的是传递类似这样的内容:'markerSize':8并且能够使用属性的字符串名称设置属性,类似这样:

Excel.SeriesCollection lines = (Excel.SeriesCollection)chrt.SeriesCollection();
Excel.Series ser = sers.Item(1);
ser.Properties("markerSize") = 8;

这可能吗,还是我必须编写代码来处理我需要修改的每个属性?

1 个答案:

答案 0 :(得分:1)

System.Reflection类可以提供您所寻找的内容。

如果某些属性实际上是字段,则代码处理这两种情况。 对于COM对象,它只支持属性,我太累了,不会想到一种方法来支持COM对象的字段和属性而不需要丑陋的try-catch块。

为什么以前的代码对Interop对象失败了?因为它们是邪恶的COM对象。 虽然Reflection通常可以返回接口的字段和属性而没有任何问题,但对于COM对象,它失败了,因为它们在运行时的真实类型是System ._ ComObject,它当然缺少您正在寻找的属性。 解决方法是使用Invoke方法,它自己处理COM的恐怖。 System。 _ComObject是隐藏类型,因此它被测试为字符串而不是Type。 (我累了)

using System.Reflection;
...
    /// <summary>
    /// Dynamicaly sets property of given object with given value. No type casting is required. Supports COM objects properties.
    /// </summary>
    /// <param name="target">targeted object</param>
    /// <param name="propertyName">property name</param>
    /// <param name="value">desired value</param>
    /// <returns>True if success, False if failure (non existing member)</returns>
    static bool SetProperty(object target, string propertyName, object value)
    {
        Type t = target.GetType();
        if(t.ToString()=="System.__ComObject")
        {
            t.InvokeMember(propertyName, BindingFlags.SetProperty, null, target, new object[] { value });
            return true;
        }
        PropertyInfo propertyInfo = t.GetProperty(propertyName);
        FieldInfo fieldInfo = t.GetField(propertyName);
        if (propertyInfo != null)
        {
            propertyInfo.SetValue(target, Convert.ChangeType(value, propertyInfo.PropertyType, null));
            return true;
        }
        if (fieldInfo!=null)
        {
            fieldInfo.SetValue(target, Convert.ChangeType(value, fieldInfo.FieldType, null));
            return true;
        }            
        return false;
    }

//usage:
foo bar = new foo();
SetProperty(bar,"myPropertyOrField","myValue");