From this article you can learn how to resize description area in PropertyGrid. Example shows use of reflection in order to dig to private members of PropertyGrid - not accessible in normal way.
Implementation is available both in C# and VB.Net languages. Use buttons below to switch language visibility.
Implementation
System.Reflection namespace needs to be put in usings.
privatestaticvoid ChangeDescriptionHeight(PropertyGrid grid, int height){if(grid ==null)thrownew ArgumentNullException("grid");foreach(Control control in grid.Controls)if(control.GetType().Name=="DocComment"){
FieldInfo fieldInfo = control.GetType().BaseType.GetField("userSized",
BindingFlags.Instance|
BindingFlags.NonPublic);
fieldInfo.SetValue(control, true);
control.Height= height;return;}}
PrivateSharedSub ChangeDescriptionHeight(grid As PropertyGrid, height AsInteger)If grid IsNothingThenThrowNew ArgumentNullException("grid")EndIfForEach control As Control In grid.ControlsIf control.[GetType]().Name="DocComment"ThenDim fieldInfo As FieldInfo = control.[GetType]().BaseType.GetField("userSized",
BindingFlags.Instance Or BindingFlags.NonPublic)
fieldInfo.SetValue(control, True)
control.Height= height
ReturnEndIfNextEndSub
From this article you can learn how to define and use simple helper. Example shows generic methods returning list of any type of Attribute from Assembly. AssemblyHelper class can be easily extended with further functionalities as needed.
Implementation and examples are available both in C# and VB.Net languages.
Implementation
Below you can find implementation we use in Karmian Framework as Assembly helper. All members in AssemblyHelper class should be marked as static, so no instance is needed to invoke any. Class AssemblyHelper itself is marked as sealed as we do not want to allow any inheritance. If you need to add new functionality that supports the Assembly - it should be implemented in the class AssemblyHelper. This approach allows the system to prevent duplication of helpers that are responsible for similar actions.
From this article you can learn how to define and use enum description type converter so sytem will know how to handle enum to string and string to enum values (very helpful in PropertyGrid for example).
Implementation is available both in C# and VB.Net languages.
Implementation
Below you can find implementation we use in Karmian Framework as enum description type converter. It can be easily extended to work also as localizable enum description type converter - Description attribute can be used as a key of localized resource.
EnumDescriptionTypeConverter class
usingSystem;usingSystem.ComponentModel;usingSystem.Globalization;namespace Karmian.Core.TypeConverters{publicclass EnumDescriptionTypeConverter : EnumConverter
{public EnumDescriptionTypeConverter(Type type):base(type){}publicoverridebool CanConvertFrom(ITypeDescriptorContext context, Type sourceType){return sourceType ==typeof(string)|| TypeDescriptor.GetConverter(typeof(Enum)).CanConvertFrom(context, sourceType);}publicoverrideobject ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value){if(value isstring)return GetEnumValue(EnumType, (string) value);if(value isEnum)return GetEnumDescription((Enum) value);returnbase.ConvertFrom(context, culture, value);}publicoverrideobject ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType){return value isEnum&& destinationType ==typeof(string)? GetEnumDescription((Enum)value):(value isstring&& destinationType ==typeof(string)? GetEnumDescription(EnumType, (string)value):base.ConvertTo(context, culture, value, destinationType));}publicstaticstring GetEnumDescription(Enum value){
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes =(DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);return(attributes.Length>0)? attributes[0].Description: value.ToString();}publicstaticstring GetEnumDescription(Type value, string name){
var fieldInfo = value.GetField(name);
var attributes =(DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);return(attributes.Length>0)? attributes[0].Description: name;}publicstaticobject GetEnumValue(Type value, string description){
var fields = value.GetFields();foreach(var fieldInfo in fields){
var attributes =(DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);if(attributes.Length>0&& attributes[0].Description== description)return fieldInfo.GetValue(fieldInfo.Name);if(fieldInfo.Name== description)return fieldInfo.GetValue(fieldInfo.Name);}return description;}}}
Imports System.ComponentModelImports System.GlobalizationNamespace Karmian.Core.TypeConvertersPublicClass EnumDescriptionTypeConverter
Inherits EnumConverter
PublicSubNew(type As Type)MyBase.New(type)EndSubPublicOverridesFunction CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type)AsBooleanReturn sourceType IsGetType(String) OrElse TypeDescriptor.GetConverter(GetType([Enum])).CanConvertFrom(context, sourceType)EndFunctionPublicOverridesFunction ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value AsObject)AsObjectIf TypeOf value IsStringThenReturn GetEnumValue(EnumType, DirectCast(value, String))EndIfIf TypeOf value Is[Enum]ThenReturn GetEnumDescription(DirectCast(value, [Enum]))EndIfReturnMyBase.ConvertFrom(context, culture, value)EndFunctionPublicOverridesFunction ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value AsObject, destinationType As Type)AsObjectReturnIf(TypeOf value Is[Enum]AndAlso destinationType IsGetType(String), GetEnumDescription(DirectCast(value, [Enum])), (If(TypeOf value IsStringAndAlso destinationType IsGetType(String), GetEnumDescription(EnumType, DirectCast(value, String)), MyBase.ConvertTo(context, culture, value, destinationType))))EndFunctionPublicSharedFunction GetEnumDescription(value As[Enum])AsStringDim fieldInfo = value.[GetType]().GetField(value.ToString())Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())ReturnIf((attributes.Length > 0), attributes(0).Description, value.ToString())EndFunctionPublicSharedFunction GetEnumDescription(value As Type, name AsString)AsStringDim fieldInfo = value.GetField(name)Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())ReturnIf((attributes.Length > 0), attributes(0).Description, name)EndFunctionPublicSharedFunction GetEnumValue(value As Type, description AsString)AsObjectDim fields = value.GetFields()ForEach fieldInfo As FieldInfo In fields
Dim attributes = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())If attributes.Length > 0AndAlso attributes(0).Description= description ThenReturn fieldInfo.GetValue(fieldInfo.Name)EndIfIf fieldInfo.Name= description ThenReturn fieldInfo.GetValue(fieldInfo.Name)EndIfNextReturn description
EndFunctionEndClassEndNamespace
Some of you have certainly met with many different aspects of developing applications based on extensions. The following publication raises the question of practices for extensions in portable applications.
On msdn pages you will find well designed in theory and with almost identical title as ours: Best Practices for Assembly Loading . In short - we get a knowledge of the 'pros and cons' of different approaches and although unfortunately article lacks of practical examples it is worth to get familiar with it.
Below you can find implementation we use as universal equality comparer. Only lambda expressions as in LINQ queries are needed to measure items. Class LambdaComparer is generic, so you can use it on any type you want to.
Be aware, that executables or assemblies loaded in such manner share main application (host) domain. This implies that if there is any reference needed other from GAC (GlobalAssemblyCache) or host working directory - you will need to handle AppDomain.CurrentDomain.AssemblyResolve event or create new AppDomain for example.
Sample code:
usingSystem;usingSystem.IO;usingSystem.Reflection;namespace ExecutableMemoryStream
{class Program
{staticvoid Main(string[] args){try{if(args.Length==0)thrownew TargetParameterCountException("Expected at least one parameter containing executable path.");using(FileStream fileStream =new FileStream(args[0], FileMode.Open))using(BinaryReader reader =new BinaryReader(fileStream)){byte[] bin = reader.ReadBytes(Convert.ToInt32(fileStream.Length));
Assembly assembly = Assembly.Load(bin);
MethodInfo method = assembly.EntryPoint;if(method !=null){object o = assembly.CreateInstance(method.ReflectedType.Name);if(method.GetParameters().Length==0)
method.Invoke(o, newobject[0]);else{string[] parameters =newstring[args.Length-1];for(int i =1; i < args.Length; i++)
parameters[i -1]= args[i];
method.Invoke(o, new[]{ parameters });}}}}catch(Exception ex){
Console.BackgroundColor= ConsoleColor.Red;
Console.ForegroundColor= ConsoleColor.White;
Console.WriteLine();
Console.WriteLine(ex.Message.PadRight(80));
Console.BackgroundColor= ConsoleColor.Black;
Console.ForegroundColor= ConsoleColor.Yellow;
Console.WriteLine("Hit 'd' for details. Any other key will terminate application.");if(Console.ReadKey(true).KeyChar=='d'){
Console.ForegroundColor= ConsoleColor.Gray;
Console.WriteLine();
Console.WriteLine(ex.StackTrace);
Console.ReadKey();}}}}}
We would like to cover the costs of maintaining the server for longer than a year.
We would like to extend our development environment with some commercial products.
We would like to get rid of the ads from our site.
We would like to take over Karmian.com in order to unify Karmian.
But most of all - we want to provide more free solutions, therefore consider pressing the button below as the absolute expression of your own will and... mood. ;)