C# 按名称获取Excel属性
我在c#中工作,并将图表属性作为json字符串传递,例如:C# 按名称获取Excel属性,c#,.net,excel,charts,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','posi
{'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;
这是可能的,还是我必须编写代码来处理需要修改的每个属性?System.Reflection类可能会提供您想要的 在这种情况下,一些属性实际上是字段,下面的代码处理这两种情况。 对于COM对象,它只支持属性,我想不出一种方法来支持COM对象的字段和属性,而不使用难看的try-catch块 为什么以前的代码对互操作对象失败?因为它们是邪恶的COM对象。 虽然反射通常可以为接口返回字段和属性而没有任何问题,但对于COM对象,它失败了,因为它们在运行时的真正类型是System.\u ComObject,当然它缺少您要查找的属性。 解决方法是使用Invoke方法,它自己处理COM的恐怖。 System.\u ComObject是隐藏类型,因此它被测试为字符串而不是类型。(我累了)
使用系统反射;
...
///
///Dynamicly使用给定值设置给定对象的属性。不需要类型转换。支持COM对象属性。
///
///目标物体
///属性名
///期望值
///成功时为True,失败时为False(不存在成员)
静态bool SetProperty(对象目标、字符串属性名称、对象值)
{
类型t=target.GetType();
if(t.ToString()=“系统对象”)
{
t、 InvokeMember(propertyName,BindingFlags.SetProperty,null,target,新对象[]{value});
返回true;
}
PropertyInfo PropertyInfo=t.GetProperty(propertyName);
FieldInfo FieldInfo=t.GetField(propertyName);
if(propertyInfo!=null)
{
SetValue(target,Convert.ChangeType(value,propertyInfo.PropertyType,null));
返回true;
}
如果(fieldInfo!=null)
{
fieldInfo.SetValue(target,Convert.ChangeType(value,fieldInfo.FieldType,null));
返回true;
}
返回false;
}
//用法:
foo-bar=新的foo();
SetProperty(条形图,“myPropertyOrField”、“myValue”);
我实现了。propertyInfo总是以null结尾。执行此操作:Debug.Print(((Excel.Series)target.Name)
将打印图表系列的当前名称,但我似乎无法获取propertyInfo集,以便对其使用SetValue()。@TrickySam:问题是。。。奇怪的我设法找出它,理解它,然后采取变通办法。我将在一段时间后发布结果,首先我需要将我的临时代码转换为我不会羞于展示的内容我感谢你的帮助。你运气好吗?问题是什么?我已经更新了答案,问题是互操作对象将自己报告为“System.\uu ComObject”,因此它们需要这样对待,例如,通过使用InvokeMember正面攻击它们。这次我在发布之前在interop对象上测试了它。;)对不起,我想我没看到。这很好用。不管怎样,谢谢你的这一套。我将来会用这个。我处理了很多“邪恶的COM对象”,哈哈。
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");