Standard Controls and Components C# Help

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.csharpaid.com) includes a sample application called FormExample, This sample application is an MDI application and includes a form named form Controls that contains many controls with basic functionality enabled. Figure 31-1 shows what formControls looks like.

Button

The Button class represents the simple command button and is derived from the 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)
(
Me’ssageBox.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 31-2shows that the button with the caption Default is the default button (notice the dark border).

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.

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.

Figure 31-1

Figure 31-1

Figure 31-2

Figure 31-2

CheckSox

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 the three Checkstate enum values in the following table.

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 it, The CheckedChanged and CheckStdteChanged events occur when the CheckState or Checked properties change. Catching these events can be useful for setting other values based QI the new state of the CheckBox. In the frmControls form class, the Checkedf:;hanged 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, Re’d,Green, and Inue – 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 you choose 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 you choose But ton, the control looks like a standard button, but it works like a toggle – selected is the in position, and 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 aspects of using list controls are adding data to and selecting data from 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 if their 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 combo and may be a good choice.

Data must be added to a list box b~fore 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 stringt”{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 phone No. 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.
You can access the data in the list control in a couple of ways, 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 formLists 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:

Once the data is loaded in the list the Selectedltem and Selectedlndex properties can be used to get at the data The SelectedItem property 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 SelectObj ect 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:

listBoxl.DataSource = null;
System.Collections.ArrayList 1st = new System.Collections.ArrayList();
lst.Add(new Vendor(“XYZ Company”, “555-555-1234”));
lst.Add(new Vendor(“ABC Company”, “555-555-2345”));
1st .Add (new vendor (“Other Company”, “555-555-345’6′));
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′));
listBoxl.ltems.Clear() ;
listBoxl.DataSource = 1st;
listBoxl.DisplayMember = ‘Name’;
listBoxl.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 = listBoxl.Selectedltem;
//obj is set to the Vendor object ~ith index of 3 (4’h object).
//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.
listBoxl.ValuesMember = “Phone’;
obj = listBoxl.SelectValue;

The thing to remember is that all of these methods return obj ect 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 comboaox , Obj ectCollection. 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.

H the values in the list are wide, you can change the width of the drop-down portion of the cohtrol with the DropDownWidth property The MaxDropDownltems 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.

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. H 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. Youcan 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 ShowUpDownproperty determines whether an UpDownarrow 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 The ErrorProvider flashes 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 roles say that the age value cannot be greater than 65. H 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 Val ida ted event of the text box, 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 31-3 shows the icon that is displayed when an invalid entry is made in the text box.

Figure 31-3

Figure 31-3

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, to call the Ic:onLocation method with the control that is causing the validation and one of the ErrorlconAlignment enumeration values. This value sets where the icon is aligned near thecontrol.Then you call the SetError method no error condition exists, you can clear the ErrorProvider by calling SetError with an empty string  the error string, The followingexample shows how this works:

If the validation fails,(the age is over 65in txtAge, for example), then the Set icon 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. Toassociate a control with the help provider, you call the SetShowHelp method, passing the control and a Boolea value that determines whether help will be shown, The HelpNamespace property allows you to s \ help file.When the HelpNamespace property is set, the help file is displayed any time you select 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 fileshould be displayed. You can set it for a specifictopic, the index, the table of contents, or the search page. SetHelpString associates a string value of help-related text to a control, H the HelpNamespace property has not been set, pressing Fl will show this text in a pop-up window, Go ahead and add a HelpProvider to the previous example:

helpProviderl.SetHelpString(txtAge, “Enter an age that is less than 65,”
helpProviderl.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 16 x 16 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 (s), 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 multi-language applications where the length of the Text property can change based on the current language.

ListView

The List View control enables 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 subitems 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 allow 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 List View, 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:

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 CountryItemobjects to the ListViewcontrol in the code of the form:

Here you add a new CountryItem to the Items collection of the ListView control (lVCountries), Notice that you set the lmageIndex 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 to having two ImageLists with differing image sizes is to make sure you add the items to the ImageList in the same order. This way index of each ImageList represents the same image, just different sizes, In the example, the Image contain icons of the flags for each country added, On top of the form, there is a ComboBox View) that lists the four different View enumeration values.

You add the items to the cbview like this.

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

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

This sets the View property of 1vCountries to the new value selected in the ComboBoxcontrol, Notice that you need to cast to the view type because obj ect is returned from the Selectedltem 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 other 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 users to arrange the icons in any position that they want. Wheri choosing Left 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.

Picture Box

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 Minimumand Maximumproperties, which 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 Backgroundlmage property to customize the look of the progress bar.

TextBox, RlchTextBox, 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 Selectionlndent, SelectionRightlndent, and selectionHanging~ndent. All of the Selection properties work in the same way, If a section of text is 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.

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, which 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. AMaskedTextProvider-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 Incl udeLi terals 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 Outpu tText property if the IncludeLi teral property were 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. Bygrouping 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 using borders. This makes the user interface more user-friendly.

Panel is the base class for the FlowLayoutPanel, TableLayoutPanel, TabPage, and Spli tterPanel.

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.

FlowLayoufPanel and TableLayoufPanel

FlowLayoutPanel and TableLayoutPanel are new additions to the .NET Framework. As the names might suggest. the panels offer the capability to layout a form using the same paradigm as a WebForm FlowLayout’Panel is a container that allows the contained controls to flow in either the horizontal 0 vertical directions.

Instead of flowing, it allows for the clipping of the controls, Flow direction is set using the FlowDirection property and the FlowDirection enumeration. The WrapContents prop( 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 RowSp’m.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 or a row, or stay a fixed size when a new control is added to a full table, If the value is FixedSized, an ArgumentException 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 has an effect only when the table is full and a control is added.

The formPanel 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 Spl i tContainer is 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 Spli t terDistance 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 Panel2MinSize 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 SplitterEventArgs. 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 setto false and there are more tabs than can fit in the display, arrows appear 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 VISualStudio .NET makes it easy to add TabPage controls to a TabControl control by using collection editor. Youcan set the various properties as you add each page. Then you can drag the o er child controls to each TabPage control.

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

You could, for example, manage the data displayed for 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 MenOtrip and Start:usStrip controls.

While used as a toolbar, the ToolStrip control uses a set of controls based on the abstract Tool.StripItem class, ToolStripItem adds the common display and layout functionality as well as managing most of the events used by the controls, ToolStripltem is derived from the System COllPonentModel.

Component class and not from the Control class. ToolStripltem-based classes must be contained in a Tool Strip-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 IrnageList control and setting it to the IrnageList property of the ToolStrip control. The Imagelndex 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 of the ControlAlignrnent 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. Verticai270 rotates the text 270 degree 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.

The first two items in the list, ToolStripDropDownltem and ToolStripControlHost, deserve a little more discussion. ToolStripDropDownltem is the base class for ToolStripMenuItems, which are used to build the menu structure, ToolStripMenultems 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:

This is the constructor from the form Main form in the code sample, First, a ToolStripControlHost is declared and instantiated, Notice that when the control is instantiated, the control that is to be hosted is passed in on the’ constructor, The next line sets up the ValueChanged event of the DateTimePicker control, The control can be accessed through the Control property of the ToolStripHostControl.

This returns 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 wopld perhaps enforce encapsulation a Iittle better is to create a new class derived from ToolStripControlHost, The following code is another version of the toolstrip version of the DateTimePicker called ToolStripDateTimePicker:

Most of what this class is doing is exposing ~ected properties, methods, and events of the DataTimePicker, This way, a reference to under lying 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 ToolStripControlHost-based class; which is DataPickerToolStrip in the example.

In this example, the ValueChanged event is being passed up to the DTPickerToolStrip What this effectively does is allow the user of the control to set up the event in the host application as if DTPickerToolStrip were derived from DateTimePicker instead of ToolStripControlHost. The following code example shows this.

This is the code to use DTPickerToolStrip:

Notice that when the Val ueChanged event handler is set up that the reference is to the DTPickerToolStrip class and not to the DateTimePicker control as in the previous example, Also notice how much cleaner the code in this example looks as compared to the first example.

In addition, because the DateTimePicker is wrapped in another class, encapsulation has improved dramatically and DTPickerToolStrip 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 from the ToolStrip class, The menu system is built by adding ToolStripMenu objects to the MenuStrip, You can do this 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
ToolStripGripStyle enumeration to set the grip as visible or hidden, The MdiWindowListltem property takes or returns a ToolStripMenultem, This ToolStripMenuItem is the menu that shows all open windows in an MDI application.

ContextMenuStrip

Toshow a context menu. or a menu displayed when the user right-clicks the mouse, the ContextMenuStrip class is used, LikeMenuStrip, Context.-!enuStrip is a container for ToolStripMenultems objects.

However, it is derived from ToolStripDropDownMenu. A ContextMenu is created the same way as a MenuStrip.

ToolStripMenuItem<; 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 ContextMenuStrip property of the control, When the user right-clicks the control, the menu is displayed.

ToolStrlpMenultem

ToolStripMenultem is the class that builds the menu structures, Each ToolStripMenuItem object represents a single menu choice on the menu system. Each ToolStripMenuItem has a ToolStripItemCollection that maintains the child menus. Thi$lunctionality is inherited from ToolStripDropDownltems.

Because ToolStripMenuItem is derived from ToolStripltem, 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. They are genaNIy two key chords such as Ctr -C (common shortcut for Copy); When a shortcut key is assigned, is optionally be displayed on menu by setting the ShowShortCutKey property to true.

Tobe useful, the menu item has to do something when the user clicks it or uses the defined shortcut, The most common way is to handle the Click event.

If the Checked property is being used, the Check StateChanged 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 then combine them when needed, An example of this is a form that has several different control Each control must display a context menu, Several menu choices will be available for all of the 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, 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 When you add ToolStripContainer and set the Docked property to Fill, a ToolStripPanel is added to each 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 T09lStripS by grabbing the ToolStrip and dragging it to either side or bottom of the form.

If you set the Visible property to false on any of the ToolStripPanels, a ToolStrip can no longer be placed in the panel, The ToolStripContainerPanel in the center of the form can be used to place the other controls the form may need.

Forms

Earlier in this chapter, you learned how to create a simple Windows application, The example contained one class derived from the System. windows. Forms. Form class. According to the .NET Framework documentation, “a Form is a representation of any window in your application.” H you come from a Visual Basic baclcground, the term “form” will seem familiar.

If your background is C++ using MFC, you’re probably used to calling a form a window, dialog box, or maybe a frame. Regardless, the form is the basic means of interacting with the user. Earlier, the chapter covered some of the more common and useful properties, methods, and events of the Control class, and because the Form class is a descendant of the Control class, all of the same properties, methods, and events exist in the Form class, The Form class adds considerable functionality to what the Control class provides, and that’s what this section discusses.

Form Class

A Wmdows client application can contain one form or hundreds of forms. The forms can be an SDIbased (Single Document Interface) or MDI-based (Multiple Document Interface) application, Regardless, the Sys tem. Windows Forms, Form class is the heart of the Windows client.

The Form class is derived from ContainerControl, which is derived from ScrollableControl, which is derived from Control, Because of this, you can assume that a form is capable of being a container for other controls, capable of scrolling when the contained controls do not fit the client area, and has many of the same properties, methods, and events that other controls have. This also makes the Form class rather complex, This section looks at much of that functionality.

Form Instantiation and Destruction

The process of form creation is important to understand, What you want to do depends on where you write the initialization code. For instantiation, the events occur in the following order:

  1. Constructor
  2. Load
  3. Activated
  4. Closing
  5. Close
  6. Deactivate

The first three events are of concern during initialization, The type of initialization you want to do could determine which event you hook into, The constructor of a class occurs during the object instantiation, The Load event occurs after object instantiation, but just before the form becomes visible, The difference between this and the constructor is the viability of the form, When the Load event is raised, the form exists but isn’t visible, During constructor execution, the form is in the process of coming into existence, The Activated event occurs when the form becomes visible and current.

This order can be altered slightly in one particular situation. If during the constructor execution of the form, the Visible property is set to true or the Show method is called (which sets the Visible property to true), the Load event fires immediately, Because this also makes the form visible and current, the Activate event is also raised.

If there is code after the Visible property has been set, it will execute So, the startup event might look something like this:

  1. Constructor, up to Visible “‘ true
  2. Load
  3. Activate
  4. Constructor, after Visible = true

This could potentially lead to some unexpected results. From a best practices standpoint, it would seem that doing as much initialization as possible in the constructor might be a good idea.

Now what happens when the form is closed? The Closing event gives you the opportunity to cancel the process. The Closing event receives CancelEventArgs as a parameter, This has a Cancel property that, if set to true, cancels the event and the form remains open, The Closing event happens as the form is being closed, whereas the Closed event happens after the form has been closed, Both allow you to do any cleanup that might have to be done.

Notice that the Deactivate event occurs after the form has been closed, This is another potential source of difficult-to-findbugs, Be sure that you don’t have anything in Deactivate that could keep the form from being properly garbage collected. For example, setting a reference to another object would cause the form to remain alive.

If you call the Application. Exit () method and you have one or more forms currently open, the Closing and Closed events will not be raised. This is an important consideration if you have open files or database connections that you were going to clean up. The Dispose method is called, so perhaps another best practice would be to put most of your cleanup code in the Dispose method.

Some properties that relate to the startup of a form are StartPosition, Show lnTaskbar, and TopMost, StartPosition can be any of the FormStartPosition enumeration values. They are:

  1. Center Parent – The form is centered in the client area of the parent form.
  2. CenterScreen – The fonn is centered in the current display.
  3. Manual – The form’s location is based on the values in the Location property.
  4. WindowsDefaultBounds – The form is located at the default Windows position and uses the default size.
  5. WindowsDefaultLocation – The Windows default location is used, but the size is based on the Size property.

The ShowlnTaskbar property determines if the form should be available in the taskbar. This is relevant only if the form is a child form and you only want the parent form to show in the taskbar. The TopMost property tells the form to start in the topmost position in the Z-order of the application, This is true even if the form does not immediately have focus.

In order for users to interact with the application, they must be able to see the form, The Show and ShowDialog methods accomplish this, The Show method just makes the form visible to the user, The following code segment demonstrates how to create a form and show it to the user, Assume that the form you want to display is called MyFormClass.

MyFormClass myForm= new MyFormClass()
myForm.Show() ;

That’s the simple way. The one drawback to this is that there isn’t any notification back to the calling code that myFormis finished and has been exited. Sometimes this isn’t a big deal, and the Showmethod will work fine, If you do need some type of notification, ShowDialog is a better option.

When the Showmethod is called, the code that follows the Showmethod is executed immediately, When ShowDialog is called, the callingcode is blocked and will wait until the form that ShowDialog called is closed.Not only will the ca1lingcode be blocked,but the form will optionally return a DialogResult value.

The DialogResul t enumeration is a list of identifiers that describe the reason the dialog is closed, These include OK, Cancel, Yell,No,and several others, In order for the form to return a DialogResult, the form’s DialogResult property must be set or the DialogResult property on one of the form’s buttons must be set.

For example, suppose that part of application asks for the phone number of a client, The form has a text box for the phone number and two buttons; one is labeled OK and the other is labeled Cancel, If you set the DialogResult of the OK button to DialogResult, OK and the DialogResult property on the Cancel button to DialogResult Cancel, then when either of these buttons is selected, the form becomes invisible and returns to the calling form the appropriate DialogResult value, Now notice that the form is not destroyed; the Visible property is just set to false. That’s because you still must get values from the form, For this example, you need to get a phone number, By creating a property and the form for the phone number, the parent form can now get the value and call the Close method on the form, This is what the code for the child form looks like:

The first thing to notice is that there is no code to handle the click events of the buttons, Because the DialogResult property is set for each of the buttons, the form disappears after either the OK or Cancel button is clicked, The only property added is the Phone Number property, The following code shows the method in the parent form that calls the Phone dialog:

This looks simple enough. Create the new Phone object (frm). When the fnn. ShowDialog () method is called, the code in this method will stop and wait for the Phone form to return, You can then check the DialogResult property of the Phone form. Because it has not been destroyed yet, just made invisible, you can still access the public properties, one of them being the PhoneNumber property, Once you get the data you need, you can call the Close method on the form.

This works well, but what if the returned phone number is not formatted correctly? If you put the ShowDialog inside of the loop, you can just recall it and have the user reenter the value, This way you get a proper value.

Remember that you must also handle the DialogResul t .Cancel if the user clicks the Cancel button.

Phone frm = new Phone();
while (true)
(
frm.ShowDialog();

Most of these are self-explanatory, with the exception of the two tool window borders, A Tool window will not appear in the taskbar, regardless of how ShowlnTaskBar is set. Also a Tool window will not show in the list of windows when the user presses Alt+Tab, The default setting is Sizable.

Unless a requirement dictates otherwise, colors for most GUI elements should be set to system colors and not to specific colors, This way, if some users like to have all of their buttons green with purple text, the application will follow along with the same colors. To set a control to use a specific system color, you must call the FromKnownColor method of the System. Drawing Color class, The FromKnownColor method takes a KnownColor enumeration value. Many colors are defined in the enumeration, as well as the various GUI element colors, such as Control, ActiveBorder, and Desktop.

So, for example, if the Background color of the form should always match the Desktop color, the code would look like this:

myForm.BackColor = Color.FromKnownColor(knownColor.Desktop);

Now if users change the color of their desktops, the background of the form changes as well, This is a nice, friendly touch to add to an application, Users might pick out some strange color combinations for their desktops, but it is their choice.

Windows XP introduced a feature called visual styles. VISualstyles change the way buttons, text boxes, menus, and other controls look and react when the mouse pointer is either hovering or clicking, You can enable visual styles for your application by calling the Application. EnableVisualStyles method.

This method has to be called before any type of GUI is instantiated Because of this, it is generally called in the Main method, as demonstrated in this example:

[STAThread)
static void Main()
(
Application.EnableVisualStyles();
Application. Run(new Form1());

This code allows the various controls that support visual styles to take advantage of them, Because of an issue with the EnableVisualStyles method, you might have to add an Application, DoEvents ( ) method right after the call to EnableVisualStyles, This should resolve the problem if icons on toolbars begin to disappear at runtime. Also, EnableVisualStyles is available in .NETFramework 1.1 only.

You have to accomplish one more task pertaining to the controls. Most controls expose the FlatStyle property, which takes a FlatStyle enumeration as its value, This property can take one of four different values:

  1. Flat – Similar to flat,except that when the mouse pointer hovers over the control, it appears in 3D.
  2. Standard – The control appears in 3D.
  3. System – The look of the control is controlled by the operating system.

To enable visual styles, the control’s FlatStyle property should be set to FlatStyle System, The application will now take on the XP look and feel and will support XP themes.

Multiple Document Interface

MDl-type applications are used when you have an application that can show either multiple instances of the same type of form or different forms that must be contained in some way – for example, a text editor that can show multiple edit windows at the same time or Microsoft Access, respectively, You can have query windows, design windows, and table windows all open at the same time, The windows never leave the boundaries of the main Access application.

The project that contains the examples for this chapter is an MDI application, The form mdiParent in the project is the MDl parent form Setting the IsMdiContainer to true will make any form an MDl parent form, If you have the form in the Designer you’ll notice that the background turns a dark gray color. This is to let you know that this is an MDI parent form, You can still add controls to the form, but it is generally not recommended.

For the child forms to behave like MDI children, the child form needs to know what form the parent is, This is done by setting the MdiParent property to the parent form In the example, all children forms are created using the ShowMdiChild method. It takes a reference to the child form that is to be shown, After calling the MdiParent property to this, which is referencing the mdiPllrent form, the form is shown Here is the code for the ShowMdiParent method:

private void ShowMdiChild(Form childForm)
(
childForm.MdiParent = this;
childForm.Show() ;

One of the issues with MOl applications is that there may be several child forms open at any given time, A reference to the current active child can be retrieved by using the Acti veMdiChild property on the parent form. This is demonstrated on the Current Active menu choice on the Window menu, This choice will show a message box with the form’s name and text value.

The child forms can be arranged by calling the LayoutMdi method, The LayoutMdi method takes an MdiLayout enumeration value as a parameter, The possible values include Cascade, TileHorizontal, and TileVertical.

Custom Controls

Using controls and components is a big part of what makes developing with a forms package such as Windows Forms so productive, The ability to create your own controls, components, and user controls makes it even more productive. Bycreating controls, functionality can be encapsulated into packages that can be reused over and over.

You can create a control in a number of ways. Youcan start from scratch, deriving your class from either Control, ScrollableControl, or ContainerControl, You will have to override the Paint event and do all of your drawing, not to mention adding the functionality that your control is suppoeed to provide.

If the control is supposed to be an enhanced version of a current control, the thing to do is to derive from the control that is being enhanced. For example, if a TextBox control is needed that changes background color if the ReadOnly property is set, creating a completely new TextBox control would be a waste of time, Derive from the TextBox control and override the ReadOnly property, Because the ReadOnly property of the TextBox control is not marked override, you have to use the new clause the following code shows the new ReadOnly property:

Three properties were added: ShowFiles, SelectedFolder, and RootFolder, Notice the attributes that have been added. You set Category, Description, and DefaultValues for the ShowFiles and RootFolder, These two properties will appear in the property browser in design mode, The SelectedFolder really has no meaning at design time, so you select the Browsable=false attribute, SelectedFolder does not appear in the property browser, However, because it is a public property, it will appear in IntelliSense and is accessible in code, Next, you have to initialize the loading of the file system, Initializing a control can be tricky, Both design time and runtime initializing must be well thought out, When a control is sitting on a Designer, it is actually running, If there is a call to a database in the constructor, for example, this call will execute when you drop the control on the Designer, In the case of the FolderTree control, this can be an issue.

Here’s a look at the method that is actually going to load the files:

ShowFiles is a Boolean member variable that is set from the ShowFiles property, If true, IDesare also shown in the tree. The only question now is when LoadTree should be called, You have several options.

It can be called when the RootFolder property is set, That is desirable in some situations, but not at design time, Remember that the control is “live” on the Designer, so when the RootNode property is set, the control will attempt to load the file system.

To solve this, check the DesignMode property, which returns true if the control is in the Designer, Now you can write the code to initialize the control:

If the control is not in design mode and _rootFolder is not an empty string. the loading of the tree will begin. The Root node is created first and this is passed into the LoadTree method.

Another option is to implement a public Init method, In the Init method, the call to LoadTree can happen, The problem with this option is that the developer who uses your control is required to make the Init call. Depending on the situation, this might be an acceptable solution.

For added flexibility,implement the ISupportlm. tialize interface. ISupportInitialize has two methods, Begin Init and EndInit, When a control implements ISupportInitialize, the BeginInit and EndIni t methods are called automatically in the generated code in Ini tiali zeComponent.

This allows the initialization process to be delayed until all of the properties are set, ISupportIni tialize allows the code in the parent form to delay initialization as well, the RootNode property is being set in code, a call to Begin Init first will allow the RootNode property as well as other properties to be set or actions to be performed before the control loads the me system, When End Init is called, the control initializes, This is what BeginInit and EndInit code looks like:

In the BeginInit method, all that is done is that a member variable _inInit is set to true, This flag is used to determine if the control is in the initialization process and is used in the RootFolder property, If the RootFolder property is set outside of the InitializeComponent class, the tree will need to be reinitialized, In the RootFolder property you check to see if _inInit is true or false.

If it is true, then you don’t want to go through the initialization process. If inInit is false, you call InitializeTree, You can also have a public Init method and accomplish the same task.

In the EndIni t method, you check to see if the control is in design mode and if _rootFolder has a valid path assigned to it. Only then is Ini tiali zeTree called.

To add’ a final professional-looking touch, you have to add a bitmap image, This is the icon that shows up in the Toolbox when the control is added to a project. The bitmap image should be 16 x 6 pixels and 16 colors, You can create this image file with any graphics editor as long as the size and color depth are set properly. Youcan even create this me in Visual Studio .NET:Right-click the project and select Add New Item, From the list, select Bitmap File to open the graphics editor, After you have created the bitmap me, add it to the project, making sure that it is in the same namespace and has the same name as the control.

Finally, set the Build Action of the bitmap to Embedded Resource: Right-click the bitmap me in the Solution Explorer and select Properties. Select Embedded Resource from the Build Action property.

To test the control, create a TestHarness project in the same solution, The TestHarness is a simple Windows Forms application with a single form, In the references section, add a reference to the FolderTreeCt 1 project, In the Toolbox window, add a reference to the FolderTreeCtl. DLL  FolderTreeCtl should now show up in the toolbox with the bitmap added as the icon, Click the icon and drag it to the TestHarness form, Set the RootFolder to an available folder and run the solution.

This is by no”means a complete control. Several things could be enhanced to make this a full-featured, production-ready control. For example, you could add the following:

  1. Exceptions – If the control tries to load a folder that the user does not have access to, an exception is raised.
  2. Background loading – Loading a large folder tree can take a long time. Enhancing the initialization process to take advantage of a background thread for loading is a good idea.
  3. Color codes – You can make the text of certain file types a different color.
  4. Icons – You can add an ImageList control and add an icon to each file or folder as it is loaded.

User Control

User controls are one of the more powerful features of Windows Forms, They enable you to encapsulate user interface designs into nice reusable packages that can be plugged into project after project, It is not uncommon for an organization to have a couple of libraries of frequently used user controls, Not only can user interface functionality be contained in user controls, but common data validation can be incorporated in them as well, such as formatting phone numbers or ID numbers.,A predefined list of items can be in the user control for fast loading of a list box or combo box, State codes or country codes fit into this category, Incorporating as much functionality that does not depend on the current application as possible into a user control makes the control that much more useful in the organization.

In this section, you create a simple address user control, You also will add the various events that make the control ready for data binding, The address control will have text entry for two address lines: city, state, and zip code.

To create a user control in a current project, just right-click the project in Solution Explorer and select Add; then select Add New User Control, You can also create a new Control Library project and add user controls to it, After a new user control has been started, you will see a form without any borders on the Designer, This is where you drop the controls that make up the user control, Remember that a user control is actually one or more controls added to a container control, so it is somewhat like creating a form, For the address control there are five TextBox controls and three Label controls, The controls can be arranged any way that seems appropriate (see Figure 31-4).

figure 31-4

figure 31-4

The TextBox controls in this example are named as follows:

  1. txtAddress1
  2. txtAdress2
  3. txtCity
  4. txtState
  5. txtZip

After the TextBox controlsare in place and have valid names, add the public properties, You might be tempted to set the visibility of the TextBox controls to public instead of private. However, this is not a good idea because it defeats the purpose of encapsulating the functionality that you might want to add to the properties, The following is a listing of the properties that must be added:

This example uses a simple swi tch statement to determine which text box raised the textChanged.event, Then a check is made to verify that the event is valid and not equal to null, Then the changed event is raised, One thing to note is that an empty EventArgs is sent (EventArgs. Empty), the fact that these events have been added to the properties to support data binding does not mean that is only way to use the control is with data binding. The properties can be set in and ~ad frOmcode without using data binding.

They haye been added so that the user control is able to binding if it is available, This is just one way of making the-user control as flexible as possible so that it might be used in as many 10 situations as possible Because a user control is essentially a control with some added features, all of the,design-time is,uses discussed in-the previous section apply here as well Initializing user controls can bring on the same issues that you saw in the FolderTree example, Care must be taken in the design of controls that you avoid giving access to data stores that might not be available to’other developers using your control.

Also similar to the control creation are the attributes that can be applied to user controls. Th public properties and methods of the user control are displayed in the properties window when thecontrol placed on the Designer. In the example of the address user control it is a good idea to a Category, Description, and Default Value attributes to the address properties, A new AddressData category can be created and the default.values would all be Thee following is an example of these attributes applied to the AddressLinel property:

As you see all that needs to be done to-add a new category is to set the text in the Category attribute the new category is also added.

There is still a lot of room for improvement For example, you,could include a list of state names and abbrevtations in the control Instead of just the state property, the,user control could expose both the state name and state abbreviataion  Exceptionpandling should also_be added.

You could also lines, Making sure that the casing is correct, you might ask yourself whether Address could be optional or whether, apartment and suite numbers should be entered on Address Line2 and not on adressLine1.

Posted on November 2, 2015 in Windows forms

Share the Story

Back to Top