PropertyGrid是个很有趣的控件。
只需要一个语句,就能实现许多功能。
尤其在开发工具类软件时,非常有用。
启先,想做个能够把一个XML节点用PropertyGrid来显示的控件。
把XML结点的属性值都列在PropergyGrid上。经过一段时间摸索,做成了。
结果却因为效率问题并未使用,如在效率不是问题的情况下应该还是能用的。
核心函数放在这里,供有需要的人参考吧。
private object CreateDynamicXMLPropertyClass(XmlNode objXMLNode)
... {
object objReturn;
string strDynamicAssemblyName = "XMLViewerRunTimeClassAssembly";
string strDynamicModuleName = "XMLViewerRunTimeModule";
string strDynamicClassName = "XMLViewerRunTimeClass" + DateTime.Now.Ticks.ToString();
string strPropertyName = string.Empty;
Type typeDynamic = null;
FieldInfo fieldInfo = null;
AppDomain currentDomain = null;
TypeBuilder typeBuilder = null;
ILGenerator ilGenerator = null;
AssemblyName assemblyName = null;
FieldBuilder fieldBuilder = null;
ModuleBuilder moduleBuilder = null;
MethodBuilder methodBuilder = null;
PropertyBuilder propertyBuilder = null;
AssemblyBuilder assemblyBuilder = null;
MethodAttributes getSetAttr;
Type[] methodArgs = ...{ typeof(string) };
IEnumerator objAttributes = null;
currentDomain = AppDomain.CurrentDomain;
assemblyName = new AssemblyName();
assemblyName.Name = strDynamicAssemblyName;
//Define a Dynamic Assembly
assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
//Define a Dynamic Module
moduleBuilder = assemblyBuilder.DefineDynamicModule(strDynamicModuleName);
//Define a runtime class with specified name and attributes.
typeBuilder = moduleBuilder.DefineType(strDynamicClassName, TypeAttributes.Public);
if (objXMLNode.Attributes != null)
...{
objAttributes = objXMLNode.Attributes.GetEnumerator();
while (objAttributes.MoveNext())
...{
XmlAttribute objXMLAttribute = (XmlAttribute)objAttributes.Current;
strPropertyName = objXMLAttribute.Name;
// Add the class variable, such as "m_strIPAddress"
fieldBuilder = typeBuilder.DefineField("m_str" + strPropertyName, typeof(string), FieldAttributes.Public);
propertyBuilder = typeBuilder.DefineProperty(strPropertyName, System.Reflection.PropertyAttributes.HasDefault, typeof(string), null);
getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
methodBuilder = typeBuilder.DefineMethod("get_" + strPropertyName, getSetAttr, typeof(string), Type.EmptyTypes);
ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(methodBuilder);
methodBuilder = typeBuilder.DefineMethod("set_" + strPropertyName,
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName,
typeof(void), methodArgs);
ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(methodBuilder);
}
}
// Add the class variable, such as "m_strIPAddress"
strPropertyName = "XMLSource";
fieldBuilder = typeBuilder.DefineField("m_str" + strPropertyName, typeof(string), FieldAttributes.Public);
propertyBuilder = typeBuilder.DefineProperty(strPropertyName, System.Reflection.PropertyAttributes.HasDefault, typeof(string), null);
getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
methodBuilder = typeBuilder.DefineMethod("get_" + strPropertyName, getSetAttr, typeof(string), Type.EmptyTypes);
ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder);
ilGenerator.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(methodBuilder);
//methodBuilder = typeBuilder.DefineMethod("set_" + strPropertyName,
// MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName,
// typeof(void), methodArgs);
//ilGenerator = methodBuilder.GetILGenerator();
//ilGenerator.Emit(OpCodes.Ldarg_0);
//ilGenerator.Emit(OpCodes.Ldarg_1);
//ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
//ilGenerator.Emit(OpCodes.Ret);
//propertyBuilder.SetSetMethod(methodBuilder);
//Create Class
typeBuilder.CreateType();
typeDynamic = moduleBuilder.GetType(strDynamicClassName);
//Create Class Instance
objReturn = Activator.CreateInstance(typeDynamic, null, null);
if (objAttributes != null)
...{
objAttributes.Reset();
while (objAttributes.MoveNext())
...{
XmlAttribute objXMLAttribute = (XmlAttribute)objAttributes.Current;
strPropertyName = objXMLAttribute.Name;
fieldInfo = typeDynamic.GetField("m_str" + strPropertyName);
fieldInfo.SetValue(objReturn, objXMLAttribute.Value);
}
}
// Keep the source of XML
strPropertyName = "XMLSource";
fieldInfo = typeDynamic.GetField("m_str" + strPropertyName);
fieldInfo.SetValue(objReturn, objXMLNode.OuterXml);
return objReturn;
}