Advanced Design Time Support For Your Components

posted @ Tuesday, September 6, 2005 11:38 PM

 

Have you ever noticed the blue links below the property grid of a objects such as the DataGrid or TabControl when you drag it onto a form? These links provide additional configuration functionality of their objects through various means; a UITypeEditor is used for the DataGrid for example. Implementing this functionality is rather simple, here is just an example.

The follow example will allow you to edit the FullName value through a custom UITypeEditor, exposing the editor several different ways, one of which is a custom designer for the component.

namespace DeveloperNotes
{
using System;
using
System.Drawing;
using
System.Windows.Forms;
using
System.Windows.Forms.Design;
using
System.Drawing.Design;
using
System.ComponentModel;
using
System.ComponentModel.Design;

[Designer(typeof(ManagerDesigner))]
public class ManagerComponent : Component
{
public ManagerComponent(){}

private static string name = string.Empty;

[Editor(typeof(NameEditor), typeof(UITypeEditor))]
public string FullName
{
get{return name;}
set{name = value;}
}
}

internal class ManagerDesigner : ComponentDesigner
{
DesignerVerbCollection verbs
= null;
frmNameEditor editor = null;
ManagerComponent mgr = null;

public
ManagerDesigner(){}
public override void Initialize(IComponent component)
{
mgr
= component as ManagerComponent;
base
.Initialize(component);
}

public override DesignerVerbCollection Verbs
{
get
{
if(verbs == null)
{
verbs
= new DesignerVerbCollection();
DesignerVerb verb = new DesignerVerb("Configure Advanced Functionality",
new EventHandler(ConfigAdvanced));
verbs.Add(verb);
}
return verbs;
}
}

public void ConfigAdvanced(object sender, EventArgs e)
{
if(editor == null)
editor
= new frmNameEditor();

editor.FullName = mgr.FullName;
DialogResult dr = editor.ShowDialog();
if
(dr == DialogResult.OK)
{
mgr.FullName
= editor.FullName;
}
}
}

internal class frmNameEditor : System.Windows.Forms.Form
{
private TextBox txtName = new System.Windows.Forms.TextBox();
private
Button btnOk = new System.Windows.Forms.Button();

public string
FullName
{
get{return txtName.Text;}
set{txtName.Text = value;}
}

public frmNameEditor()
{
this.btnOk.Text = "Ok";
this
.btnOk.Click += new EventHandler(btnOk_Click);
this
.btnOk.Location = new Point(50, 50);
this
.Controls.AddRange(new Control[]{this.btnOk, this.txtName});
}

private void btnOk_Click(object sender, EventArgs e)
{
DialogResult
= DialogResult.OK;
}
}

internal class NameEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if(context != null)
{
return UITypeEditorEditStyle.Modal;
}
return base.GetEditStyle(context);
}

public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider,
object value)
{
if((context != null) && (provider != null))
{
IWindowsFormsEditorService editorService
=
provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;

if
(editorService != null)
{
frmNameEditor editor
= new frmNameEditor();
editor.FullName = value as string;

if
(editorService.ShowDialog(editor) == DialogResult.OK)
{
return editor.FullName;
}
}
}
return base.EditValue(context, provider, value);
}
}
}