For controls such as ComboBox, we can draw them by setting their DrawMode feature (Attribute).
For the sake of convenience, let's define a class StringColorObject (this does not have the relationship with OwnerDraw itself, just a class written in the COMBOBOX to use. The class is named after this class itself is very simple:
Using system.drawing;
Namespace OwnerDrawSample
{
Public Class StringColorObject
{
// Field to hold the string representing the color
PRIVATE STRING ColorRepresent;
// Field to hold the actual color, The value of the string colorrepresent
Private color color;
// THE Constructor
// Takes 2 Parameters, The Color Reperesentation and The Color Itself
Public StringColorObject (String ColorRepresent, Color Color)
{
THIS.COLORREPRESENT = ColorRepresent;
THIS.COLOR = Color;
}
// Some Attributes
Public String ColorRepresentation
{
get
{
Return this.colorrepresent;
}
// ONLY GETTER, NO SETTER
}
Public Color Color
{
get
{
Return this.color;
}
// ONLY GETTER, NO SETTER
}
// Override the Tostring Method in System.Object
Public override string toString ()
{
Return this.colorrepresent;
}
// Override the gethashcode method
Public Override Int getHashcode ()
{
// Return The Key Field's Hash Code
Return this.color.gethashcode ();
}
// Override the equals method
Public Override Bool Equals (Object Obj)
{
IF (! (bj is stringcolorObject))
Return False;
Return this.color.equals ((StringColorObject) obj) .color);
}
}
}
Create a Windows Application and drag a ComboBox into the form from the toolbox and name it CMBCOLORS and add it in the Form's constructor:
//
// Todo: Add any constructor code after INITIALIZECOMPONENT call
//
This.fillcomboxcolor (this.cmbcolors);
This.cmbcolors.selectedIndex = 0;
Among them, FillComboxColor (ComboBox) is a custom function, which is used to populate the ComboBox object specified by the parameter. It is implemented as:
Private void FillcomboxColor (ComboBox CMB) {
CMB.Items.Addrange (new object [] {
New StringColorObject ("Black", Color.Black,
New StringColorObject ("Blue", Color.Blue, New StringColorObject ("Dark Red), Color.darkRed,
New StringColorObject ("Green", Color.green,
// ......
});
}
The above are just some of the actual work of the preparatory work, OwnerDraw now just beginning to ComboBox objects cmbColors of DrawMode set OwnerDrawFixed (or OwnerDrawVariable, here set OwnerDrawFixed mode) side note:.. DrawMode can take Normal, OwnerDrawFixed and three OwnerDrawVariable One. Where, the Normal mode indicates that the control is drawn by the operating system, and the size of the element is equal; the OwnerDrawFixed mode indicates that the control is drawn by manual, and the size of the element is equal; OwnerDrawVariable is the representation of the control, and the size of the elements can be not equal.
The core part of OwnerDraw is started below:
1) Write the MeasureItem event for the control
When you want to display one of ComboBox (iTeM) [即 是 Click the ComboBox drop button], this event will be evokeed first. It is used to measure the length, width information of the ITEM. E.g:
//Registration issue
THIS.CMBCOLOR.MEASUREITEM = New MeasureItem (this.cmbcolor_measureItem);
/ / Implement CMBCOLOR_MEASUREITEM --- Measurement of each Item of ComboBox
Private Void CMBColor_measureItem (Object Sender, System.Windows.Forms)
{
// Generally, it is necessary to set the itemHeight property and ItemWidth property of MeasureItemEventArgs object E.
ComboBox CMB = (ComboBox) Sender;
E.ItemHeight = cmb.ItemHeight; // Of course, you can write E.ItemHeight = 20;
// But for OwnerDrawFixed mode, this function seems to be more. (So for ComboBox)
// why ????????????? More work is essential.
}
2) Write the DrawItem event of the control
The drawing tasks of the items in ComboBox will be completed in the DrawItem event. Similarly, first register the event, then add the appropriate code to complete the response to the event:
//Registration issue
this.cmbcolor.drawItem = New
DrawiteMeventHandler (this.cmbcolor_drawite);
// Draw Item
Private void CMBColor_DrawItem (Object Sender, System.Windows.Forms.DrawiteMeventArgs E)
{
ComboBox CMB = (ComboBox) Sender;
IF (cMB == null) return;
INT index = E.index; // Get the Item of Item to be drawn (index)
IF (index == -1) return;
// If Item is selected, draw the correct background color
E. DrawBackground ();
e.drawfocusRectangle (); // Because Item is selected, draw a focus rectangle
Graphics g = E.Graphics;
/ / Get the corresponding color according to the Item index
Color C = (StringColorObject) cmbcolor.items [index]). Color; Rectangle RectColor = E.Bounds; // Get the border surrounded by Item and store it in RectColor
// Take RectColor to make appropriate transformations, which will not affect the E.Bounds itself
RectColor.offset (2, 2); // Right shift 2, drop 2
RectColor.width = 20; // Width set to 20
RectColor.Height - = 4; // High degree of minus 4
g.drawRectangle (New Pen (C), RectColor); // Draw the rectangle represented by RectColor, ie the rectangular portion of the left side of the Item seen in the figure
// Do RECTCOLOR again, and fill it
RectColor.Offset (2, 2);
RectColor.width = 17; // Be careful, draw and fill in C #
RectColor.Height - = 3; // Different processing methods for the last pixel point
G.FillRectangle (New Solidbrush (C), RectColor); // Pack RectColor Rectangle, this rectangle is the filled rectangle on the left of the Item seen in the figure.
g.drawstring (StringColorObject) cmbcolor.items [index]). Tostring (),
THIS.FONT, New Solidbrush (C), E.BOUNDS.LEFT 25, E.BOUNDS.TOP);
// Draw a string
}
This program will run very well. In order to read the program, you have to know some of the following concepts:
1). The Index property expression of the E.Index MeasureItemGS object means that Item's index value is desired. For the example, black (Black), Blue ... respectively corresponds to index 0,1 ... (This statement is not very strict, but it is easy to accept. The strict statement is that the StringColorObject object corresponds to index ...).
2). E.Graphics This is a Graphics object to be drawn on Item. With it, you can implement graphical drawings on Item.
3). E.Bounds This is the boundary rectangle of Items to be drawn.
I know these concepts, it is not difficult to understand the operations completed above and why do you have done it.
For MenuItem's manual drawing, what you have to do is almost the same. Different, you need to set its OwnerDraw from the default false to True. Then MeasureItem, DrawItem. If you practice, you will find if you don't register MeasureItem and supplemented by the corresponding code, you won't see the MenuItem.
--- The end