Flylib.com

Books Software

 
 
 

Enhancing Controls Through Owner Draw


Enhancing Controls Through Owner Draw

There are a lot more drawing features included in .NET, but what we've seen here should be enough to whet your appetite. You can do a lot of fancy drawing with GDI+, but let's face it: You and I are programmers, not artists. If we were artists , we'd be raking in six figures using a floor mop to draw traditional abstract cubist Italian landscapes with Bauhausian accents.

Fortunately, there are practical semi-artistic things you can do with GDI+. One important drawing feature is owner draw, a sharing of drawing responsibilities between a control and you, the programmer. (You are the "owner.") The ComboBox control supports owner drawing of the individual items in the drop-down portion of the list. Let's create a ComboBox control that displays color names , including a small sample of the color to the left of the name . Create a new Windows Forms application, and add a ComboBox control named ComboBox1 to Form1 . Make these changes to ComboBox1 .

  • Change its DropDownStyle property to DropDownList .

  • Change its DrawMode property to OwnerDrawFixed .

  • Alter its Items property, adding multiple color names as distinct text lines in the String Collection Editor window. I added Red, Green, and Blue.

Now, add the following code to the source code area of Form1 's class.

Private Sub ComboBox1_DrawItem(ByVal sender As Object, _
      ByVal e As System.Windows.Forms.DrawItemEventArgs) _
      Handles ComboBox1.DrawItem
   ' ----- Ignore the unselelected state.
   If (e.Index = -1) Then Return

   ' ----- Create a brush for the display color, based on
   '   the name of the item.
   Dim colorBrush As New SolidBrush(Color.FromName( _
      CStr(ComboBox1.Items(e.Index))))

   ' ----- Create a text brush. The color varies based on
   '       whether this item is selected or not.
   Dim textBrush As Brush
   If ((e.State And DrawItemState.Selected) = _
         DrawItemState.Selected) Or _
         ((e.State And DrawItemState.HotLight) = _
         DrawItemState.HotLight) Then
      textBrush = New SolidBrush(SystemColors.HighlightText)
   Else
      textBrush = New SolidBrush(SystemColors.ControlText)
   End If

   ' ----- Get the shape of the color display area.
   Dim colorBox As New Rectangle(e.Bounds.Left + 4, _
      e.Bounds.Top + 2, (e.Bounds.Height - 4) * 2, _
      e.Bounds.Height - 4)

   ' ----- Draw the selected or unselected background.
   e.DrawBackground()

   ' ----- Draw the custom color area.
   e.Graphics.FillRectangle(colorBrush, colorBox)
   e.Graphics.DrawRectangle(Pens.Black, colorBox)

   ' ----- Draw the name of the color to the right of
   '       the color.
   e.Graphics.DrawString(CStr(ComboBox1.Items(e.Index)), _
      ComboBox1.Font, textBrush, 8 + colorBox.Width, _
      e.Bounds.Top + ((e.Bounds.Height - _
      ComboBox1.Font.Height) / 2))

   ' ----- Draw a selected rectangle around the item,
   '       if needed.
   e.DrawFocusRectangle()

   ' ----- Clean up.
   textBrush.Dispose()
   colorBrush.Dispose()
End Sub


Run the code and play with the combo box, as shown in Figure 17-14.

Figure 17-14. Our custom color combo box




Enhancing Classes with Attributes

Class-modifying attributes are something we discussed way back in Chapter 1, "Introducing .NET," and they have nothing to do with GDI+. I just wanted to refresh your memory, because they will be used in this chapter's project code.

Class- or member-modifying attributes appear just before the definition of the class or member, and within angle brackets. This code attaches the ObsoleteAttribute attribute to the SomeOldClass class.

<ObsoleteAttribute> _
Class SomeOldClass
   ...class details here...
End Class


(You can leave the "Attribute" part of an attribute's name off if the first part of the name doesn't conflict with any Visual Basic keyword.) Attributes appear as metadata in the final compiled assembly, and they are used by classes and applications that, by design, extract meaning from specific attributes. In this chapter's code, we'll make use of the PropertyGrid control, the control that implements the Properties panel within the Visual Studio development environment, and is often used to modify Form and Control properties. This control is available for your use in your own applications. To use it, assign a class instance to the control's SelectedObject property. Then, magically, all of the object's properties appear in the controls list of properties.

Nice as this is, it's not always desirable. Your object may have properties that should not be displayed. The PropertyGrid control is designed to be generic; it doesn't know about your object's needs, so it doesn't know which properties to exclude. That is, it doesn't know until you tell it through attributes. By adding specific attributes to your class's properties, you tell the PropertyGrid control how to treat members of your object. For instance, the BrowsableAttribute attribute tells the PropertyGrid to include ( True ) or exclude ( False ) the property.

<Browsable(False)> _
Public Property SecretProperty() As String...


I'll supply additional details about this when we use the PropertyGrid control later in this chapter.