1. Trang chủ
  2. » Công Nghệ Thông Tin

Visual Basic 2005 Design and Development - Chapter 11 ppsx

32 232 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 32
Dung lượng 777,1 KB

Nội dung

Property Support Visual Studio developers take the Properties window for granted, but it’s actually a pretty remark- able tool. When you click a control on a form, the window displays the control’s properties and lets you edit them in ways that are appropriate for the different property data types. It lets you enter text for properties that are strings or simple values such as numbers, it lets you select files and colors from dialogs, and it lets you pick choices from a drop-down list for enumerated values. If a property is a collection of objects, you can click an ellipsis to the right of the property to open a collection editor where you can add and remove objects, and edit their properties. When you build a custom control, you get all of this functionality for free. In many cases, this default behavior is more than enough to let developers use your controls. In fact, if you are developing controls for in-house use, I would recommend that you try to live with the capabilities provided by the Properties window for you. Additional features (such as cus- tom property editors) make developing with controls easier, but they are fairly tricky to imple- ment. Unless you will be spending a lot of time working with the properties, it may not be worth the additional effort of writing customized tools. In contrast, if you are building controls that will be used by developers outside of your project, it may be worthwhile providing some of these extra capabilities. You may also need to build some of these tools if your controls’ properties will be directly accessible to end users. For example, the PropertyGrid control lets users view and modify object properties at run-time. If you use that control, you may need to streamline your properties so that they are easier for the users to under- stand and manage. Unfortunately, controls (and code, in general) often live far longer than was originally intended. The control that you plan to use only once may be adopted by other projects, and you may end up supporting it practically forever. To avoid unwelcome work, you should make your controls (and all of your code) as bulletproof as possible, but you can still avoid adding gratuitous extras. Make the control’s property procedures validate their data so developers cannot push bad data into the control. You don’t necessarily need to give every property fancy property editors until you’re cer- tain there’s a need for them. 16_053416 ch11.qxd 1/2/07 6:33 PM Page 297 This chapter describes some of the ways you can add design-time support for custom controls and their properties. It shows how to add drop-down and dialog editors to the Properties window, how to add smart tags to a control, and how to build property sheets. Some of the attributes, interfaces, and classes used by the examples in this chapter require that you add a reference to System.Design and System.Windows.Forms.Design namespaces. Double-click My Project, select the References tab, and check the namespaces in the list. If one of the namespaces (probably System.Design) is missing from the list, click the Add button and select the namespace there. Customizations Overview This chapter describes several ways that you can enhance Visual Basic’s design time for custom controls. To demonstrate most of these enhancements, this chapter uses an example control named ScribbleControl. This control displays a hand-drawn image. At design time, you can both see and edit the image. At run- time, the user can view the image. If the control’s Enabled property is True, the user can also edit the image at run-time. Figure 11-1 shows the control at design time displaying an image. Figure 11-1: The ScribbleControl displays a hand-drawn image at design time and run-time. This control represents its drawing as a series of polylines, where a polyline is a series of connected points. The control’s PolyPolyline property contains a reference to a PolyPolyline object. That object contains an array of Polyline objects, each of which contains an array of Points. Each of these classes has support methods that perform such tasks as drawing a Polyline or PolyPolyline. 298 Part II: Meta-Development 16_053416 ch11.qxd 1/2/07 6:33 PM Page 298 Figure 11-1 shows several enhancements to Visual Basic’s design-time support for the ScribbleControl class. Because the PolyPolyline property is an array of objects, the Properties window would normally display a collection editor to allow the developer to add, remove, and modify Polyline objects. That’s not a very useful way to specify a drawing, however, so the control overrides this behavior. If you click the ellipsis shown on the right of the PolyPolyline property in Figure 11-1, Visual Basic displays the editor dialog shown in Figure 11-2. On this editor, you can click the left mouse button and drag to draw new polylines. If you click the right mouse button, the editor clears the picture. When you are finished, you can click OK to save the new PolyPolyline property, or Cancel to leave the control’s PolyPolyline property unchanged. Figure 11-2: You can edit a ScribbleControl’s picture at design time. Notice also that the Properties window displays a tiny image of the drawing in the PolyPolyline property’s entry. The ScribbleControl provides several other custom properties. The LineColor property determines the color that the control uses to draw its polylines. In this control, however, LineColor isn’t just any old color. Instead, it must be one of red, orange, yellow, green, blue, indigo, violet, black, or white. You can see in Figure 11-1 that the LineColor entry in the Properties window displays the name of the currently selected color. If you select that property, the window displays a drop-down arrow on the right as it normally would for a color property. If you click this arrow, however, you don’t see a normal color selection dialog. Instead, you see the color selection drop-down shown in Figure 11-3. The LineWidth property determines the thickness of the lines that the control draws. The Properties window displays LineWidth by showing a sample of the line and the line’s width in pixels. Like the LineColor property, LineWidth displays a custom drop-down when you click its drop-down arrow. Figure 11-4 shows the LineWidth drop-down. 299 Chapter 11: Property Support 16_053416 ch11.qxd 1/2/07 6:33 PM Page 299 Figure 11-3: The LineColor property displays a custom selection drop-down. Figure 11-4: The LineWidth property displays a custom selection drop-down. Below the properties in the Properties window in Figure 11-1, you can see a link labeled “Draw Spiral.” This is a command verb supported by the ScribbleControl class. If you click this link, the control clears its picture and draws a spiral. More generally, a command verb can take any action that is appropri- ate to configure or modify the control. While the entries in the Properties window affect only a single property, these verbs can perform any action on the control. 300 Part II: Meta-Development 16_053416 ch11.qxd 1/2/07 6:33 PM Page 300 The ScribbleControl in the form designer is selected in Figure 11-1. If you look closely near the control’s upper-right corner, you’ll see a small box holding a little rightward-pointing triangle. This is called a smart tag. If you click a smart tag, a panel of actions pops up that lets you configure the associ- ated control. If you click the smart tag for the ScribbleControl, you’ll see the smart tag panel shown in Figure 11-5. Controls on this panel let you set the ScribbleControl’s BackColor, LineColor, and LineWidth properties. Figure 11-5: The ScribbleControl’s smart tag lets you configure the control. The smart tag’s Draw Star command clears the control’s picture and draws a star. Figure 11-6 shows the control after clicking this command. Figure 11-6: The Draw Star command draws a star. The Draw Spiral command clears the control’s picture and draws the spiral shown in Figure 11-7. The Draw Spiral command is the same command displayed as a link below the properties in the Properties window. The bottom of the smart tag’s panel contains an Information area that displays the number of Polylines in the current drawing. In Figure 11-5, this area shows that the shark drawing contains 14 Polylines. 301 Chapter 11: Property Support 16_053416 ch11.qxd 1/2/07 6:33 PM Page 301 Figure 11-7: The Draw Spiral command draws a spiral. Finally, the ScribbleControl also provides property pages. These have gone somewhat out of fashion since Visual Basic .NET was released, but they are still useful for manipulating a control in very complex ways. Like the smart tag panel, property sheets let you change all of the control’s properties in one place. They can also provide more complex commands such as the Draw Star and Draw Spiral tools. While the smart tag pop-up must display all of its tools at once, property sheets can include many pages. In some very complex controls (such as graphing and charting controls), property sheets may contain pages to set basic properties (colors, line types, point symbols), chart style (line graph, bar graph, pie chart), data, axis labels, and so forth. If you right-click the ScribbleControl and select Properties, Visual Basic displays the property sheets shown in Figure 11-8. (Normally, right-clicking and selecting Properties displays the Properties window. But if the control has property pages, Visual Basic displays those instead.) You can also display the prop- erty sheets by clicking the property pages button at the top of the Properties window. You can see this button in Figure 11-4 to the right of the lightning bolt button that displays the control’s Events. Figure 11-8: Property sheets let you manipulate a control in complex ways. The column on the left shows icons and names for the pages contained by the property sheet. The rest of the dialog contains controls that manipulate the control you right-clicked in the form designer. Figure 11-8 shows the first property page, which lets you set the control’s basic properties. 302 Part II: Meta-Development 16_053416 ch11.qxd 1/2/07 6:33 PM Page 302 If you click the Drawing item in the left-hand column, you’ll see the second property page shown in Figure 11-9. This page lets you use the mouse to draw a new picture. Figure 11-9: This property sheet lets you draw pictures with the mouse. When you make a change to any of the controls on the property pages, the Apply button is enabled. If you click Apply, the property sheet applies all of the changes to the ScribbleControl that you origi- nally right-clicked in the form designer. If you click OK, the dialog applies the changes and closes. If you click Cancel, the dialog closes and leaves the ScribbleControl unchanged. The following sections explain in detail how to implement each of these design-time features. This control contains a lot of code for performing such chores as adding Polyline objects to the control’s PolyPolyline property, adding points to a Polyline, and drawing the control’s image. This code isn’t central to creating the design-time customizations, so most of this code has been omitted to save space. Download the example project from www.vb-helper.com/one_on_one.htm to see the details. Important Note: When you build the editors and other classes that provide the design-time support, some of them seem to get cached or linked tightly to Visual Studio. If you make a change to the editor class and recompile, Visual Studio may continue using the old version. To make Visual Studio relinquish its hold on the older editor, save your changes, close Visual Studio, delete the project’s bin and obj directories, restart Visual Basic, and rebuild the application. Note also that Visual Studio sometimes gets confused if you load a form containing a control that you have modified. For example, suppose you save a form containing a ScribbleControl, close the form, and then remove the control’s LineWidth property. When you reopen the form, the form designer tries to reload the control’s properties from the form’s resources. Unfortunately, those resources include a LineWidth property, so the form designer will probably become confused. You may need to manually edit the resource file (which is just XML text) and remove the offending property. One way to avoid this problem is to not save forms containing the controls you are currently building. Open the application and then open a test form. Place a control on it and test the design-time features you are working on. Then close the form without saving changes. Modify the control as needed, and then, when you reopen the form, you can add a new control. The chapter finishes by discussing another common scenario: providing design-time support for proper- ties that are references to objects. It shows how you can allow developers to view and modify the object’s sub-properties. 303 Chapter 11: Property Support 16_053416 ch11.qxd 1/2/07 6:33 PM Page 303 Displaying and Editing LineWidth To display a property in a special format and to allow custom editing in the Properties window, you need to associate the property with a property editor class. For example, the following code shows how the ScribbleControl declares its LineWidth property: ‘ The thicknesses of the lines. Private m_LineWidth As Integer = 1 <EditorAttribute(GetType(LineWidthEditor), GetType(UITypeEditor))> _ Public Property LineWidth() As Integer Get Return m_LineWidth End Get Set(ByVal value As Integer) If value < 1 Then value = 1 If value > 10 Then value = 10 m_LineWidth = value Me.Invalidate() End Set End Property The EditorAttribute attribute indicates that the PolyPolylineEditor class provides support for editing the PolyPolyline property in the Properties window. It provides that support with the LineWidthEditor class. The LineWidthEditor class uses a LineWidthListBox object. The LineWidthEditor and Line WidthListBox classes are described in the following sections. (You can download these examples at www.vb-helper.com/one_on_one.htm.) LineWidthEditor The LineWidthEditor class performs two tasks. First, it lets the user edit a LineWidth property by selecting an item from a drop-down list. Second, it displays a sample line with the right thickness in the Properties window. Figure 11-4 shows both the editing drop-down and the sample line drawn in the Properties window. The following code shows the LineWidthEditor class perform these tasks: Imports System.Drawing.Design Public Class LineWidthEditor Inherits System.Drawing.Design.UITypeEditor ‘ Indicates that this editor displays a dropdown. Public Overloads Overrides Function GetEditStyle( _ ByVal context As System.ComponentModel.ITypeDescriptorContext) _ As System.Drawing.Design.UITypeEditorEditStyle Return UITypeEditorEditStyle.DropDown End Function ‘ Edit a line width. Public Overloads Overrides Function EditValue(_ 304 Part II: Meta-Development 16_053416 ch11.qxd 1/2/07 6:33 PM Page 304 ByVal context As System.ComponentModel.ITypeDescriptorContext, _ ByVal provider As System.IServiceProvider, ByVal value As Object) As Object ‘ Get an IWindowsFormsEditorService. Dim editor_service As IWindowsFormsEditorService = _ CType(provider.GetService(GetType(IWindowsFormsEditorService)), _ IWindowsFormsEditorService) ‘ If we failed to get the editor service, return the value. If editor_service Is Nothing Then Return value ‘ Convert the generic value into a line width value. Dim line_width As Integer = DirectCast(value, Integer) ‘ Make the editing control. Dim editor_control As New LineWidthListBox(line_width, editor_service) ‘ Display the editing control. editor_service.DropDownControl(editor_control) ‘ Save the new results. Return editor_control.SelectedIndex + 1 End Function ‘ Indicate that we draw a representation for the Properties window’s value. Public Overrides Function GetPaintValueSupported(_ ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean Return True End Function ‘ Draw a representation for the Properties window’s value. Public Overrides Sub PaintValue(_ ByVal e As System.Drawing.Design.PaintValueEventArgs) e.Graphics.FillRectangle(Brushes.White, e.Bounds) Dim line_width As Integer = DirectCast(e.Value, Integer) Dim y As Integer = e.Bounds.Y + e.Bounds.Height \ 2 Using line_pen As New Pen(Color.Black, line_width) e.Graphics.DrawLine(line_pen, _ e.Bounds.Left + 1, y, _ e.Bounds.Right - 1, y) End Using End Sub End Class LineWidthEditor inherits from the UITypeEditor class. That class provides basic support for the Properties window. The editor overrides its inherited GetEditStyle function to return UITypeEditorEditStyle.DropDown, indicating that the editor provides a drop-down property editor. The EditValue function actually does the editing. It casts the value it should edit into an Integer LineWidth value. It then makes a LineWidthListBox control (described in the following section) and uses an IWindowsFormsEditorService object to display the control. The function finishes by returning 305 Chapter 11: Property Support 16_053416 ch11.qxd 1/2/07 6:33 PM Page 305 the line width selected by the control. The Properties window sets the LineWidth property of the ScribbleControl it is editing to this value. The LineWidthEditor’s GetPaintValueSupported function returns True to indicate that the class can draw a special representation of the LineWidth property. Subroutine PaintValue does the drawing. It clears a rectangle inside the bounds where it should draw, and then draws a line with the appropriate thickness. See Figure 11-4 to see the result. Notice that the Properties window displays a textual representation of the LineWidth in addition to the sample line. LineWidthListBox To edit a LineWidth value, the LineWidthEditor class displays a LineWidthListBox control. This control should be a single control that the Properties window can display as a drop-down. The following code defines the LineWidthListBox control: Imports System.ComponentModel <ToolboxItem(False)> _ Public Class LineWidthListBox Inherits ListBox ‘ The editor service displaying us. Private m_EditorService As IWindowsFormsEditorService ‘ A margin around the image in the list box. Private Const ITEM_MARGIN As Integer = 2 Public Sub New(ByVal line_width As Integer, _ ByVal editor_service As IWindowsFormsEditorService) MyBase.New() m_EditorService = editor_service ‘ Give the list some items. For i As Integer = 0 To 9 Me.Items.Add(i) Next i Me.SelectedIndex = line_width - 1 Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed Me.ItemHeight = 16 + 2 * ITEM_MARGIN End Sub ‘ Close the dropdown. Private Sub LineWidthEditorDropdown_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Click If m_EditorService IsNot Nothing Then m_EditorService.CloseDropDown() End Sub ‘ Draw a menu item. Private Sub LineWidthEditorDropdown_DrawItem(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles Me.DrawItem 306 Part II: Meta-Development 16_053416 ch11.qxd 1/2/07 6:33 PM Page 306 [...]... name, position, size, and text 321 16_053416 ch11.qxd 1/2/07 6:33 PM Page 322 Part II: Meta -Development Rather than trying to design the form by hand using properties in this manner, you may want to make a new form and arrange the controls you need on it Then, open the designer-generated code, and copy and paste what you need into the class This section of code creates LineWidthListBox and LineColorListBox... object to show its sub-properties You would need to type in a valid string of the form “Rod, Stephens (98 7-6 543)” for that property At that point, Visual Studio would assign a new Contact object to the control’s property The Properties window would then allow you to expand the Contact property and see its sub-properties 327 16_053416 ch11.qxd 1/2/07 6:33 PM Page 328 Part II: Meta -Development To avoid... invoke the control’s methods, and do just about anything else that Visual Basic code can do to a control The previous chapter explained how to build custom controls and components This chapter explained how to add additional support for the properties of those controls and components It shows how to make type converters and property editors that let the Properties window display and edit values It explained... tag, you use the Designer attribute to associate the control with a designer The following code shows the Designer attribute that associates the ScribbleControl class with the ScribbleControlDesigner class You’ll see this Class statement with a bit more context later in this chapter _ Public Class ScribbleControl End Class The ScribbleControlDesigner class... “, “ & Zip End Function 323 16_053416 ch11.qxd 1/2/07 6:33 PM Page 324 Part II: Meta -Development Figure 1 1-1 3 shows the Properties window displaying the value returned by ToString Figure 1 1-1 3: The Properties window displays the result of an object’s ToString function This is better, but it’s still not perfect The value displayed for the property is grayed out and not editable The Properties window... ScribbleActionList(Me.Component)) End If Return lists End Get End Property End Class 313 16_053416 ch11.qxd 1/2/07 6:33 PM Page 314 Part II: Meta -Development ScribbleControlDesigner inherits from the ControlDesigner designer class and overrides its inherited ActionLists function This function returns a DesignerActionListCollection that contains a list of classes that represent the lists of actions that... controls to display and edit the properties just as the Properties window does Figure 1 1-1 0 shows the smart tag panel displaying its LineWidth editor Figure 1 1-1 0: The smart tag panel can use UITypeEditors, too The LineColor, BackColor, and LineWidth properties are relatively straightforward The DrawStar and DrawSpiral subroutines are almost as simple They each create a new PolyPolyline object and add points... object that has its own properties and methods To examine object properties such as these, this section uses a new example Figure 1 1-1 1 shows a form containing a UserControl named ContactViewer This control has two object properties: Contact and Address The Contact class has FirstName, LastName, and Phone properties The Address class provides Street, City, State, and Zip properties The ContactViewer... Street, City, State, and Zip properties The ContactViewer simply displays the values in those properties in its Label controls 322 16_053416 ch11.qxd 1/2/07 6:33 PM Page 323 Chapter 11: Property Support Figure 1 1-1 1: The ContactViewer UserControl has Contact and Address properties that are objects Left to its own devices, the Properties window displays an object reference property by using the value... string would represent the fish drawing?) To prevent confusion, the code overrides this behavior and displays a blank string in the Properties window Second, this property provides the modal dialog editor shown in Figure 1 1-2 instead of a drop-down editor 308 16_053416 ch11.qxd 1/2/07 6:33 PM Page 309 Chapter 11: Property Support The following code shows how the ScribbleControl defines its PolyPolyline . the image at run-time. Figure 1 1-1 shows the control at design time displaying an image. Figure 1 1-1 : The ScribbleControl displays a hand-drawn image at design time and run-time. This control. custom drop-down when you click its drop-down arrow. Figure 1 1-4 shows the LineWidth drop-down. 299 Chapter 11: Property Support 16_053416 ch11.qxd 1/2/07 6:33 PM Page 299 Figure 1 1-3 : The LineColor. Polyline or PolyPolyline. 298 Part II: Meta -Development 16_053416 ch11.qxd 1/2/07 6:33 PM Page 298 Figure 1 1-1 shows several enhancements to Visual Basic s design- time support for the ScribbleControl class.

Ngày đăng: 14/08/2014, 11:20