Standard Controls And Components


The previous section covered some of the common methods and properties for controls. This section looks at the various controls that ship with the .NET Framework, and explains what each of them offers in added functionality. The sample download (www.wrox.com) includes a sample application called FormExample. This sample application is an MDI application (discussed later in the chapter) and includes a form named frmControls that contains many controls with basic functionality enabled. Figure 23-2 shows what frmControls looks like.

image from book
Figure 23-2

Button

The Button class represents the simple command button and is derived from ButtonBase class. The most common thing to do is to write code to handle the Click event of the button. The following code snippet implements an event handler for the Click event. When the button is clicked, a message box pops up that displays the button's name:

 private void btnTest_Click(object sender, System.EventArgs e) { MessageBox.Show(((Button)sender).Name + " was clicked."); } 

With the PerformClick method, you can simulate the Click event on a button without the user actually clicking the button. The NotifyDefault method takes a Boolean value as a parameter and tells the button to draw itself as the default button. Typically the default button on a form has a slightly thicker border. To identify the button as default, you set the AcceptButton property on the form to the button. Then, when the user presses the Enter key, the button Click event for the default button is raised. Figure 23-3 shows that the button with the caption Default is the default button (notice the dark border).

image from book
Figure 23-3

Buttons can have images as well as text. Images are supplied by way of an ImageList object or the Image property. ImageList objects are exactly what they sound like: a list of images managed by a component placed on a form. They are explained in detail later in this chapter.

Both Text and Image have an Align property to align the text or image on the Button. The Align property takes a ContentAlignment enumeration value. The text or image can be aligned in combinations of left and right and top and bottom.

CheckBox

The CheckBox control is also derived from ButtonBase and is used to accept a two-state or three-state response from the user. If you set the ThreeState property to true, the CheckBox's CheckState property can be one of these three CheckState enum values:

Checked

The CheckBox has a check mark.

Unchecked

The CheckBox does not have a check mark.

Indeterminate

In this state the CheckBox becomes gray.

The Indeterminate value can be set only in code and not by a user. This is useful if you need to convey to the user that an option has not been set. You can also check the Checked property if you want a Boolean value.

The CheckedChanged and CheckStateChanged events occur when the CheckState or Checked properties change. Catching these events can be useful for setting other values based on the new state of the CheckBox. In the frmControls form class, the CheckedChanged event for several CheckBoxes is handled by the following method:

 private void checkBoxChanged(object sender, EventArgs e) { CheckBox checkBox = (CheckBox)sender; MessageBox.Show(checkBox.Name + " new value is " + checkBox.Checked.ToString());  } 

As the checked state of each check box changes, a message box is displayed with the name of the check box that was changed along with the new value.

RadioButton

The last control derived from ButtonBase is the radio button. Radio buttons are generally used as a group. Sometimes referred to as option buttons, radio buttons allow the user to choose one of several options. When you have multiple RadioButton controls in the same container, only one at a time may be selected. So if you have three options — for example, Red, Green, and Blue — if the Red option is selected and the user clicks the Blue option, the Red is automatically deselected.

The Appearance property takes an Appearance enumeration value. This can be either Button or Normal. When choosing Normal, the radio button looks like a small circle with a label beside it. Selecting the button fills the circle; selecting another button deselects the currently selected button and makes the circle look empty. When choosing Button, the control looks like a standard button, but it works like a toggle — selected is the in position, deselected is the normal or out position.

The CheckedAlign property determines where the circle is in relation to the label text. It could be on top of the label, on either side, or below.

The CheckedChanged event is raised whenever the value of the Checked property changes. This way you can perform other actions based on the new value of the control.

ComboBox, ListBox, and CheckedListBox

ComboBox, ListBox, and CheckedListBox are all derived from the ListControl class. This class provides some of the basic list management functionality. The most important things about using list controls are adding and selecting data to the list. Which list is used is generally determined by how the list is used and the type of data that is going to be in the list. If there is a need to have multiple selections or the user needs to be able to see several items in the list at any time, the ListBox or CheckedListBox is going to be the best choice. If only a single item is ever selected in the list at any time, a ComboBox may be a good choice.

Data must be added to a list box before it can be useful. This is done by adding objects to the ListBox. ObjectCollection. This collection is exposed by the list's Items property. Because the collection stores objects, any valid .NET type can be added to the list. In order to identify the items, two important properties need to be set. The first is the DisplayMember property. This setting tells the ListControl what property of your object should be displayed in the list. The other is ValueMember, which is the property of your object that you want to return as the value. If strings have been added to the list, by default the string value is used for both of these properties. The frmLists form in the sample application shows how both objects and strings (which are of course objects) can be loaded into a list box. The example uses Vendor objects for the list data. The Vendor object contains just two properties: Name and PhoneNo. The DisplayMember property is set to the Name property. This tells the list control to display the value from the Name property in the list to the user.

A couple of ways exist to access the data in the list control, as shown in the following code example. The list is loaded with the Vendor objects. The DisplayMember and ValueMember properties are set. You can find this code in the frmLists form class in the sample application.

First is the LoadList method. This method loads the list with either Vendor objects or a simple string containing the vendor name. An option button is checked to see which values should be loaded in the list:

 private void LoadList(Control ctrlToLoad) { ListBox tmpCtrl = null; if (ctrlToLoad is ListBox) tmpCtrl = (ListBox)ctrlToLoad; tmpCtrl.Items.Clear(); tmpCtrl.DataSource = null; if (radioButton1.Checked) { //load objects tmpCtrl.Items.Add(new Vendor("XYZ Company", "555-555-1234")); tmpCtrl.Items.Add(new Vendor("ABC Company", "555-555-2345")); tmpCtrl.Items.Add(new Vendor("Other Company", "555-555-3456")); tmpCtrl.Items.Add(new Vendor("Another Company", "555-555-4567")); tmpCtrl.Items.Add(new Vendor("More Company", "555-555-6789")); tmpCtrl.Items.Add(new Vendor("Last Company", "555-555-7890")); tmpCtrl.DisplayMember = "Name"; } else { tmpCtrl.Items.Clear(); tmpCtrl.Items.Add("XYZ Company"); tmpCtrl.Items.Add("ABC Company"); tmpCtrl.Items.Add("Other Company"); tmpCtrl.Items.Add("Another Company"); tmpCtrl.Items.Add("More Company"); tmpCtrl.Items.Add("Last Company"); } } 

Once the data is loaded in the list the SelectedItem and SelectedIndex properties can be used to get at the data. The SelectedItem returns the object that is currently selected. If the list is set to allow multiple selections, there is no guarantee which of the selected items will be returned. In this case, the SelectObject collection should be used. This contains a list of all of the currently selected items in the list.

If the item at a specific index is needed, the Items property can be used to access the ListBox. ObjectCollection. Because this is a standard .NET collection class, the items in the collection can be accessed in the same way as any other collection class.

If DataBinding is used to populate the list, the SelectedValue property will return the property value of the selected object that was set to the ValueMember property. If Phone is set to ValueMember, the SelectedValue will return the Phone value from the selected item. In order to use ValueMember and SelectValue the list must be loaded by way of the DataSource property. An ArrayList or any other IList-based collection must be loaded with the objects first, then the list can be assigned to the DataSource property. This short example demonstrates this:

 listBox1.DataSource = null; System.Collections.ArrayList lst = new System.Collections.ArrayList(); lst.Add(new Vendor("XYZ Company", "555-555-1234")); lst.Add(new Vendor("ABC Company", "555-555-2345")); lst.Add(new Vendor("Other Company", "555-555-3456")); lst.Add(new Vendor("Another Company", "555-555-4567")); lst.Add(new Vendor("More Company", "555-555-6789")); lst.Add(new Vendor("Last Company", "555-555-7890")); listBox1.Items.Clear(); listBox1.DataSource = lst; listBox1.DisplayMember = "Name"; listBox1.ValueMember = "Phone"; 

Using SelectedValue without using DataBinding will result in a NullException error.

The following lines of code show the syntax of accessing the data in the list:

  //obj is set to the selected Vendor object obj = listBox1.SelectedItem; //obj is set to the Vendor object with index of 3 (4th  object) obj = listBox.Items[3]; //obj is set to the values of the Phone property of the selected vendor object //This example assumes that databinding was used to populate the list listBox1.ValuesMember = "Phone"; obj = listBox1.SelectValue; 

The thing to remember is that all of these methods return object as the type. A cast to the proper data type will need to be done in order to use the value of obj.

The Items property of the ComboBox returns ComboBox.ObjectCollection. A ComboBox is a combination of an edit control and a list box. You set the style of the ComboBox by passing a DropDownStyle enumeration value to the DropDownStyle property. The following table lists the various DropDownStyle values.

If the values in the list are wide you can change the width of the drop-down portion of the control with the DropDownWidth property. The MaxDropDownItems property sets the number of items to show when the drop-down portion of the list is displayed.

The FindString and FindStringExact methods are two other useful methods of the list controls. FindString finds the first string in the list that starts with the passed-in string. FindStringExact finds the first string that matches the passed-in string. Both return the index of the value that is found or -1 if the value is not found. They can also take an integer that is the starting index to search from.

Value

Description

DropDown

The text portion of the combo box is editable and users can enter a value. They also must click the arrow button to show the list.

DropDownList

The text portion is not editable. Users must make a selection from the list.

Simple

This is similar to DropDown except that the list is always visible.

DateTimePicker

The DateTimePicker allows users to select a date or time value (or both) in a number of different formats. You can display the DateTime-based value in any of the standard time and date formats. The Format property takes a DateTimePickerFormat enumeration that sets the format to Long, Short, Time, or Custom. If the Format property is set to DateTiemePickerFormat.Custom, you can set the CustomFormat property to a string that represents the format.

There is both a Text property and a Value property. The Text property returns a text representation of the DateTime value whereas the Value property returns the DateTime object. You can also set the maximum and minimum allowable date values with the MinDate and MaxDate properties.

When users click the down arrow, a calendar is displayed allowing the users to select a date in the calendar. Properties are available that allow you to change the appearance of the calendar by setting the title and month background colors as well as the foreground colors.

The ShowUpDown property determines whether an UpDown arrow is displayed on the control. The currently highlighted value can be changed by clicking the up or down arrow.

ErrorProvider

ErrorProvider is actually not a control but a component. When you drag a component to the designer, it shows in the component tray under the designer. What the ErrorProvider does is flash an icon next to a control when an error condition or validation failure exists. Suppose that you have a TextBox entry for an age. Your business rules say that the age value cannot be greater than 65. If users try to enter an age greater than that you must inform them that the age is greater than the allowable value and that they need to change the entered value. The check for a valid value takes place in the Validated event of the text box. If the validation fails, you call the SetError method, passing in the control that caused the error and a string that informs the user what the error is. An icon starts flashing indicating that an error has occurred, and when the user hovers over the icon the error text is displayed. Figure 23-4 shows the icon that is displayed when an invalid entry is made in the text box.

image from book
Figure 23-4

You can create an ErrorProvider for each control that produces errors on a form, but if you have a large number of controls this can become unwieldy. Another option is to use one error provider and in the validate event call the IconLocation method with the control that is causing the validation and one of the ErrorIconAlignment enumeration values. This value sets where the icon is aligned near the control. Then you call the SetError method. If no error condition exists, you can clear the ErrorProvider by calling SetError with an empty string as the error string. The following example shows how this works:

 private void txtAge_Validating(object sender,  System.ComponentModel.CancelEventArgs e) { if(txtAge.TextLength > 0 && Convert.ToInt32(txtAge.Text) > 65) { errMain.SetIconAlignment((Control)sender, ErrorIconAlignment.MiddleRight); errMain.SetError((Control)sender, "Value must be less then 65."); e.Cancel = true; } else { errMain.SetError((Control)sender, ""); } } private void txtZipCode_Validating(object sender, System.ComponentModel.CancelEventArgs e) { if(txtZipCode.TextLength > 0 && txtZipCode.Text.Length != 5) { errMain.SetIconAlignment((Control)sender, ErrorIconAlignment.MiddleRight); errMain.SetError((Control)sender, "Must be 5 charactors.."); e.Cancel = true; } else { errMain.SetError((Control)sender, ""); } } 

If the validation fails (the age is over 65 in txtAge, for example), then the SetIcon method of the ErrorProvider errMain is called. It will set the icon next to the control that failed validation. The error is set next so that when users hover over the icon, the message informs them of what is responsible for the failed validation.

HelpProvider

HelpProvider, like ErrorProvider, is a component and not a control. HelpProvider allows you to hook up controls to help topics. To associate a control with the help provider you call the SetShowHelp method, passing the control and a Boolean value that determines whether help will be shown. The HelpNamespace property allows you to set a help file. When the HelpNamespace property is set, the help file is displayed anytime you select F1 and a control that you have registered with the HelpProvider is in focus. You can set a keyword to the help file with the SetHelpKeyword method. SetHelpNavigator takes a HelpNavigator enumeration value to determine which element in the help file should be displayed. You can set it for a specific topic, the index, the table of contents, or the search page. The SetHelpString associates a string value of help-related text to a control. If the HelpNamespace property has not been set, pressing F1 will show this text in a pop-up window. Go ahead and add a HelpProvider to the previous example:

 helpProvider1.SetHelpString(txtAge,"Enter an age that is less than 65");  helpProvider1.SetHelpString(txtZipCode,"Enter a 5 digit zip code"); 

ImageList

An ImageList component is exactly what the name implies — a list of images. Typically, this component is used for holding a collection of images that are used as toolbar icons or icons in a TreeView control. Many controls have an ImageList property. The ImageList property typically comes with an ImageIndex property. The ImageList property is set to an instance of the ImageList component and the ImageIndex property is set to the index in the ImageList that represents the image that should be displayed on the control. You add images to the ImageList component by using the Add method of the ImageList.Images property. The Images property returns an ImageCollection.

The two most commonly used properties are ImageSize and ColorDepth. ImageSize uses a Size structure as its value. The default value is 1616 but it can be any value from 1 to 256. The ColorDepth uses a ColorDepth enumeration as its value. The color depth values go from 4 bit to 32 bit. For .NET Framework 1.1, the default is ColorDepth.Depth8Bit.

Label

Labels are generally used to provide descriptive text to the user. The text might be related to other controls or the current system state. You usually see a label together with a text box. The label provides the user with a description of the type of data to be entered in the text box. The Label control is always read-only — the user cannot change the string value of the Text property. However, you can change the Text property in your code. The UseMnemonic property allows you to enable the access key functionality. When you precede a character in the Text property with the ampersand (&), that letter will appear underlined in the label control. Pressing the Alt key in combination with the underlined letter puts the focus on the next control in the tab order. If the Text property contains an ampersand in the text, add a second one and it will not underline the next letter. For example, if the label text is "Nuts & Bolts," set the property to "Nuts && Bolts." Because the Label control is read-only, it cannot gain focus; that's why focus is sent to the next control. Because of this, it is important to remember that if you enable mnemonics, you must be certain to set the tab order properly on your form.

The AutoSize property is a Boolean value that specifies whether the Label will resize itself based on the contents of the Label. This can be useful for multilanguage applications where the length of the Text property can change based on the current language.

ListView

The ListView control allows you to display items in one of four different ways. You can display text with an optional large icon, text with an optional small icon, or text and small icons in a vertical list or in detail view, which allows you to display the item text plus any sub items in columns. If this sounds familiar it should, because this is what the right side of File Explorer uses to display the contents of folders. ListView contains a collection of ListViewItems. ListViewItems allows you to set a Text property used for the display. ListViewItem has a property called SubItems that contains the text that appears in detail view.

The following example demonstrates how you might use ListView. This example includes a short list of countries. Each CountryList object contains a property for the country name, country abbreviation, and currency. Here is the code for the CountryList class:

 using System; namespace FormsSample { public class CountryItem  : System.Windows.Forms.ListViewItem { string _cntryName = ""; string _cntryAbbrev = ""; public CountryItem(string countryName, string countryAbbreviation, string currency) { _cntryName = countryName; _cntryAbbrev = countryAbbreviation; base.Text = _cntryName; base.SubItems.Add(currency); } public string CountryName { get {return _cntryName;} } public string CountryAbbreviation { get {return _cntryAbbrev;} } } } 

Notice that you are deriving the CountryList class from ListViewItem. This is because you can add only ListViewItem-based objects to the ListView control. In the constructor, you pass the country name to the base.Text property and add the currency value to the base.SubItems property. This displays the country name in the list and the currency in a separate column when in details view.

Next, you need to add a couple of the CountryItem objects to the ListView control in the code of the form:

 lvCountries.Items.Add(new CountryItem("United States","US","Dollar")); lvCountries.Items[0].ImageIndex = 0; lvCountries.Items.Add(new CountryItem("Great Britain", "GB", "Pound")); lvCountries.Items[1].ImageIndex = 1; lvCountries.Items.Add(new CountryItem("Canada", "CA", "Dollar")); lvCountries.Items[2].ImageIndex = 2; lvCountries.Items.Add(new CountryItem("Japan", "JP", "Yen")); lvCountries.Items[3].ImageIndex = 3; lvCountries.Items.Add(new CountryItem("Germany", "GM", "Deutch Mark")); lvCountries.Items[4].ImageIndex = 4; 

Here you add a new CountryItem to the Items collection of the ListView control (lvCountries). Notice that you set the ImageIndex property of the item after you add it to the control. There are two ImageIndex objects, one for large icons and one for small icons (SmallImageList and LargeImageList properties). The trick with having two ImageLists with differing image sizes is to make sure you add the items to the ImageList in the same order. This way the index of each ImageList represents the same image, just different sizes. In the example, the ImageLists contain icons of the flags for each country added.

On top of the form, there is a ComboBox (cbView) that lists the four different View enumeration values. You add the items to the cbView like this:

 cbView.Items.Add(View.LargeIcon); cbView.Items.Add(View.SmallIcon); cbView.Items.Add(View.List); cbView.Items.Add(View.Details); cbView.SelectedIndex = 0; 

In the SelectedIndexChanged event of cbView, you add the single line of code:

 lvCountries.View = (View)cbView.SelectedItem; 

This sets the View property of lvCountries to the new value selected in the ComboBox control. Notice that you need to cast to the View type because object is returned from the SelectedItem property of the cbView.

Last, but hardly least, you have to add columns to the Columns collection. The columns are for details view. In this case you are adding two columns: Country Name and Currency. The order of the columns is as follows: the Text of the ListViewItem, then each item in the ListViewItem.SubItem collection, in the order it appears in the collection. You can add columns either by creating a ColumnHeader object and setting the Text property and optionally the Width and Alignment properties. After creating the ColumnHeader object you can add it to the Columns property. The other way to add columns is to use an override of the Columns.Add method. It allows you to pass in the Text, Width, and Alignment values. Here is an example:

 lvCountries.Columns.Add("Country",100, HorizontalAlignment.Left);  lvCountries.Columns.Add("Currency",100, HorizontalAlignment.Left); 

If you set the AllowColumnReorder property to true, the user can drag the column headers around and rearrange the column order.

The CheckBoxes property on the ListView shows check boxes next to the items in the ListView. This allows the user to easily select multiple items in the ListView control. You can check which items are selected by checking the CheckedItems collection.

The Alignment property sets the alignment of icons in Large and Small icon view. The value can be any of the ListViewAlignment enumeration values. They are Default, Left, Top, and SnapToGrid. The Default value allows the user to arrange the icons in any position that they want. When choosing Left or Top, the items are aligned with the left or top of the ListView control. When choosing SnapToGrid, the items snap to an invisible grid on the ListView control. The AutoArrange property can be set to a Boolean value and will automatically align the icons based on the Alignment property.

PictureBox

The PictureBox control is used to display an image. The image can be a BMP, JPEG, GIF, PNG, metafile, or icon. The SizeMode property uses the PictureBoxSizeMode enumeration to determine how the image is sized and positioned in the control. The SizeMode property can be AutoSize, CenterImage, Normal, and StretchImage.

You can change the size of the display of the PictureBox by setting the ClientSize property. You load the PictureBox by first creating an Image-based object. For example, to load a JPEG file into a PictureBox you would do the following:

 Bitmap myJpeg = new Bitmap("mypic.jpg");  pictureBox1.Image = (Image)myJpeg; 

Notice that you will need to cast back to an Image type because that is what the Image property expects.

ProgressBar

The ProgressBar control is a visual clue to the status of a lengthy operation. It indicates to users that there is something going on and that they should wait. The ProgressBar control works by setting the Minimum and Maximum properties. These properties correspond to the progress indicator being all the way to the left (Minimum) or all the way to the right (Maximum). You set the Step property to determine the number that the value is incremented each time the PerformStep method is called. You can also use the Increment method and increment the value by the value passed in the method call. The Value property returns the current value of the ProgressBar.

You can use the Text property to inform the user of the percentage of the operation that has been completed or the number of items left to process. There is also a BackgroundImage property to customize the look of the progress bar.

TextBox, RichTextBox and MaskedTextBox

The TextBox control is one of the most used controls in the Toolbox. The TextBox, RichTextBox, and MaskedTextBox controls are all derived from TextBoxBase. TextBoxBase provides properties such as MultiLine and Lines. MultiLine is a Boolean value that allows the TextBox control to display text in more than one line. Each line in a text box is a part of an array of strings. This array is exposed through the Lines property. The Text property returns the entire text box contents as a single string. TextLength is the total length of the string that text would return. The MaxLength property will limit the length of the text to the specified amount.

SelectedText, SelectionLength, and SelectionStart all deal with the currently selected text in the text box. The selected text is highlighted when the control has focus.

The TextBox control adds a couple of interesting properties. AcceptsReturn is a Boolean value that will allow the TextBox to accept the Enter key as a new line or whether it activates the default button on the form. When set to true, pressing the Enter key creates a new line in the TextBox. CharacterCasing determines the casing of the text in the text box. The CharacterCasing enumeration contains three values, Lower, Normal, and Upper. Lower lowercases all text regardless of how it is entered, Upper renders all text in uppercase letters, and Normal displays the text as it is entered. The PasswordChar property takes a char that represents what is displayed to the users when they type text in the text box. This is typically used for entering passwords and PINs. The text property will return the actual text that was entered; only the display is affected by this property.

The RichTextBox is a text editing control that can handle special formatting features. As the name implies, the RichTextBox control uses Rich Text Format (RTF) to handle the special formatting. You can make formatting changes by using the Selection properties: SelectionFont, SelectionColor, and SelectionBullet, and paragraph formatting with SelectionIndent, SelectionRightIndent, and SelectionHangingIndent. All of the Selection properties work in the same way. If there is a section of text highlighted, a change to a Selection property affects the selected text. If no text is selected, the change takes effect with any text that is inserted to the right of the current insertion point.

The text of the control can be retrieved by using the Text property or the Rtf property. The Text property returns just the text of the control whereas the Rtf property returns the formatted text.

The LoadFile method can load text from a file in a couple of different ways. It can use either a string that represents the path and file name or it can use a stream object. You can also specify the RichTextBoxStreamType. The following table lists the values of RichTextBoxStreamType.

Value

Description

PlainText

No formatting information. In places that contained OLE objects, spaces are used.

RichNoOleObjs

Rich text formatting, but spaces where the OLE objects would have been.

RichText

Formatted RTF with OLE objects in place.

TextTextOleObjs

Plain text with text replacing the OLE objects.

UnicodePlainText

Same as PlainText but Unicode encoded.

The SaveFile method works with the same parameters, saving the data from the control to a specified file. If a file by that name already exists, it will be overwritten.

The MaskedTextBox supplies the ability to limit what the user may input into the control. It also allows for automatic formatting of the data entered. Several properties are used in order to validate or format the user's input. Mask is the property that contains the mask string. The mask string is similar to a format string. The number of characters allowed, the data type of allowed characters, and the format of the data are all set using the Mask string. A MaskedTextProvider-based class can also provide the formatting and validation information needed. The MaskedTextProvider can only be set by passing it in on one of the constrictors.

Three different properties will return the text of the MaskedTextControl. The Text property returns the text of the control at the current moment. This could be different depending on whether or not the control has focus, which depends on the value of the HidePromptOnLeave property. The prompt is a string that users see to guide them on what should be entered. The InputText property always returns just the text that the user entered. The OutputText property returns the text formatted based on the IncludeLiterals and IncludePrompt properties. If, for example, the mask is for a phone number, the Mask string would possibly include parentheses and a couple of dashes. These would be the literal characters and would be included in the OutputText property if the IncludeLiteral property is set to true.

A couple of extra events also exist for the MaskedTextBox control. OutputTextChanged and InputTextChanged are raised when InputText or OutputText changes.

Panel

A Panel is simply a control that contains other controls. By grouping controls together and placing them in a panel, it is a little easier to manage the controls. For example, you can disable all of the controls in the panel by disabling the panel. Because the Panel control is derived from ScrollableControl, you also can get the advantage of the AutoScroll property. If you have too many controls to display in the available area, place them in a Panel and set AutoScroll to true — now you can scroll through all of the controls.

Panels do not show a border by default, but by setting the BorderStyle property to something other than none, you can use the Panel to visually group related controls. This makes the user interface more user-friendly.

Panel is the base class for the FlowLayoutPanel, TableLayoutPanel, TabPage, and SplitterPanel. By using these controls, a very sophisticated and professional-looking form or window can be created. The FlowLayoutPanel and TableLayoutPanel are especially useful for creating forms that resize properly.

FlowLayoutPanel and TableLayoutPanel

FlowLayoutPanel and TableLayoutPanel are new additions to the .NET Framework. As the names might suggest, the panels offer the ability to lay out a form using the same paradigm as a Web Form. FlowLayoutPanel is a container that allows the contained controls to flow in either the horizontal or vertical directions. Instead of flowing, clipping of the controls can be done. Flow direction is set using the

FlowDirection property and the FlowDirection enumeration. The WrapContents property determines if controls flow to the next row or column when the form is resized or if the control is clipped.

TableLayoutPanel uses a grid structure to control the layout of controls. Any Windows Forms control can be a child of the TableLayoutPanel, including another TableLayoutPanel. This allows for a very flexible and dynamic window design. When a control is added to a TableLayoutPanel, four additional properties are added to the Layout category of the property page. They are Column, ColumnSpan, Row, and RowSpan. Much like an html table on a Web page, column and row spans can be set for each control. By default the control will be centered in the cell of the table, but this can be changed by using the Anchor and Dock properties.

The default style of the rows and columns can be changed using RowStyles and ColumnsStyles collections. These collections contain RowStyle and ColumnsStyle objects, respectively. The Style objects have a common property, SizeType. SizeType uses the SizeType enumeration to determine how the column width or row height should be sized. Values include AutoSize, Absolute, and Percent. AutoSize shares the space with other peer controls. Absolute allows a set number of pixels for the size and Percent tells the control to size the column or width as a percentage of the parent control.

Rows, columns, and child controls can be added or removed at runtime. The GrowStyle property takes a TableLayoutPanelGrowStyle enumeration value that sets the table to add a column, a row, or stay fixed size when a new control is added to a full table. If the value is FixedSized, an AurgumentException is thrown when there is an attempt to add another control. If a cell in the table is empty, the control will be placed in the empty cell. This property only has an effect when the table is full and a control is added.

The frmPanel form in the sample application has FlowLayoutPanels and TableLayoutPanels with a variety of controls set in them. Experimenting with the controls, especially the Dock and Anchor properties of the controls placed in the layout panels, is the best way to understand how they work.

SplitContainer

The SplitContainer control is really three controls in one. It has two panel controls with a bar or splitter between them. The user is able to move the bar and resize the panels. As the panels resize, the controls in the panels also can be resized. The best example of a SplitContainer would be File Explorer. The left panel contains a TreeView of folders and the right side contains a ListView of folder contents. When the user moves the mouse over the splitter bar, the cursor changes showing that the bar can be moved.

The SplitContainer can contain any control including layout panels and other SplitContainers. This allows the creation of very complex and sophisticated forms.

The movement and position of the splitter bar can be controlled with the SplitterDistance and SplitterIncrement properties. The SplitterDistance property determines where the splitter starts in relation to the left or top of the control. The SplitterIncrement determines the number of pixels the splitter moves when being dragged. The panels can have their minimum size set with the Panel1MinSize and Panel2MinSize properties. These properties are also in pixels.

The Splitter control raises two events that relate to moving: the SplitterMoving event and the SplitterMoved event. One takes place during the move and the other takes place after the move has happened. They both receive a SplitterEventArgs. The SplitterEventArgs contains properties for the X and Y coordinates of the upper-left corner of the Splitter (SplitX and SplitY) and the X and Y coordinates of the mouse pointer (X and Y).

TabControl and TabPages

TabControl allows you to group related controls onto a series of tab pages. TabControl manages the collection of TabPages. Several properties control the appearance of TabControl. The Appearance property uses the TabAppearance enumeration to determine what the tabs look like. The values are FlatButtons, Buttons, or Normal. The Multiline property is a Boolean that determines if more than one row of tabs is shown. If the Multiline property is set to false and there are more tabs than can fit in the display, a set of arrows appears that allow the user to scroll and see the rest of the tabs.

The TabPage Text property is what is displayed on the tab. The Text property is a parameter in a constructor override as well.

Once you create a TabPage control, it is basically a container control for you to place other controls. The designer in Visual Studio .NET makes it easy to add TabPage controls to a TabControl control by using the collection editor. You can set the various properties as you add each page. Then you can drag the other child controls to each TabPage control.

You can determine the current tab by looking at the SelectedTab property. The SelectedIndex event is raised each time a new tab is selected. By listening to the SelectedIndex property and then confirming the current tab with SelectedTab, you can do special processing based on each tab.

ToolStrip

The ToolStrip control is a container control used to create toolbars, menu structures, and status bars. The ToolStrip is used directly for toolbars, and serves as the base class for the MenuStrip and StatusStrip controls.

When used as a toolbar, the ToolStrip control uses a set of controls based on the abstract ToolStripItem class. ToolStripItem adds the common display and layout functionality as well as managing most of the events used by the controls. ToolStripItem is derived from the System.ComponentModel.Component class and not from the Control class. ToolStripItem-based classes must be contained in a ToolStrip-based container.

Image and Text are probably the most common properties that will be set. Images can be set with either the Image property or by using the ImageList control and setting it to the ImageList property of the ToolStrip control. The ImageIndex property of the individual controls can then be set.

Formatting of the text on a ToolStripItem is handled with the Font, TextAlign, and TextDirection properties. TextAlign sets the alignment of the text in relation to the control. This can be any on the ControlAlignment enumeration values. The default is MiddleRight. The TextDirection property sets the orientation of the text. Values can be any of the ToolStripTextDirection enumeration values, which include Horizontal, Inherit, Vertical270, and Vertical90. Vertical270 rotates the text 270 degrees and Vertical90 rotates the text 90 degrees.

The DisplayStyle property controls whether text, image, text and image, or nothing is displayed on the control. When AutoSize is set to true, the ToolStripItem will resize itself so only the minimum amount of space is used.

The controls that are derived directly from ToolStripItem are listed in the following table.

Tool Strip Items

Description

ToolStripButton

Represents a button that the user can select.

ToolStripLabel

Displays non-selectable text or image on the ToolStrip. The ToolStripLabel can also display one or more hyperlinks.

ToolStripSeparator

Used to separate and group other ToolStripItems. Items can be grouped according to functionality.

ToolStripDropDownItem

Displays drop-down items. Base class for ToolStripDropDownButton, ToolStripMenuItem, and ToolStripSplitButton.

ToolStripControlHost

Hosts other non-ToolStripItem derived controls on a ToolStrip. Base class for ToolStripComboBox, ToolStripProgressBar, and ToolStripTextBox.

The first two items in the list, ToolStripDropDownItem and ToolStripControlHost, deserve a little more discussion. ToolStripDropDownItem is the base class for ToolStripMenuItems, which are used to build the menu structure. ToolStripMenuItems are added to MenuStrip controls. As mentioned earlier, MenuStrips are derived from ToolStrip controls. This is important when it comes time to manipulate or extend menu items. Because toolbars and menus are derived from the same classes, creating a framework for managing and executing commands becomes much easier.

ToolStripControlHost can be used to host other controls that do not derive from ToolStripItem. Remember that the only controls that can be directly hosted by a ToolStrip are those that derive from ToolStripItem. The following example shows how to host a DateTimePicker control on a ToolStrip:

 public mdiParent() { InitializeComponent(); ToolStripControlHost _dateTimeCtl;  _dateTimeCtl = new ToolStripControlHost(new DateTimePicker()); ((DateTimePicker)_dateTimeCtl.Control).ValueChanged += delegate { toolStripLabel1.Text =  ((DateTimePicker)_dateTimeCtl.Control).Value.Subtract(DateTime.Now).ToString(); }; _ _dateTimeCtl.Width = 200; _dateTimeCtl.DisplayStyle = ToolStripItemDisplayStyle.Text; toolStrip1.Items.Add(_dateTimeCtl); } 

This is the constructor from the frmMain form in the code sample. First, a ToolStripControlHost is declared and instantiated. Notice that when the control is instantiated that the control that is to be hosted is passed in on the constructor. The next line is setting up the ValueChanged event of the DateTimePicker control. The control can be accessed through the Control property of the ToolStripHostControl. This will return a Control object, so it will need to be cast back to the proper type of control. Once that is done, the properties and methods of the hosted control are available to use.

Another way to do this that would perhaps enforce encapsulation a little better would be to create a new class derived from ToolStripControlHost. The following code is another version of the tool strip version of the DateTimePicker called ToolStripDateTimePicker:

 namespace FormsSample.SampleControls { public class ToolStripDateTimePicker: System.Windows.Forms.ToolStripControlHost { //need to declare the event that will be exposed public event EventHandler ValueChanged; public ToolStripDateTimePicker ()  : base(new DateTimePicker()) { } //create strong typed Control property. public new DateTimePicker Control { get{return (DateTimePicker)base.Control;} } //create a striong typed Value property public DateTime Value { get { return Control.Value; } } protected override void OnSubscribeControlEvents(Control control) { base.OnSubscribeControlEvents(control); ((DateTimePicker)control).ValueChanged += new EventHandler(HandleValueChanged; } protected override void OnUnsubscribeControlEvents(Control control) { base.OnSubscribeControlEvents(control); ((DateTimePicker)control).ValueChanged -= new EventHandler(HandleValueChanged); } private void HandleValueChanged (object sender, EventArgs e) { if (ValueChanged != null) ValueChanged(this, e); } } } 

Most of what this class is doing is exposing selected properties, methods, and events of the DateTime Picker. This way a reference to the underlying control doesn't have to be maintained by the hosting application. The process of exposing events is a bit involved. The OnSubscribecontrolEvents method is used to synchronize the events of the hosted control, in this case DateTimePicker, to the Tool StripControlHost-based class, which is ToolStripDateTimePicker in the example. In this example, the ValueChanged event is being passed up to the ToolStripDateTimePicker. What this effectively does is allow the user of the control to set up the event in the host application as if ToolStripDate TimePicker was derived from DateTimePicker instead of ToolStripControlHost. The following code example shows this. This is the code to use ToolStripDateTimePicker:

 public mdiParent() { ToolStripDateTimePicker otherDateTimePicker = new ToolStripDateTimePicker (); otherDateTimePicker.Width = 200; otherDateTimePicker.ValueChanged +=  new EventHandler(otherDateTimePicker_ValueChanged); toolStrip1.Items.Add(otherDateTimePicker); } 

Notice that when the ValueChanged event handler is set up that the reference is to the ToolStrip DateTimePicker class and not to the DateTimePicker control as in the previous example. Notice how much cleaner the code in this example looks as compared to the first example. Not only that, because the DateTimePicker is wrapped up in another class, encapsulation has improved dramatically and ToolStripDateTimePicker is now much easier to use in other parts of the application or in other projects.

MenuStrip

The MenuStrip control is the container for the menu structure of an application. As mentioned earlier, MenuStrip is derived form the ToolStrip class. The menu system is built by adding ToolStripMenu objects to the MenuStrip. This can be done in code or in the designer of Visual Studio. Drag a MenuStrip control onto a form in the designer and the MenuStrip will allow the entry of the menu text directly on the menu items.

The MenuStrip control has only a couple of additional properties. GripStyle uses the ToolStripGrip Style enumeration to set the grip as visible or hidden. The MdiWindowListItem property takes or returns a ToolStripMenuItem. This ToolStripMenuItem will be the menu that shows all open windows in an MDI application.

ContextMenuStrip

To show a context menu, or a menu displayed when the user right-clicks the mouse, the ContextMenu Strip class is used. Like MenuStrip, ContextMenuStrip is a container for ToolStripMenuItems objects. However, it is derived from ToolStripDropDownMenu. A ContextMenu is created the same as a MenuStrip. ToolStripMenuItems are added and the Click event of each item is defined to perform a specific task. Context menus are assigned to specific controls. This is done by setting the ContextMenu Strip property of the control. When the user right-clicks the control, the menu will be displayed.

ToolStripMenuItem

ToolStripMenuItem is the class that builds the menu structures. Each ToolStripMenuItem object represents a single menu choice on the menu system. Each ToolStripMenuItem has a ToolStrip ItemCollection that maintains the child menus. This functionality is inherited from ToolStrip DropDownItem.

Because ToolStripMenuItem is derived from ToolStripItem, all of the same formatting properties apply. Images appear as small icons to the right of the menu text. Menu items can have check marks show up next to them with the Checked and CheckState properties.

Shortcut keys can be assigned to each menu item. Shortcut keys are generally two key chords such as Ctrl+C (common shortcut for Copy). When a shortcut key is assigned it can optionally be displayed on the menu by setting the ShowShortCutKey property to true.

To be useful, the menu item has to do something when the user clicks it or uses the defined shortcut keys. The most common way is to handle the Click event. If the Checked property is being used, the CheckStateChanged and CheckedChanged events can be used to determine a change in the checked state.

ToolStripManager

Menu and toolbar structures can become large and cumbersome to manage. The ToolStripManager class provides the ability to create smaller, more manageable pieces of a menu or toolbar structure and then combine them when needed. An example of this is if a form has several different controls on it. Each control must display a context menu. Several menu choices will be available for all of the controls, but each control will also have a couple of unique menu choices. The common choices can be defined on one ContextMenuStrip. Each of the unique menu items can be predefined or created at runtime. For each control that needs a context menu assigned to it, the common menu is cloned and the unique choices are merged with the common menu using the ToolStripManager.Merge method. The resulting menu is assigned to the ContextMenuStrip property of the control.

ToolStripContainer

The ToolStripContainer control is used for docking of ToolStrip based controls. Adding a ToolStrip Container and setting the Docked property to Fill, a ToolStripPanel is added to each side of the form and a ToolStripContainerPanel is added to middle of the form. Any ToolStrip (ToolStrip, MenuStrip, or StatusStrip) can be added to any of the ToolStripPanels. The user can move the ToolStrips by grabbing the ToolStrip and dragging it to either side or bottom of the form. By setting the Visible property to false on any of the ToolStripPanels, a ToolStrip can no longer be placedin the panel. The ToolStripContainerPanel in the center of the form can be used to place the other controls the form may need.




Professional C# 2005
Pro Visual C++ 2005 for C# Developers
ISBN: 1590596080
EAN: 2147483647
Year: 2005
Pages: 351
Authors: Dean C. Wills

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