Creating a Windows Control Designer

When you modify control properties for visual controls, the control is generally updated immediately and you have an idea of the effect of your changes. However, what do you do if you want to experiment with several potentially complex changes or your changes will be evident only when code runs? You create a designer—that's what you do.

The .NET Framework introduces the IDesigner interface. From this interface a generic ComponentDesigner class was defined, and from the ComponentDesigner class a ControlDesigner class was defined. Basically, a designer is a class that allows you to associate a verb and behavior with a component or control. A verb (an action that will be displayed as a context menu item) is represented as text associated with an event handler you define. The Visual Studio .NET IDE knows how to read verbs from the IDesigner interface, display the verbs, and invoke the related event handler when the verb (context menu item) is clicked. Of course, once you hit the event handler, you are running code and the sky is the limit.

To demonstrate, I added a RegexDesigner to CustomControls.vbproj. The RegexDesigner provides us with a facility for testing a regular expression in the IDE, using the designer, without needing to compile and run the code using the RegexTextBox. The IDE tests the regular expression first, saving a compile and test cycle. In a big application a designer like the RegexDesigner can save a lot of time. Listing 9.18 provides the source code for the RegexDesigner.

Listing 9.18. Implementing a ControlDesigner Class with Two Verbs
1:  Imports System.Windows.Forms
2:  Imports System.Windows.Forms.Design
3:  Imports System.ComponentModel.Design
4:
5:  Public Class RegexDesigner
6:    Inherits ControlDesigner
7:
8:    Public Overrides ReadOnly Property Verbs() _
9:      As DesignerVerbCollection
10:   Get
11:     Return New DesignerVerbCollection( _
12:       New DesignerVerb() { _
13:         New DesignerVerb("About", _
14:           AddressOf AboutHandler), _
15:         New DesignerVerb("Test Expression", _
16:           AddressOf TestExpressionHandler)})
17:   End Get
18:   End Property
19:
20:   Private Sub AboutHandler(ByVal sender As Object, _
21:     ByVal e As System.EventArgs)
22:
23:     Dim About As String = _
24:       "Regex ControlDesigner" & vbCrLf & _
25:       "Copyright " & Chr(169) & " 2002. " & _
26:       "All Rights Reserved." & vbCrLf & _
27:       "By Paul Kimmel. [email protected]"
28:
29:     MessageBox.Show(About, "About", _
30:       MessageBoxButtons.OK, MessageBoxIcon.Information)
31:
32:   End Sub
33:
34:   Private ReadOnly Property TextBox() As RegexTextBox
35:   Get
36:     Return CType(Me.Control, RegexTextBox)
37:   End Get
38:   End Property
39:
40:   Private Property Pattern() As String
41:   Get
42:     Return TextBox.Pattern
43:   End Get
44:   Set(ByVal Value As String)
45:     TextBox.Pattern = Value
46:   End Set
47:   End Property
48:
49:   Private Property InputString() As String
50:   Get
51:     Return TextBox.Text
52:   End Get
53:   Set(ByVal Value As String)
54:     TextBox.Text = Value
55:   End Set
56:   End Property
57:
58:   Private Sub TestExpressionHandler( _
59:     ByVal sender As Object, _
60:     ByVal e As System.EventArgs)
61:
62:     Dim APattern As String = Pattern
63:
64:     If (FormRegexTester.ShowDialog( _
65:       APattern, InputString)) Then
66:       Pattern = APattern
67:     End If
68:
69:   End Sub
70:
71: End Class

Because the ControlDesigner class does a lot of the leg work of implementing the basic behaviors of IDesigner, we need to implement only the read-only Verbs property. Verbs returns a DesignerVerbCollection, which contains a DesignerVerb for each context menu item you want to support (lines 8 through 18). The Verbs property in Listing 9.18 defines two verbs: About and Test Expression. When the About context menu item is clicked, the AboutHandler is invoked by the IDE; when the Test Expression context menu item is clicked, the TestExpressionHandler is called. Thus when About is clicked in the IDE—we'll talk about associating the designer in a moment—a simple About dialog (as defined by lines 20 through 32) is displayed, and when Test Expression is clicked, the code in lines 58 through 69 is run.

TestExpressionHandler displays a custom dialog that facilitates testing the Pattern property of the RegexTextBox at design time. FormRegexTester is a custom dialog form I created with two input fields. One input field (APattern) represents the regular expressions and the second (InputString) represents a test input string (Figure 9.12). Enter values into each field and click the Test button. If the input string matches the regular expression pattern, the text in the status bar is updated to reflect a valid pattern-input string pair. Click OK to store the changes back into the component, or click Cancel to dump the changes.

Figure 9.12. The regular expression test form for the RegexDesigner.


Applying the Designer to the Control

The ControlDesigner and ComponentDesigner classes provide you with an easy-to-implement advanced way to visually design a control or component. In our example we implemented a regular expression tester. To associate this tester with a specific control, add the DesignerAttribute to the control class. The application of the DesignerAttribute is shown in Listing 9.19, a modification of an excerpt from Listing 9.3.

Listing 9.19. Using the DesignerAttribute to Associate a Control Designer with a Control
Imports System.ComponentModel
Imports System.Text.RegularExpressions
Imports System.Windows.Forms
Imports System.Drawing

<Designer(GetType(RegexDesigner))> _
Public Class RegexTextBox
  Inherits TextBox

  Private FPattern As String
. . .

After we compile and add our control along with the designer to the Toolbox, we should see the new verbs displayed in every instance of the control's context menu.

Testing the Control Designer

In order to test a control designer we need to associate it with the control and add the bunch to the Toolbox. Drag and drop an instance of the control to a form and right-click on the control. If everything is working correctly, you will see the verbs reflected as context menu items (Figure 9.13). Click any verb to invoke that operation. For example, to display the regular expression test dialog shown in Figure 9.12, click the Test Expression context menu item shown in Figure 9.13.

Figure 9.13. The About and Test Expression verbs reflected in an instance of the RegexTextBox's control designer, RegexDesigner.


You have the option of implementing an IDesigner interface from scratch. However, it is easier to inherit from the ComponentDesigner or ControlDesigner classes as a way to save yourself some labor. It is worth noting that the ControlDesigner classes for Windows Forms and Web Pages are a bit different, branching at HtmlControlDesigner for Web Pages. With a bit of experimentation you shouldn't find it too difficult to make a ControlDesigner class for Web Controls.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.25.112