Windows Forms Programming in Visual Basic .NET
Unlike main and context menus , controls [8] dragged from the Toolbox onto the surface provided by the Designer are added to the form's Controls collection. You can use that collection yourself to add controls dynamically at run time (as we showed earlier in this chapter), or you can add arrays of controls the way the Designer-generated InitializeComponent does: [8] Technically speaking, both MainMenu and ContextMenu are components , as are all the rest of the items that you can drag and drop from the Toolbox that show up on the tray along the bottom of the design surface. For a list of the standard WinForms components, see Appendix D: Standard WinForms Components and Controls.
Sub InitializeComponent() Me.SuspendLayout() ' child control creation and initialization ... Me.Controls.AddRange( _ New System.Windows.Forms.Control() { _ Me.StatusBar1, _ Me.TextBox1}) Me.ResumeLayout(False) End Sub Notice the calls to SuspendLayout and ResumeLayout. SuspendLayout is an optimization to keep the form from updating itself visually until ResumeLayout is called. By bracketing several tasks ”the child control creation and initialization as well as the addition of the controls to the control collection ”in SuspendLayout and ResumeLayout, we don't have to worry about the form trying to draw itself until everything is set up. This is something that you can do if you need to make a nontrivial set of changes to the form's properties or controls yourself. Control Z-Order
In addition to Add and AddRange, you can remove controls from the form's collection using Remove and RemoveRange (another good place to use SuspendLayout and ResumeLayout). When the controls have been in the collection long enough to be drawn, the order in the collection establishes the z-order among the controls on the form. Figure 2.9 shows an example of a form with three buttons that have been added to the controls collection in z-order order:
Me.Controls.AddRange( _ New System.Windows.Forms.Control() { _ Me.zOrder0Button, _ Me.zOrder1Button, _ Me.zOrder2Button}) Figure 2.9. Z-Order and Tab Order
If you need to change the z-order at design time, you can right-click on a control and choose Bring To Front, which brings the control to z-order zero, or Send To Back, which sets the z-order to the last item in the collection. Similarly, you can move a control at run time using the Control.BringToFront and Control.SendToBack methods . Control Tab Order
Directing your attention again to Figure 2.9, notice the little numbers in the upper-left corner. Those numbers indicate the tab order of the controls on the form and are put there by the View Tab Order menu item in VS.NET. Tab order is the order in which the controls will receive focus as the user presses the Tab key. Tab order is exposed on each control by the TabIndex property. Also notice that tab order has no relation to z-order; our button with a z-order of 0 has a tab order of 2. Themed Controls
Modern versions of Windows (Windows XP and later) support controls that are drawn with a theme. A theme can be whatever the Windows shell team adds in the future, but one of the main aspects of a theme is that a user can adjust the way the basic controls are drawn. For example, when buttons aren't themed, they look like those in Figure 2.10. Figure 2.10. Unthemed Buttons in Windows XP
However, when the Windows XP theme is applied in the Display control panel, buttons (and other standard controls) take on a futuristic look, as shown in Figure 2.11. Figure 2.11. Themed Buttons in Windows XP
By default, a WinForms application always gets the Windows standard controls without themed rendering. Under version 1.0, enabling themed rendering required a .manifest file. [9] Enabling themed controls under WinForms v1.1 no longer requires a .manifest file. Instead, there's a method on the System.Windows.Forms.Application class that you call before showing any UI: [9] You can read about adding theme support to WinForms 1.0 applications in "Using Windows XP Themes with Windows Forms," http://www.gotdotnet.com/team/windowsforms/Themes.aspx.
Shared Sub Main() Application.EnableVisualStyles() Application.Run(New Form1()) End Sub The EnableVisualStyles method eliminates the need to add a .manifest file to your application, but that's not the whole job; you'll also need to set the FlatStyle on each control on your form from the default value of FlatStyle.Standard to FlatStyle.System. Figure 2.12 shows the difference when the application is running under Windows XP. Figure 2.12. WinForms FlatStyles
As a shortcut to setting the FlatStyle property on the subset of controls that support it (buttons, group boxes, and labels), you can consider a hunk of code such as the following [10] : [10] To be more thorough about getting controls and contained controls on a form, see the GetAllControls method in Chapter 3: Dialogs.
Public Sub New() ' Required for Windows Form Designer support InitializeComponent() ' Set the FlatStyle for all controls SetFlatStyleSystem(Me) End Sub Sub SetFlatStyleSystem(myparent As Control) Dim mycontrol As Control Dim mybuttonbase As ButtonBase Dim mygroupbox As GroupBox Dim mylabel As Label For Each mycontrol in myparent.Controls ' Only these controls have a FlatStyle property If TypeOf mycontrol Is ButtonBase Then mybuttonbase = CType(mycontrol, ButtonBase) mybuttonbase.FlatStyle = FlatStyle.System ElseIf TypeOf mycontrol Is GroupBox Then mygroupbox = CType(mycontrol, GroupBox) mygroupbox.FlatStyle = FlatStyle.System ElseIf TypeOf myctonrol Is Label Then mylabel = CType(mycontrol, Label) mylabel.FlatStyle = FlatStyle.System End If ' Set contained controls' FlatStyle too SetFlatStyleSystem(mycontrol) Next End Sub Only the standard Windows controls support a themed appearance by default. If you build your own custom controls that draw themselves , they'll have to handle their own themed rendering (how to build and draw custom controls is discussed in Chapter 8: Controls). Hosting COM Controls
As wonderful and varied as WinForms controls are, especially considering the burgeoning third-party WinForms control market, Component Object Model (COM) controls [11] have been around a lot longer, and you may still need to use some of them in your WinForms applications. WinForms provides built-in support for hosting COM controls, and VS.NET makes it easy to take advantage of that support. [11] COM controls are also known as OLE controls and ActiveX controls. The first step is to get your COM control of choice to show up on the Toolbox so that you can drag it onto your forms. To get a COM control to show up in the Toolbox, right-click on the Toolbox and choose Customize Toolbox, which will bring up the Customize Toolbox dialog, as shown in Figure 2.13. Figure 2.13. Customize Toolbox Dialog
All the items under the COM Components tab are COM controls registered on your machine. Checking any of them and pressing OK will add the control to the Toolbox, as shown in Figure 2.14. Figure 2.14. COM Component Added to the Toolbox
After a COM control has been added to the Toolbox, you can drop an instance onto a form, set the properties, and handle the events. Any COM control added to your WinForms project will cause a pair of interop assemblies to be generated by VS.NET [12] and added to the project. It's this code that you're referencing and that forwards your calls to the underlying COM control. [13] [12] The aximp.exe command line tool generates COM control interop assemblies in the same way that VS.NET does. [13] For more information about COM interop, see Essential .NET, Volume I: The Common Language Runtime (Addison-Wesley, 2003), by Don Box, with Chris Sells. Also, COM controls need COM initialized in a UI-friendly manner, so make sure that the STAThreadAttribute adorns your Main method:
<STAThread()> _ Shared Sub Main() Application.Run(New Form1()) End Sub When you create a new Windows Forms application in VS.NET, this attribute is applied by default, so to hurt yourself you must actively remove it. |