Fixed Layout


The fundamental elements of the layout system assist control positioning, sizing, and ordering to establish a basic composition. One of the key requirements, therefore, is to ensure that the basic composition is retained, something that depends on the Windows Forms Designer "remembering" your composition.

Position and Size

When controls are dropped onto a form, moved into position, and resized as necessary, the Windows Forms Designer needs a mechanism that allows it to accurately compose and recompose a form and its controls at design-time and run-time. For example, consider the four controls hosted on a form in Figure 4.1.

Figure 4.1. Controls Contained by a Form


The Windows Forms Designer generates the code to instantiate, position, and size each of these controls. This code is added to the form's Designer-managed InitializeComponent method:

// PositionAndSizeForm.designer.cs using System.Drawing; using System.Windows.Forms; ... partial class PositionAndSizeForm {   ...   void InitializeComponent() {     this.nameLabel = new Label();     this.nameTextBox = new TextBox();     this.occupationLabel = new Label();     this.occupationTextBox = new TextBox();     ...     // nameLabel     this.nameLabel.Location = new Point(12, 15);     this.nameLabel.Size = new Size(34, 13);     ...     // nameTextBox     this.nameTextBox.Location = new Point(79, 12);     this.nameTextBox.Size = new Size(110, 20);     ...     // occupationLabel     this.occupationLabel.Location = new Point(12, 42);     this.occupationLabel.Size = new.Size(61, 13);     ...     // occupationTextBox     this.occupationTextBox.Location = new Point(79, 39);     this.occupationTextBox.Size = new Size(110, 20);     ...   }   Label nameLabel;   TextBox nameTextBox;   Label occupationLabel;   TextBox occupationTextBox; }


Position, with respect to the upper-left corner of each control's parent, is stored in the Location property, which is of type System.Drawing.Point. Size is captured by the Size property, which is of type System.Drawing.Size.

Dragging controls around and resizing them to establish a composition can be quite an endeavor, particularly as you try to ensure that they are nicely spaced and aligned with respect to each other and the form. Fortunately, the Windows Forms Designer offers specialized layout support to assist this process.

Layout Mode

One aspect of form composition is to make sure that controls are nicely aligned with respect to each other. Another is to ensure that appropriate and consistent amounts of white space are maintained between controls and the edges of a form. For this, the Windows Forms Designer provides two layout modes: SnapToGrid and SnapLines.

You configure the layout mode by setting the LayoutMode property via Tools | Options | Windows Forms Designer | General. Either mode causes controls to snap to certain locations determined by the mode; a control snaps when the Designer detects that it is within a certain proximity to a predefined location and automatically aligns it to that location.

SnapToGrid supports snapping to a predefined grid whose dimensions you can set in the same location you configure the layout mode. However, real-world composition is more complicated and flexible than SnapToGrid accommodates. This is why we have the SnapLines layout mode, Windows Forms Designer's default. When controls are dragged onto or around a form or resized, snap lines are manifested as one or more "sticky" lines that guide controls to alignment with other controls in close proximity, including to horizontal and vertical edges, to common text baselines, and to text margins. These snap lines are all illustrated in Figure 4.2.

Figure 4.2. SnapLines Layout Mode with Control Edge, Text Margin, Text Baseline, and Space Snap Lines


The Windows Forms Designer easily determines control edge, text margin, and text baseline snap lines without your help. However, you determine space proximity, which is a combination of two pieces of information for each control and the form: padding and margin.

Padding

Padding is the internal distance in pixels from the edge of a form or control's client area that child controls (and also things like text, images, and so on) can't intrude on. You configure this using the Padding property, which is of type Padding:

namespace System.Windows.Forms {    struct Padding {      // No padding      public static readonly Padding Empty;      // Constructors      Padding(int all);      Padding(int left, int top, int right, int bottom);      // Properties (Properties window and code)      int All { get; set; } // Get/Set all padding edges      int Bottom { get; set; } // Get/Set bottom padding edge only      int Left { get; set; } // Get/Set left padding edge only      int Right { get; set; } // Get/Set right padding edge only      int Top { get; set; } // Get/Set top padding edge only      // Properties (Code only)      int Horizontal { get; } // Sum of Left and Right padding      int Vertical { get; } // Sum of Top and Bottom padding      Size Size { get; } // Horizontal + Vertical    } }


Padding is implemented on the base Control class and most controls that derive from it, including most common controls, user controls, container controls, and forms. Some controlsincluding TextBox, ListBox, ListView, and MonthCalendardon't support padding, because padding is either fixed or doesn't make sense for them. For those controls that do support padding, the default is to have zero padding, although you can change this by setting the Padding property with the desired values, as shown in Figure 4.3.

Figure 4.3. Setting a Control's Padding


You can set each dimension individually, or you can use the Padding.All shortcut if all the desired padding dimensions are the same. Either way, the Windows Forms Designer generates the appropriate code:

// PositionAndSizeForm.designer.cs using System.Windows.Forms; ... partial class PositionAndSizeForm {   ...   void InitializeComponent() {     ...     this.paddedLabel.Padding = new Padding(3);     ...   } }


Note that the Padding structure's Horizontal, Vertical, and Size properties are read-only and consequently not available from the Properties window. However, you may find them useful when rendering a custom control, as discussed in Chapter 11: Design-Time Integration: The Properties Window.

Margins

A margin defines the spacing between adjacent controls. You configure margins by using a control's Margin property, which is also of type Padding and is configured in the same manner. All controls implement the Margin property except for Form, because margins are useful only within a form's client area.

Calculating Space SnapLines

When the Windows Forms Designer calculates the size and location of the space proximity snap lines (as shown in Figure 4.2), it adds the padding and margin values for each relevant dimension of the control being dragged or resized and the controls around it. Figure 4.4 illustrates how various combinations of padding and margins are used by the Windows Forms Designer in its calculations.

Figure 4.4. Using the Margin and Padding Properties to Calculate the Space Snap Line (See Plate 6)


Location, Size, Padding, and Margin constitute the basic set of information that allows the Windows Forms Designer to accurately reconstruct and lay out your form at design-time, and allows Windows Forms to do the same at run-time.

However, even though this information keeps controls positioned nicely with respect to each other and to their host form, it has no effect when controls appear on top of other controls. In these situations, we need to remember which controls appear above which. For this, the Windows Forms Designer supports control positions within a vertical dimension known as the z-order.

Control Z-Order

Although a control's location specifies its upper-left position in a container relative to the container's upper-left corner, all controls in the same container are logically ordered in a vertical stack, with controls higher in the stack being rendered on top of controls lower in the stack. The position of a control within this stack is defined by its z-order and is implicitly determined by the order in which controls are added to their container. For example, consider the following code:

// ZOrderForm.designer.cs partial class ZOrderForm {   void InitializeComponent() {     ...     this.Controls.Add(this.zorder0button3);     this.Controls.Add(this.zorder1button2);     this.Controls.Add(this.zorder2button1);     ...   } }


The resulting z-order of these controls is shown in Figure 4.5.

Figure 4.5. Z-Order in Action


As you can see, controls are rendered in last-to-first order, although their z-order is calculated in first-to-last order. The first control to be added to the Controls collection, and the last control to be drawn on the form, has the highest z-order in the vertical stack, which equates to a z-order number of zero. Controls lower down in the stack may have a higher z-order number but are considered lower in the z-order itself.

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). At run-time, you can use the Control.BringToFront and Control.SendToBack methods. For more control, you can use the SetChildIndex property of the Controls collection. But the easiest approach is to use Document Outline in VS05 (View | Other Windows | Document Outline), as shown in Figure 4.6

Figure 4.6. Managing Z-Order with Document Outline


Document Outline visualizes the containment hierarchy of all controls on a form, including z-order within each container. Additionally, it lets you change a control's container and z-order directly. For example, Figure 4.6 shows a control's z-order about to be moved up in the container to cover the other controls in the same container. You'll also find Document Outline useful for shuffling tool strip items left and right within tool strip controls, which are discussed later in this chapter.

Control Tab Order

Just as you can control the visual order of your controls, you can also control the sequence in which a user can navigate through them at run-time. This sequence is known as the tab order. A control is registered to be included in the tab order when its Boolean TabStop property is set to true, the default. The position of a control in the tab order is determined by its TabIndex property, an integer value that the Windows Forms Designer automatically generates for controls as they are dropped onto a form. The tab index starts at zero for the first control dropped and increases for each subsequently dropped control.

To change the tab order, you can either programmatically set the TabIndex properties for all controls, or declaratively using the Properties window. However, you may find the programmatic technique laborious because you have to write code, while using the Properties window can be monotonous as you iteratively navigate between it and controls on a form, one control at a time, setting the TabIndex and remembering the tab order as you go. These problems are exacerbated when UI changes require an update to the tab order.

Instead, you can visually set the tab order from the Windows Forms Designer by clicking View | Tab Order, as illustrated in Figure 4.7.

Figure 4.7. Editing the Tab Order Visually


Each control's tab order is displayed in a blue box, irrespective of the value of its TabStop property. To change the tab order, you simply click the blue boxes with the crosshair cursor in the desired tab order. The Windows Forms Designer updates the indices after each click. You can stop visual tab order editing by again clicking View | Tab Order (or pressing Esc).

A control's tab index is relative to other controls within the container, and this means that you set its TabIndex property with a single integer value. However, when you visually edit the tab order, the tab order for each control prefixes the tab index of each container control up the containment hierarchy, as shown in Figure 4.6. For example, both TabIndex property values for the Name and Street address text boxes would be 1, even though they are displayed as "1" and "4.1," respectively, in the Windows Forms Designer. This is much easier to work with than writing code or using the Properties window.

One nice side effect of setting the tab order is that the first control in the tab order automatically receives the focus when a form is loaded. If your form is related to data entry, this simple UI optimization allows your users to start entering data immediately without having to navigate to the first data entry field.




Windows Forms 2.0 Programming
Windows Forms 2.0 Programming (Microsoft .NET Development Series)
ISBN: 0321267966
EAN: 2147483647
Year: 2006
Pages: 216

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net