Abstract
Property grid is a control which has strong capabilities.
Property grid extracts the properties of the class and displays corresponding values. A user can display a user friendly name that can differ from the property used for the class. Property name can be displayed in a different language as well. If multi language software is needed, the user may need to display property names in more than one language, maybe with switching between the languages at runtime.
Architecture
Designing Class
The class can be designed with different attributes, to be used in property grid. These attributes belong to System.ComponentModel
namespace.
Assignment of Default Property for the Class
DefaultPropertyAttribute("<PropertyName>")
is the attribute which is used to create the property default to the class.
[DefaultPropertyAttribute("Name")]
public class ExploringPropertyGrid
{
public property Name
{
get{}
set{}
}
}
The above block of code will make the property Name
default while browsing the object of the class in property grid.
Other Attributes
[Browsable(true)]
[CategoryAttribute("Settings")]
[DescriptionAttribute("Name of the object")]
[ReadOnlyAttribute(false)]
Editing Property the Grid
Property grid allows the user to edit the property in the grid according to the type. A boolean
and an enum
value shall be allowed to select from combo, while an integer
type property shall be allowed to user to enter a value.
Using a Non boolean, Non enum Data Type as a Combo Editing
Here a type converter is useful to make a property editable as combo values in grid. Here is the code for sample converter. The code converts a string
to combo type.
public class BTypeConVerter : StringConverter
{
public string[] tempStr;
public override bool GetStandardValuesSupported
(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive
(ITypeDescriptorContext context)
{
return true;
}
public override object ConvertFrom(ITypeDescriptorContext context,
System.Globalization.CultureInfo culture, object value)
{
return base.ConvertFrom(context, culture, value);
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection
GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new string[]{ "Val1", "Val2", "Val3" });
}
}
Accessing the Class's Members in Converter Class
The other members of the converting member's class, can be accessed under the converter class, context
is the access door to the class instance. In the context.Instance
you can find the instance of the current context. User can cast it to the class type and can access the member in the current context. The code example shows the same method.
public override System.ComponentModel.TypeConverter.StandardValuesCollection
GetStandardValues(ITypeDescriptorContext context)
{
(context.Instance as ExploringPropertyGrid).Name = -----------
}
Using Converter in the Property
[TypeConverter(typeof(BTypeConVerter))
public string Title
{
get{}
set
{
//Set the another property values Here
}
}
Hiding a Property from Property Grid at Runtime
The attributes of a property can be set as read-only in runtime for property grid using a PropertyDescriptor
. User can set it either in a member function of a class or in a get{} set{}
section of property. The following code sets the readonly attribute of a property “DataType
” to true
. In the same way, the user can set it as false
.
PropertyDescriptor descriptor =
TypeDescriptor.GetProperties(this.GetType())["DataType"];
ReadOnlyAttribute attrib =
(ReadOnlyAttribute)descriptor.Attributes[typeof(ReadOnlyAttribute)];
FieldInfo isReadOnly =
attrib.GetType().GetField("isReadOnly", BindingFlags.NonPublic| BindingFlags.Instance);
isReadOnly.SetValue(attrib, true);
Note: ReadOnlyAttribute
of all the properties must be set before, like [ReadOnlyAttribute(true)]
, while writing the class. Otherwise, the above code will set all the property’s attributes to true
.
In the same way, the Browsable
attribute of any property can be set at runtime using PropertyDescriptor
. Here is the code:
PropertyDescriptor descriptor=
TypeDescriptor.GetProperties(this.GetType())["DataType"];
BrowsableAttribute attrib=
(BrowsableAttribute)descriptor.Attributes[typeof(BrowsableAttribute)];
FieldInfo isBrow =
attrib.GetType().GetField("browsable",BindingFlags.NonPublic | BindingFlags.Instance);
isBrow.SetValue(attrib,false);
The point to remember in both the cases is that all the attributes must be set for all properties, otherwise it will refresh all the properties of the class.