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 I showed earlier in this chapter), or you can add arrays of controls the way the Designer-generated InitializeComponent does:
void InitializeComponent() { this.SuspendLayout(); // ...child control creation and initialization... this.Controls.AddRange( new System.Windows.Forms.Control[] { this.statusBar1, this.textBox1}); this.ResumeLayout(false); } 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-OrderIn 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: this.Controls.AddRange( new System.Windows.Forms.Control[] { this.zOrder0Button, this.zOrder1Button, this.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 OrderDirecting 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 ControlsModern 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:
static void Main() { Application.EnableVisualStyles(); Application.Run(new Form1()); } 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]
public MyThemedForm() { // Required for Windows Form Designer support InitializeComponent(); // Set the FlatStyle for all controls SetFlatStyleSystem(this); } void SetFlatStyleSystem(Control parent) { foreach( Control control in parent.Controls ) { // Only these controls have a FlatStyle property ButtonBase button = control as ButtonBase; GroupBox group = control as GroupBox; Label label = control as Label; if( button != null ) button.FlatStyle = FlatStyle.System; else if( group != null ) group.FlatStyle = FlatStyle.System; else if( label != null ) label.FlatStyle = FlatStyle.System; // Set contained controls FlatStyle, too SetFlatStyleSystem(control); } } 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 ControlsAs 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.
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]
Also, COM controls need COM initialized in a UI-friendly manner, so make sure that the STAThreadAttribute adorns your Main method: [STAThreadAttribute] static void Main() { Application.Run(new Form1()); } 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. |