PropertyGrid控件的使用3

第一个类(C#写的):

public static class ObjectWrapperFactory
{
// Method attributes for get_* set_* methods (property accessors)
private static readonly MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;

public static ObjectWrapper CreateWrapper(object instance)
{
return InternalCreateWrapper(instance, null, false);
}

public static ObjectWrapper CreateWrapperWithVisibleProperties(object instance, string[] propertyNames)
{
if (propertyNames == null)
propertyNames = new string[] { };

return InternalCreateWrapper(instance, propertyNames, true);
}

public static ObjectWrapper CreateWrapperWithHiddenProperties(object instance, string[] propertyNames)
{
if (propertyNames == null)
propertyNames = new string[] { };

return InternalCreateWrapper(instance, propertyNames, false);
}

private static ObjectWrapper InternalCreateWrapper(object instance, string[] propertyNames, bool makeVisible)
{
if (instance == null)
throw new ArgumentNullException("instance");

// Create assembly to hold generated wrapper type
AssemblyName assemblyName = new AssemblyName("ObjectWrapperAssembly");
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

// Create module to store Type information in
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("ObjectWrapperModule.dll");

// Start creating object wrapper type
TypeBuilder wrapperClass = moduleBuilder.DefineType("GeneratedClasses.ObjectWrapper", TypeAttributes.Public);

// Add field to keep reference to wrapped object instance
FieldBuilder wrappedInstanceField = wrapperClass.DefineField("wrappedInstance", instance.GetType(), FieldAttributes.Private);

// Create constructor, that takes wrapped object instance as parameter
CreateConstructor(wrappedInstanceField, wrapperClass, instance);

// Create properties, that are wrappers for instance object properties
PropertyInfo[] propertyCollection = instance.GetType().GetProperties();

if (propertyCollection != null)
foreach (PropertyInfo p in propertyCollection)
{
if (propertyNames == null)
{
CreateProperty(p, wrapperClass, wrappedInstanceField);
}
else
{
if (makeVisible)
{
if (ContainsName(propertyNames, p.Name))
CreateProperty(p, wrapperClass, wrappedInstanceField);
}
else
{
if (!ContainsName(propertyNames, p.Name))
CreateProperty(p, wrapperClass, wrappedInstanceField);
}
}
}

// Build the System.Type
Type wrapperType = wrapperClass.CreateType();
//((AssemblyBuilder)wrapperType.Assembly).Save("ObjectWrapperModule.dll");

// Create wrapper object instance
object wrapper = Activator.CreateInstance(wrapperType, instance);
return new ObjectWrapper(instance, wrapper);
}

private static void CreateConstructor(FieldBuilder instanceField, TypeBuilder typeBuilder, object instance)
{
// Add constructor to take wrapped instance as parameter
Type[] constructorArguments = { instance.GetType() };
ConstructorBuilder constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArguments);

// The constructor calls its superclass constructor. The constructor stores its argument in the private field.
ILGenerator constructorIL = constructor.GetILGenerator();

ConstructorInfo superConstructor = typeof(Object).GetConstructor(Type.EmptyTypes);

constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodes.Call, superConstructor);
constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodes.Ldarg_1);
constructorIL.Emit(OpCodes.Stfld, instanceField);
constructorIL.Emit(OpCodes.Ret);
}

private static void CreateProperty(PropertyInfo propertyInfo, TypeBuilder typeBuilder, FieldBuilder instanceField)
{
// Build wrapper properties, that are mapped to wrapped object properties
PropertyBuilder wrappedInstancePropBldr = typeBuilder.DefineProperty(propertyInfo.Name,
propertyInfo.Attributes,
propertyInfo.PropertyType,
null
);

// Create property getters
CreatePropertyGetter(propertyInfo, wrappedInstancePropBldr, typeBuilder, instanceField);

// Create property setters
CreatePropertySetter(propertyInfo, wrappedInstancePropBldr, typeBuilder, instanceField);

// Create property attributes to display them correctly in the property grid
CreateCustomAttributes(propertyInfo, wrappedInstancePropBldr);
}

private static void CreatePropertyGetter(PropertyInfo propertyInfo, PropertyBuilder propertyBuilder, TypeBuilder typeBuilder, FieldBuilder instanceField)
{
if (propertyInfo.GetGetMethod() == null)
return;

MethodBuilder wrappedInstanceGetPropMthdBldr =
typeBuilder.DefineMethod("get_" + propertyInfo.Name,
getSetAttr,
propertyInfo.PropertyType,
Type.EmptyTypes);

// Method invokes get_* method of the wrapped class.
ILGenerator wrappedInstanceGetIL = wrappedInstanceGetPropMthdBldr.GetILGenerator();

wrappedInstanceGetIL.Emit(OpCodes.Ldarg_0);
wrappedInstanceGetIL.Emit(OpCodes.Ldfld, instanceField);
wrappedInstanceGetIL.Emit(OpCodes.Callvirt, propertyInfo.GetGetMethod());
wrappedInstanceGetIL.Emit(OpCodes.Ret);

propertyBuilder.SetGetMethod(wrappedInstanceGetPropMthdBldr);
}

private static void CreatePropertySetter(PropertyInfo propertyInfo, PropertyBuilder propertyBuilder, TypeBuilder typeBuilder, FieldBuilder instanceField)
{
if (propertyInfo.GetSetMethod() == null)
return;

MethodBuilder wrappedInstanceSetPropMthdBldr =
typeBuilder.DefineMethod("set_" + propertyInfo.Name,
getSetAttr,
null,
new Type[] { propertyInfo.PropertyType });

// Method invokes set_* method of the wrapped class.
ILGenerator wrappedInstanceSetIL = wrappedInstanceSetPropMthdBldr.GetILGenerator();

wrappedInstanceSetIL.Emit(OpCodes.Ldarg_0);
wrappedInstanceSetIL.Emit(OpCodes.Ldfld, instanceField);
wrappedInstanceSetIL.Emit(OpCodes.Ldarg_1);
wrappedInstanceSetIL.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod());
wrappedInstanceSetIL.Emit(OpCodes.Ret);

propertyBuilder.SetSetMethod(wrappedInstanceSetPropMthdBldr);
}

private static void CreateCustomAttributes(PropertyInfo propertyInfo, PropertyBuilder propertyBuilder)
{
Array customAttributes = propertyInfo.GetCustomAttributes(true);
ConstructorInfo ctor = null;
object[] ctorArgs = null;

// In order for properties to be displayed properly inside the property grid
// it is necessary to set appropriate BrowsableAttribute, DescriptionAttribute, CategoryAttribute,
// DisplayNameAttribute attribute values (could be more attributes applicable).
if (customAttributes != null)
foreach (Attribute attribute in customAttributes)
{
ctor = null;
ctorArgs = null;

if (attribute is BrowsableAttribute)
{
BrowsableAttribute a = attribute as BrowsableAttribute;
ctor = typeof(BrowsableAttribute).GetConstructor(new Type[] { typeof(bool) });
ctorArgs = new object[] { a.Browsable };
}

if (attribute is DescriptionAttribute)
{
DescriptionAttribute a = attribute as DescriptionAttribute;
ctor = typeof(DescriptionAttribute).GetConstructor(new Type[] { typeof(string) });
ctorArgs = new object[] { a.Description };
}

if (attribute is CategoryAttribute)
{
CategoryAttribute a = attribute as CategoryAttribute;
ctor = typeof(CategoryAttribute).GetConstructor(new Type[] { typeof(string) });
ctorArgs = new object[] { a.Category };
}

if (attribute is DisplayNameAttribute)
{
DisplayNameAttribute a = attribute as DisplayNameAttribute;
ctor = typeof(DisplayNameAttribute).GetConstructor(new Type[] { typeof(string) });
ctorArgs = new object[] { a.DisplayName };
}

if (ctor != null && ctorArgs != null)
propertyBuilder.SetCustomAttribute(new CustomAttributeBuilder(ctor, ctorArgs));
}

// Property grid by default does not allow editing object properties, but sometimes it is necessary
// to fill in value as a string (i.e. when filling System.Windows.Control.ContentControl.Content value
// for Windows Presentation Foundation ContentControl). For that purpose we add
// TypeConverter(typeof(StringConverter)) attribute to such properties.
if (propertyInfo.PropertyType.Equals(typeof(object)))
{
TypeConverterAttribute a = new TypeConverterAttribute();
ctor = typeof(TypeConverterAttribute).GetConstructor(new Type[] { typeof(System.Type) });
ctorArgs = new object[] { typeof(StringConverter) };
propertyBuilder.SetCustomAttribute(new CustomAttributeBuilder(ctor, ctorArgs));
}
}

private static bool ContainsName(string[] names, string nameToFind)
{
foreach (string name in names)
{
if (name == nameToFind)
return true;
}

return false;
}
}

// Class that stores both references to a real object instance and its wrapper.
public class ObjectWrapper
{
private object _wrappedInstance;

public object WrappedInstance
{
get { return _wrappedInstance; }
}

private object _wrapper;

public object Wrapper
{
get { return _wrapper; }
}

public ObjectWrapper(object element, object wrappedElement)
{
if (element == null)
throw new ArgumentNullException("element");

if (wrappedElement == null)
throw new ArgumentNullException("wrappedElement");

_wrappedInstance = element;
_wrapper = wrappedElement;
}

public bool Contains(object element)
{
if (element == null)
return false;

return (element == _wrappedInstance);
}
}

使用(vb写的)


Dim propertyNames() As String = {"id", "dt", "dataType"} ‘为属性名称


Me.propertyGrid.SelectedObject = ObjectWrapperFactory.CreateWrapperWithHiddenProperties(new EntityValueObject, propertyNames).Wrapper

优点:

不像上一篇介绍的那样必须在编译之前用特性来控制某些属性的可见性,通过使用了代码控制即可实现运行时动态的控制属性的显示与否

从 http://www.codeproject.com/ 学习到的,呵呵!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值