2014-01-02 4 views
0

Я работаю в C# и я передаю в свойствах графика в виде строки JSON, например:Получить свойство Excel по имени

{'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

Класс System.Reflection может предоставить то, что вы ищете.

В случае, если некоторые свойства будут фактически полями, следующий код обрабатывает обе ситуации. Для объектов COM он поддерживает только свойства, я слишком устал, чтобы думать о способе поддержки как полей, так и свойств для COM-объектов без уродливых блоков try-catch.

Почему предыдущий код не удался для объектов Interop? Потому что они злые COM-объекты. Хотя Reflection может нормально возвращать поля и свойства для интерфейса без каких-либо проблем, для COM-объектов он потерпел неудачу, потому что их истинным типом во время выполнения является System._ ComObject, который, конечно же, не обладал свойствами, которые вы искали. Обходным методом является использование метода Invoke, который имеет дело с ужасами COM сам по себе. Система. _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"); 
+0

Я реализовал. propertyInfo всегда заканчивается нулевым. Выполнение этого: 'Debug.Print (((Excel.Series) target) .Name)' напечатает текущее имя серии диаграмм, но я не могу получить набор свойств, чтобы я мог использовать SetValue(). –

+0

@TrickySam: Проблема ... странная. Мне удалось точно определить это, понять, а затем сделать обходной путь. Я опубликую результаты через некоторое время, сначала мне нужно превратить свой временный код во что-то, чего мне не будет стыдно показывать. ;) – PTwr

+0

Я ценю вашу помощь. Вам повезло с этим? В чем проблема? –

Смежные вопросы