背景:项目中引用了一个dll,dll中有个自定义控件,自定义控件中有一个打印控件(Private),我的项目要根据权限设置打印控件的一些按钮是否显示
即:修改外部dll的私有控件控件属性。
刚开始想到的就是反射,但是怎么也获取不到这个属性,只能获取公共成员(public),
原来私有成员要不同的搜索类型(System.Reflection.BindingFlags)枚举。
private void FrmControlShow_Shown(object sender, EventArgs e)
{
Microsoft.Reporting.WinForms.ReportViewer newControl = bizReportCongtrol.GetPrivateField<Microsoft.Reporting.WinForms.ReportViewer>("MainReportViewer");
newControl.ShowExportButton = false;
newControl.ShowPrintButton = false;
bizReportCongtrol.SetPrivateField("MainReportViewer", newControl);
}
将方式获取变量值和设置变量值封装在一个静态类中
public static class OperatePrivate
{
public static T GetPrivateField<T>(this ReportControl.BizRdlCongtrol instance, string fieldname)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
FieldInfo field = type.GetField(fieldname, flag);
return (T)field.GetValue(instance);
}
public static void SetPrivateField(this ReportControl.BizRdlCongtrol instance, string fieldname, object value)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
FieldInfo field = type.GetField(fieldname, flag);
field.SetValue(instance, value);
}
}
这边对私有成员的操作做了一个封装(可直接拷贝使用),这边的扩展类型可以自己修改成想要的类型,不一定要用object
using System;
using System.Reflection;
namespace OperateCommon
{
public static class OperatePrivate
{
#region 字段
/// <summary>
/// 获得私有字段的值
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="instance">扩展对象类型</param>
/// <param name="fieldname">私有字段名称 string</param>
/// <returns>私有字段值 T</returns>
public static T GetPrivateField<T>(this object instance, string fieldname)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
FieldInfo field = type.GetField(fieldname, flag);
return (T)field.GetValue(instance);
}
/// <summary>
/// 设置私有字段的值
/// </summary>
/// <param name="instance">扩展对象类型</param>
/// <param name="fieldname">私有字段名称 string</param>
/// <param name="value">私有字段新值 object</param>
public static void SetPrivateField(this ReportControl.BizRdlCongtrol instance, string fieldname, object value)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
FieldInfo field = type.GetField(fieldname, flag);
field.SetValue(instance, value);
}
#endregion
#region 属性
/// <summary>
/// 获取私有属性的值
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="instance">扩展对象类型</param>
/// <param name="propertyname">私有属性名称 string</param>
/// <returns>私有字段值 T</returns>
public static T GetPrivateProperty<T>(this object instance, string propertyname)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
PropertyInfo field = type.GetProperty(propertyname, flag);
return (T)field.GetValue(instance, null);
}
/// <summary>
/// 设置私有属性的值
/// </summary>
/// <param name="instance">扩展对象类型</param>
/// <param name="propertyname">私有属性名称</param>
/// <param name="value">私有属性新值</param>
public static void SetPrivateProperty(this object instance, string propertyname, object value)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
PropertyInfo field = type.GetProperty(propertyname, flag);
field.SetValue(instance, value, null);
}
#endregion
#region 方法
/// <summary>
/// 调用私有方法
/// </summary>
/// <typeparam name="T">返回类型</typeparam>
/// <param name="instance">扩展对象类型</param>
/// <param name="name">私有属性名称 string</param>
/// <param name="param">参数列表 object</param>
/// <returns>调用方法返回值</returns>
public static T CallPrivateMethod<T>(this object instance, string name, params object[] param)
{
BindingFlags flag = BindingFlags.Instance | BindingFlags.NonPublic;
Type type = instance.GetType();
MethodInfo method = type.GetMethod(name, flag);
return (T)method.Invoke(instance, param);
}
#endregion
}
}
以上封装内容参照了http://www.cnblogs.com/8023-1314/archive/2012/12/14/2818743.html