// public static void AddConverter(Type type, ConvertObjectHandler obj) // { // if (_converters == null) // _converters = new Dictionary<Type, ConvertObjectHandler>(); // // _converters[type] = obj; // } #endregion #region Methods /// <summary> /// Adds an Option to a specified target. /// </summary> /// <param name="key">property key - any spaces will be removed</param> /// <param name="value">start value of the property</param> /// <param name="desc">property description</param> /// <param name="category">property category</param> /// <param name="optionChangedEvent">event handler to receive the /// PropertyValueChanged event</param> /// <param name="target">the object that will receive the changed /// property values: an internal event handler will be created and the /// name must be the name of a property of the type that the target is /// whatever that meant</param> internal void AddOption( string key, object value, string desc, string category, OptionChangedEventHandler optionChangedEvent = null, object target = null) { // key = key.Replace(" ", String.Empty); // nobody be stupid ... ViewerOption option; if (!_options.ContainsKey(key)) { option = new ViewerOption(value, desc, category); _options[key] = option; } else { option = _options[key]; option.Value = value; option.Description = desc; } if (optionChangedEvent != null) { option.OptionChangedEvent += optionChangedEvent; } else if (target != null) { _properties[key] = new Property(target, key); this[key].OptionChangedEvent += OnOptionChanged; } }
/// <summary> /// Gets the object tied to the key. If there is no object one will be /// created with the value specified. /// </summary> /// <param name="key">the name of the Option object</param> /// <param name="value">if there is no Option object tied to the /// string, an Option will be created with this as its Value</param> /// <returns>the Option object tied to the key</returns> internal ViewerOption GetOption(string key, object value) { if (!_options.ContainsKey(key)) { var option = new ViewerOption(value, null, null); _options.Add(key, option); } return(_options[key]); }
/// <summary> /// Emits a generic get/set property in which the result returned [there /// is no return..] resides in a hashtable whose key is the name of the /// property. Ie, does complicated stuff. /// </summary> /// <param name="typeBuilder"></param> /// <param name="fieldInfo"></param> /// <param name="option"></param> /// <param name="name"></param> private void EmitProperty( TypeBuilder typeBuilder, FieldInfo fieldInfo, ViewerOption option, string name) { // to figure out what opcodes to emit, i would compile a small class // having the functionality i wanted, and view it with ildasm. // peverify is also kinda nice to use to see what errors there are. var propertyBuilder = typeBuilder.DefineProperty( name, PropertyAttributes.None, option.Value.GetType(), new Type[] {}); var objType = option.Value.GetType(); var methodGetter = typeBuilder.DefineMethod( "get_" + name, MethodAttributes.Public, objType, new Type[] {}); var generator = methodGetter.GetILGenerator(); generator.DeclareLocal(objType); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, fieldInfo); generator.Emit(OpCodes.Ldstr, name); generator.EmitCall( OpCodes.Callvirt, typeof(Hashtable).GetMethod("get_Item"), null); if (objType.IsValueType) { generator.Emit(OpCodes.Unbox, objType); if (_typeHash[objType] != null) { generator.Emit((OpCode)_typeHash[objType]); } else { generator.Emit(OpCodes.Ldobj, objType); } } else { generator.Emit(OpCodes.Castclass, objType); } generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Br_S, (byte)0); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ret); var methodSetter = typeBuilder.DefineMethod( "set_" + name, MethodAttributes.Public, null, new [] { objType }); generator = methodSetter.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, fieldInfo); generator.Emit(OpCodes.Ldstr, name); generator.Emit(OpCodes.Ldarg_1); if (objType.IsValueType) { generator.Emit(OpCodes.Box, objType); } generator.EmitCall( OpCodes.Callvirt, typeof(Hashtable).GetMethod("set_Item"), null); generator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(methodGetter); propertyBuilder.SetSetMethod(methodSetter); if (option.Description != null) { var ctorInfo = typeof(DescriptionAttribute).GetConstructor(new [] { typeof(string) }); var attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[] { option.Description }); propertyBuilder.SetCustomAttribute(attributeBuilder); } if (option.Category != null) { var ctorInfo = typeof(CategoryAttribute).GetConstructor(new [] { typeof(string) }); var attributeBuilder = new CustomAttributeBuilder(ctorInfo, new object[] { option.Category }); propertyBuilder.SetCustomAttribute(attributeBuilder); } }