
Introduction
This article discusses three types of drop down properties:
- Dynamic Enumeration - View a drop down combo box with dynamic values.
- Images & Text - Show different bitmaps based on the value in the drop down list.
- Drop Down Editor - Show a custom UI type editor as a drop down form.
Dynamic Enumeration
Often, we would like to show dynamic values in a combo box, avoiding hard coded values. Instead, we may load them from a database or text files to support globalization and more. In this case, the property is called Rule, and rules are loaded from the RichTextBox. First, we define an internal class, having a string array containing the list of values.
Collapse |
Copy Code
internal class HE_GlobalVars
{
internal static string[] _ListofRules;
}We also define a type converter as follows:
Collapse |
Copy Code
public class RuleConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection
GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(HE_GlobalVars._ListofRules);
}
}The Rule property is defined as follows:
Collapse |
Copy Code
true)>
[TypeConverter(typeof(RuleConverter))]
public string Rule
{
get {
string S = "";
if (_Rule != null)
{
S = _Rule;
}
else
{
if (HE_GlobalVars._ListofRules.Length > 0)
{
Array.Sort(HE_GlobalVars._ListofRules);
S = HE_GlobalVars._ListofRules[0];
}
}
return S;
}
set{ _Rule = value; }
}Then, from the application itself, we fill the list of rules:
Collapse |
Copy Code
private void UpdateListofRules()
{
int _NumofRules = richTextBox1.Lines.Length;
HE_GlobalVars._ListofRules = new string[_NumofRules];
for(int i = 0; i <= _NumofRules - 1; i++)
{
HE_GlobalVars._ListofRules[i] = richTextBox1.Lines[i];
}
}Images & Text
Some property types such as Image, Color, or Font.Name paint a small representation of the value just to the left of the space where the value is shown. This is accomplished by implementing the UITypeEditor PaintValuemethod. When the property browser renders a property value for a property that defines an editor, it presents the editor with a rectangle and a Graphics object with which to paint.
Here the property named SourceType is shown as a drop down list where each value has its own image located next to it. Images are loaded from a resource file.
Collapse |
Copy Code
public enum HE_SourceType {LAN, WebPage, FTP, eMail, OCR}
public class SourceTypePropertyGridEditor : UITypeEditor
{
public override bool GetPaintValueSupported(ITypeDescriptorContext context)
{
return true;
}
public override void PaintValue(PaintValueEventArgs e)
{
string m = this.GetType().Module.Name;
m = m.Substring(0, m.Length - 4);
ResourceManager resourceManager =
new ResourceManager (m + ".ResourceStrings.SampleResources",
Assembly.GetExecutingAssembly());
int i = (int)e.Value;
string _SourceName = "";
switch(i)
{
case ((int)HE_SourceType.LAN): _SourceName = "LANTask"; break;
case ((int)HE_SourceType.WebPage): _SourceName = "WebTask"; break;
case ((int)HE_SourceType.FTP): _SourceName = "FTPTask"; break;
case ((int)HE_SourceType.eMail): _SourceName = "eMailTask"; break;
case ((int)HE_SourceType.OCR): _SourceName = "OCRTask"; break;
}
Bitmap newImage = (Bitmap)resourceManager.GetObject(_SourceName);
Rectangle destRect = e.Bounds;
newImage.MakeTransparent();
e.Graphics.DrawImage(newImage, destRect);
}
}
[Editor(typeof(SourceTypePropertyGridEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public HE_SourceType SourceType
{
get{return _SourceType;}
set{_SourceType = value;}
}Drop Down Editor
Visual Studio .NET uses type converters for text-based property editing and code serialization. Some built-in types, such as Color or DockStyle, get a specialized user interface in the property grid as well as text support. If you would like to supply a graphical editing interface for your own property types, you can do so by supplying a UI type editor as a drop-down editor user interface.
First, we create a form to be used as an editor. When initializing the form, we must set its TopLevel property tofalse. To make it caption-less, we have to set the following properties:
Collapse |
Copy Code
this.MaximizeBox = false;
this.MinimizeBox = false;
this.ControlBox = false;
this.ShowInTaskbar = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
The Contrast property is used in this case.
The following code uses the IServiceProvider passed to EditValue. It asks it for theIWindowsFormsEditorService interface (which is defined in the System.Windows.Forms.Designnamespace). This service provides the facility for opening a drop-down editor, we simply call the DropDownControlmethod on it, and it will open whichever control we pass. It sets the size and location of the control so that it appears directly below the property when the drop-down arrow is clicked.
When we write the UI editor class itself, we have a choice as to the kind of user interface we can supply. We can either open a modal dialog or supply a pop-up user interface that will appear in the property grid itself. We indicate this by overriding the GetEditStyle method. This method returns a value from the UITypeEditorEditStyleenumeration, either Modal or DropDown. For either type of user interface, we must also override the EditValuemethod, which will be called when the user tries to edit the value. The value returned from EditValue will be written back to the property. It will call EditValue when the arrow button is clicked.
Collapse |
Copy Code
public class ContrastEditor : UITypeEditor
{
public override UITypeEditorEditStyle
GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
IWindowsFormsEditorService wfes =
provider.GetService(typeof(IWindowsFormsEditorService)) as
IWindowsFormsEditorService;
if (wfes != null)
{
frmContrast _frmContrast = new frmContrast();
_frmContrast.trackBar1.Value = (int) value;
_frmContrast.BarValue = _frmContrast.trackBar1.Value;
_frmContrast._wfes = wfes;
wfes.DropDownControl(_frmContrast);
value = _frmContrast.BarValue;
}
return value;
}
}