You want the Click event handler for a button to run, but you want to initiate this action from code instead of waiting for the user to click the button.
Solution
Call the button’s PerformClick() method:
Button1.PerformClick()
Discussion
While it’s nice that the Buttoncontrol has aPerformClick()method to run itsClickevent handler in an object-oriented manner, most controls and most control events have no such related method. If you wish to call an event handler immediately through code, you have to call it like any other method, passing the correct arguments:
' ---- Call the text box control's GotFocus handler. TextBox1_GotFocus(TextBox1, New System.EventArgs)
In this case, calling theTextBox1control’sGotFocus()event handler will run that handler’s code, but it will not cause the focus to move to the text box. An even better solution would be to write a shared routine that theGotFocus()event handler and your other code both call.
You want to provide custom drawing code for a control.
Solution
Sample code folder: Chapter 04\ControlDrawing
For most controls, provide an event handler for thePaintevent, and add your drawing code there. This event’s second argument includes aGraphicsproperty representing the canvas on which you can issue your drawing commands. Some controls also provide separateDrawItem events that let you draw specific portions of the control, such as distinct items in aListBoxcontrol. You can also draw directly on the form’s surface. This recipe’s code includes samples for all these activities.
Create a new Windows Forms application, and add two controls: aButtoncontrol namedXButtonand aComboBoxcontrol namedColorList. Change theColorListcontrol’sDrawModeproperty toOwnerDrawFixedand itsDropDownStyleproperty toDropDownList. Then add the following source code to the form’s code template:
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load ' ----- Add some basic colors to the color list. ColorList.Items.Add("Red") ColorList.Items.Add("Orange") ColorList.Items.Add("Yellow") ColorList.Items.Add("Green") ColorList.Items.Add("Blue") ColorList.Items.Add("Indigo") ColorList.Items.Add("Violet") End Sub
Private Sub Form1_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles Me.Paint ' ----- Draw an ellipse on the form. e.Graphics.DrawEllipse(Pens.Black, 10, 10, _ Me.ClientRectangle.Width - 20, _ Me.ClientRectangle.Height - 20) End Sub
Private Sub XButton_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles XButton.Paint ' ----- Draw a big x in a rectangle on the button surface. Dim usePen As Pen
' ----- Provide a neutral background. e.Graphics.Clear(SystemColors.Control)
' ----- Draw the outline box. usePen = New Pen(SystemColors.ControlText, 3) e.Graphics.DrawRectangle(usePen, XButton.ClientRectangle)
' ----- Draw the x. e.Graphics.DrawLine(usePen, 0, 0, _ XButton.Width, XButton.Height) e.Graphics.DrawLine(usePen, 0, _ XButton.Height, XButton.Width, 0) usePen.Dispose() End Sub
Private Sub ColorList_DrawItem(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DrawItemEventArgs) _ Handles ColorList.DrawItem ' ----- Draw the color instead of the text. Dim useBrush As Brush ' ----- Check for a nonselected item. If (e.Index = -1) Then Return
' ----- Set the neutral background. e.DrawBackground()
' ----- Fill in the color. useBrush = New SolidBrush(Color.FromName(CStr( _ ColorList.Items(e.Index)))) e.Graphics.FillRectangle(useBrush, _ e.Bounds.Left + 2, e.Bounds.Top + 2, _ e.Bounds.Width - 4, e.Bounds.Height - 4) useBrush.Dispose()
' ----- Surround the color with a black rectangle. e.Graphics.DrawRectangle(Pens.Black, _ e.Bounds.Left + 2, e.Bounds.Top + 2, _ e.Bounds.Width - 4, e.Bounds.Height - 4)
' ----- Show the item selected if needed. e.DrawFocusRectangle() End Sub
Private Sub XButton_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles XButton.Click MsgBox("Button clicked.") End Sub
Run the program. TheXButton control no longer looks like a button; it instead looks like a custom-drawn “X.” Although the button looks strange, it still works. The ellipse we drew directly on the form’s surface is there. Also, theComboBox control now displays actual colors instead of just the names of colors. This all appears in Figure 4-4.
Figure 4-4. Controls drawn with custom code
Discussion
Some of the controls that support item-level drawing, such as the ListBox andComboBoxcontrols, include ane.Stateproperty in the data passed to the event handler. This value indicates the current state of the item being drawn: selected, not selected, or a half dozen other relevant states. You do not need to take that property into account if your implementation doesn’t require it, but it is generally a good idea to provide feedback to the user in a way the user expects. Adjusting the display based on this property helps achieve that purpose.
As shown in the sample code, theDrawItemevent handler includese.DrawBackground()ande.DrawFocusRectangle()methods that help you properly draw the item. Availability of these methods varies by control type.
See Also
See the recipes in Chapter 9 for examples that use the various GDI+ drawing commands.
You want a specific form to appear on top of all other forms in your application, no matter which form is selected.
Solution
If you wish to have a Toolbox-type form that is accessible at the same time as other forms but always remains on top, set the form’s TopMost property to True.
Discussion
If you also want to disable access to all other forms, open the important form of the moment using its ShowDialog() method:
Form1.ShowDialog()
No other forms already displayed by the application will be available until theShowDialog()form closes.
On a form, you want to have the Enter key trigger a specific button (such as an “OK” button) and have the Escape key trigger another button (such as a “Cancel” button).
Solution
Use the form’s AcceptButton andCancelButtonproperties to assign the appropriate buttons. In the Visual Studio Form Designer, setting these form properties to the names of buttons on the form will enable the keyboard shortcuts for those buttons.
Discussion
Setting a button to be a form’s CancelButton object has the side effect of changing that button’sDialogResultproperty toCancel.
Even if you set an accept button, the Enter key doesn’t always trigger it. For instance, if another button on the form has the focus, that button, and not the form’s accept button, is triggered when the user presses the Enter key.
Please check back next week for the continuation of this article.