Home arrow C# arrow Page 4 - Custom Controls and Design-Time Support: Part 2/2
C#

Custom Controls and Design-Time Support: Part 2/2


Creating custom controls is a key technique in .NET development. This article by Matthew is the second of a two part series where he looks at how to create a custom Windows Form control that behaves properly in Visual Studio .NET.

Author Info:
By: Wrox Team
Rating: 4 stars4 stars4 stars4 stars4 stars / 25
January 13, 2003
TABLE OF CONTENTS:
  1. · Custom Controls and Design-Time Support: Part 2/2
  2. · The DirectoryTree
  3. · Filtering Control Class Members
  4. · Designer Verbs
  5. · UITypeEditors
  6. · Custom UITypeEditors
  7. · Conclusion

print this article
SEARCH DEVARTICLES

Custom Controls and Design-Time Support: Part 2/2 - Designer Verbs
(Page 4 of 7 )

You can also use a custom designer to add to the context menu that's displayed when a programmer right-clicks on your control in the design environment. This menu contains some standard options provided by Visual Studio .NET, but it can also contain your own commands (technically known as verbs).

To add your own verbs, you need to override the Verbs property, create a new DesignerVerbCollection, and add the appropriate DesignerVerb object entries. Your control designer handles the verb, generally by updating the associated control.

The following example retrieves a list of all the drives on the current computer, and adds a context menu entry for each one. The user can click on the appropriate entry to set the Drive property of the control.

public class DirectoryTreeDesigner : ControlDesigner
{

protected override void PostFilterProperties(
System.Collections.IDictionary properties)
{
properties.Remove("Nodes");
}

DesignerVerbCollection verbs = new DesignerVerbCollection();

public DirectoryTreeDesigner()
{
// Configure the designer verb collection.
string[] drives = System.IO.Directory.GetLogicalDrives();

foreach (string drive in drives)
{
verbs.Add(new DesignerVerb("Set Drive " + drive,
new EventHandler(OnVerb)));
}
}

public override DesignerVerbCollection Verbs
{
get
{ return verbs; }
}

protected void OnVerb(object sender, EventArgs e)
{
// Retrieve the selected drive.
char driveLetter = ((DesignerVerb)sender).Text[10];

// Adjust the associated control.
((DirectoryTree)this.Control).Drive = driveLetter;
}

}


Generally you won't use your designer verbs to provide settings for a property. A more interesting technique is to provide higher-level configuration operations that adjust several properties at once.

One example of this is found in the ASP.NET Calendar control, which allows the user to choose a theme from a list of preset choices. When a theme is selected, several properties are modified in conjunction.

The implementation for this design is refreshing easy. Just add a Windows form to your project, and display it when the appropriate designer verb is selected. Here's another simple example using the DirectoryTree. This time, only a single verb is available, which then displays a window that allows the user to choose a drive.

When a drive is chosen, a public form-level variable is set, and then retrieved by the designer, which applies the change. This approach is more manageable than the previous design, and doesn't clutter the context menu with drive letters:

public class DirectoryTreeDesigner : ControlDesigner
{

protected override void PostFilterProperties(
System.Collections.IDictionary properties)

{
properties.Remove("Nodes");
}

DesignerVerbCollection verbs = new DesignerVerbCollection();

public DirectoryTreeDesigner()
{
// Configure the designer verb collection.
verbs.Add(new DesignerVerb("Set Drive",
new EventHandler(OnVerb)));
}

public override DesignerVerbCollection Verbs
{
get
{ return verbs; }
}
protected void OnVerb(object sender, EventArgs e)
{
// Show the form.
SelectDrive frm = new SelectDrive();
frm.DriveSelection = ((DirectoryTree)this.Control).Drive;
frm.ShowDialog();

// Adjust the associated control.
((DirectoryTree)this.Control).Drive = frm.DriveSelection;
}

}


The SelectDrive form is quite simple:

public class SelectDrive : System.Windows.Forms.Form
{
private System.Windows.Forms.Button cmdClose;
private System.Windows.Forms.ListBox lstDrives;

private void cmdClose_Click(object sender, System.EventArgs e)
{
this.Close();
}

public char DriveSelection;

private void listDrives_SelectedIndexChanged(object sender,
System.EventArgs e)
{
DriveSelection = lstDrives.Text[0];
}

private void SelectDrive_Load(object sender, System.EventArgs e)
{
string[] drives = System.IO.Directory.GetLogicalDrives();
lstDrives.DataSource = drives;

// Select the current drive.
lstDrives.SelectedIndex =
lstDrives.FindString(DriveSelection.ToString());

// Attach the event handler.
// This step is performed after the selected index is set,
// to prevent it from being overwritten as the list is built.
this.lstDrives.SelectedIndexChanged += new
System.EventHandler(this.listBox1_SelectedIndexChanged);

}

}


One quirk remains in the designer that we've built. When the DirectoryTree.Drive property is modified by the designer, the Properties window is not updated until the control is deselected and then reselected.

To correct this defect, you need to explicitly notify the IDE that a change has been made.
The rewritten OnVerb() method handles this:

// Notify the IDE that the Drive property has changed.
PropertyDescriptorCollection properties;
properties = TypeDescriptor.GetProperties(typeof(DirectoryTree));
PropertyDescriptor changedProperty = properties.Find("Drive", false);
this.RaiseComponentChanged(changedProperty, "", frm.DriveSelection);


When you add a form to a control project in this way, the client will be able to see the form class, and even create and display instances of it. If this isn't the behavior you want, you will need to nest your form class inside your control class and make it private or protected.

Unfortunately, if you do this, you have to forego Visual Studio .NET's design-time support, and manually copy the form code into the class.
blog comments powered by Disqus
C# ARTICLES

- Introduction to Objects and Classes in C#, P...
- Visual C#.NET, Part 1: Introduction to Progr...
- C# - An Introduction
- Hotmail Exposed: Access Hotmail using C#
- Razor Sharp C#
- Introduction to Objects and Classes in C#
- Making Your Code CLS Compliant
- Programming with MySQL and .NET Technologies
- Socket Programming in C# - Part II
- Socket Programming in C# - Part I
- Creational Patterns in C#
- Type Conversions
- Creating Custom Delegates and Events in C#
- Inheritance and Polymorphism
- Understanding Properties in C#

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials