Updating Data Sources
To complete either modifying an existing record or adding a new one, you must call the Update() member of the recordset object.
Before initializing an update of a recordset, you should always ensure that the recordset is open and that the update operation you intend to perform is legal.
A transaction packages a series of database update operations so that original state of that database can be restored in the event of an error.
Exercises
You can download the source code for the examples in the book and the solutions to the following exercises from http://www.wrox.com.
1.Modify the update application in this chapter so that the dialog box for adding a new order always displays the customers in alphabetical order, and the dialog box always displays the first customer each time it is displayed.
2.Modify the example to display the total value of a new order on the view to select products for the order (which corresponds to CPrductView).
3.Extend the example in this chapter to enable the employee to be selected from the records in the Employees table.
4.Extend the example further to allow the shipped via field in an order to be chosen from the records in the Shippers table.
21
Applications Using
Windows Forms
In this chapter, you will learn how you put together the GUI for a Windows Forms application. You will also learn how you support user interaction with the controls that you use. You’ll do this by assembling a single application incrementally throughout the chapter so by the end of the chapter you’ll have a Windows Forms program of a reasonable size.
In this chapter, you’ll learn:
How to build an application GUI interactively using the Form Design capability
How to add controls to a form
How to add event handlers for controls
Understanding Windows Forms
Windows Forms is a facility for creating Windows applications that execute with the CLR. A form is a window that is the basis for an application window or a dialog window to which you can add other controls that the user can interact with. Visual C++ 2005 comes with a standard set of more than 60 controls that you can use with a form. Because there is a very large number of controls, you’ll get to grips only with a representative sample in this book, but that should give you enough of an idea of how they are used to explore the others for yourself. Many of the standard controls provide a straightforward interactive function, such as Button controls that represent buttons to be clicked or TextBox controls that allow text to be entered. Some of the standard controls are containers, which means that they are controls that can contain other controls. For example, a GroupBox control can contain other controls such as Button controls or TextBox controls, and the function of a GroupBox control is simply to group the controls together for some purpose and optionally provide a label for the group in the GUI.
A form and the controls that you use with a form are represented by a C++/CLI class. Each class has a set of properties that determines the behavior and appearance of the control or form. For
Chapter 21
example, whether or not a control is visible in the application window and whether or not a control is enabled to allow user interaction are determined by the property values that are set. You can set a control’s properties interactively when you assemble the GUI using the IDE. You can also set property values at runtime using functions that you add to the program or via code that you add to existing functions through the code Editor pane. The classes also define functions that you call to perform operations on the control.
When you create a project for a Windows Forms application, an application window based on the Form class is created along with all the code to display the application window. After you create a Windows Forms project, there are four distinct operations involved in developing a Windows Forms application:
You create the GUI interactively in the Form Design tab that is displayed in the Editor pane by selecting controls in the Toolbox window and placing them on the form. You can also create additional form windows.
You modify the properties for the controls and the forms to suit your application needs in the Properties window.
You can create click event handlers for a control by double-clicking the control on the Form Design tab. You can also set an existing function as the handler for an event for a control from its Properties window.
You can modify and extend the classes that are created automatically from your interaction with the Form Design tab to meet the needs of your application.
You’ll get a chance to see how it works in practice.
Understanding Windows Forms Applications
You first need to get an idea of how the default code for a Windows Forms application works. Create a new CLR project using the Windows Forms Application template and assign the name Ex21_01 to the project. The Editor pane displays a graphical representation of the application window because with a Windows Forms application you build the GUI graphically. Even double-clicking Form1.h in the Solution Explorer pane does not display the code, but you can see it by right-clicking in the Editor window and selecting View Code from the context menu.
The code defines the Form1 class that represents the application window, and the first thing to note is that the code is defined in its own namespace:
namespace Ex21_01
{
using namespace System;
using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data;
using namespace System::Drawing;
// rest of the code
}
Applications Using Windows Forms
When you compile the project, it creates a new assembly, and the code for this assembly is within the namespace Ex21_01, which is the same as the project name. The namespace ensures that a type in another assembly that has the same name as a type in this assembly is differentiated because each type name is qualified by its own namespace name.
There are also six using directives for .NET library namespaces, and these cover the library functionality you are most likely to need in your application. These namespaces are:
Namespace |
Contents |
|
|
System |
This namespace contains classes that define data types that are |
|
used in all CLR applications. It also contains classes for events |
|
and event handling, exceptions, and classes that support |
|
commonly used functions. |
System::ComponentModel |
This namespace contains classes that support the operation of |
|
GUI components in a CLR application. |
System::Collections |
This namespace contains collection classes for organizing data |
|
in various ways, and includes classes to define lists, queues, |
|
dictionaries (maps), and stacks. |
System::Windows::Forms |
This namespace contains the classes that support the use of |
|
Windows Forms in an application. |
System::Data |
This namespace contains classes that support ADO.NET, which |
|
is used for accessing and updating data sources. You’ll learn |
|
more about accessing data sources in a CLR application in the |
|
next chapter. |
System::Drawing |
Defines classes that support basic graphical operations such as |
|
drawing on a form or a component. |
|
|
The Form1 class is derived from the Form class that is defined in the System::Windows::Forms namespace. The Form class represent a window either an application window or a dialog window, and the Form1 class that defines the window for Ex21_01 inherits all the members of the Form class.
The section at the end of the Form1 class contains the definition of the InitializeComponent() function. This function is called by the constructor to set up the application window and any components that you add to the form. The comments indicate that you must not modify this section of code using the code editor, and this code is updated automatically as you alter the application window interactively. It’s important when you do use Form Design that you do not ignore these comments and modify the automatically generated code yourself; if you do, things are certain to go wrong at some point. Of course, you can write all the code for a Windows Forms application from the ground up, but it is much quicker and less error-prone to use the Form Design capability to set up the GUI for your application interactively. This doesn’t mean you shouldn’t know how it works.
The code for the InitializeComponent() function initially looks like this:
void InitializeComponent(void)
{
this->components = gcnew System::ComponentModel::Container();
Chapter 21
this->Size = System::Drawing::Size(300,300); this->Text = L”Form1”;
this->Padding = System::Windows::Forms::Padding(0); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
}
The components member of the Form1 class is inherited from the base class, and its role is to keep track of components that you subsequently add to the form. The first statement stores a handle to a Container object in components and this object represents a collection that stores GUI components in a list. Each new component that you add to the form using the Form Design capability is added to this Container object.
Modifying the Properties of a Form
The remaining statements in the InitializeComponent() function set properties for Form1. You must not modify any of these directly in the code, but you can choose your own values for these through the Properties window for the form, so return to the Form1.h[Design] tab for the form in the Editor window and right-click it to display the Properties windows shown in Figure 21-1.
Figure 21-1
Applications Using Windows Forms
It’s worth browsing through the list of properties for the form to get an idea of the possibilities. Clicking any of the properties displays a description at the bottom of the window. Figure 21-1 shows the Properties window with the width increased to make the descriptions visible. You can select the cell in the right column to modify the property value. The properties that have a + to the left have multiple values and clicking the + displays the values so you can change them individually. You can also display the properties in alphabetical order by clicking a button. This is helpful when you know the name of the property you want to change, as it makes it easier to find it.
Try changing the Width value for the Size property to 600 and the Height value to 400. You could also change the Text property (which is in the Appearance category) to “A Winning Application”. This changes the text in the title bar for the application window. If you go back to the Form1.h tab in the Editor window, you’ll see that the code in the InitializeComponent() function has been altered to reflect the property changes you have made.
Note that you can also arrange for the application window to be maximized when the program starts by setting the value for the WindowState property. With the default Normal setting, the window is the size you have specified, but you can set the property to Maximized or Minimized by selecting from the list of values for this property.
How the Application Starts
Execution of the application begins, as always, in the main() function, and this is defined in the
Ex21_01.cpp file as:
int main(array<System::String ^> ^args)
{
//Enabling Windows XP visual effects before any controls are created Application::EnableVisualStyles();
//Create the main window and run it
Application::Run(gcnew Form1()); return 0;
}
The main() function calls two static functions that are defined in the Application class that is defined in the System::Windows::Forms namespace. The static functions in the Application class are at the heart of every Windows Forms application. The EnableVisualStyles() function that is called first in main() enables visual styles for the application. The Run() function starts a Windows message loop for the application and makes the Form object that is passed as the argument visible. An application running with the CLR is still ultimately a Windows application, so it works with a message loop in the same way as all other Windows applications.
Customizing the Application GUI
The process of customizing the GUI to suit your application requirements involves adding standard controls and/or additional forms and adjusting their properties. You are going to develop Ex21_01 into a program to generate lottery entries. This provides experience in using a good selection of the controls that are available. The program won’t be an ideal design because it includes controls that duplicate some functions
Chapter 21
perhaps unnecessarily, but the benefit is that you get to try out various possibilities in a working application. I have chosen two lotteries with which I am familiar and for which the program generates entries; if these don’t match the lottery that you favor, you should be able to adjust the example quite easily.
Let me make one point against entering for a lottery — you would probably not choose the numbers 1 to 6 as your entry because it is extremely unlikely that such an entry would win. Of course, the truth is that it’s just as likely as any other more random-looking set of numbers you might choose, but the numbers 1 to 6 have never come up as the winning entry in any lottery anywhere. So you can conclude that whatever you choose — you lose.
To display the controls that are available, first select the Form1.h[Design] tab in the Editor window and then press Ctrl+Alt+X, or select the View > Toolbox menu item. The window containing the list of available controls is displayed as shown in Figure 21-2.
Figure 21-2
The first block in the Toolbox window is labelled All Windows Forms and lists all the controls available for use with a form. You can click the plus sign for All Windows Forms tab if it is not already expanded. You can collapse this block by clicking the minus sign to the left of the block heading, and you’ll see that the controls are also grouped by type in the list starting with the Common Controls block. You’ll probably find it most convenient initially to use the group containing all the controls at the beginning of the list, but after you are familiar with what controls are available, you may find it easier to collapse the groups and just have one group expanded at one time.
Adding Controls to a Form
Add a MenuStrip control to the top of the form by clicking MenuStrip in the Toolbox window and then clicking where you want it to be placed — the top of the client area in the application window. You’ll
see a small arrow at the top left of the control. If you click this, a pop-up window appears, as shown in Figure 21-3.
Applications Using Windows Forms
Figure 21-3
The first item in the MenuStrip Tasks pop-up embeds the menu strip in a ToolStripContainer control that provides panels on all four sides of the form plus a central area in which you can place another control. The second item generates four standard menu items: File Edit, Tools, and Help, complete with menu item lists. You don’t need these in this example but this is a useful instant menu generation capability for many applications; however, adding it has the merit that you get Exit item on the File menu for closing the application. The RenderMode allows you to choose the painting style for the menu strip, and you can leave this at the default selection. The Dock option enables you to choose which side of the form the menu strip is to be docked or you can elect to have it undocked. The GripStyle option determines whether the grip for dragging the menu around is visible or not. The Visual C++ 2005 menu strips have visible grips that allow you to move them around. Selecting the final Edit Items option displays a dialog box in which you can edit the properties for the menu strip or for any of its menu items.
Adding Menus
To add a menu, type the menu text in the box on the menu strip. Add three menu items to the menu strip with the text &Play, &Limits, and &Help. The & precedes the character that is the accelerator character for the menu item so Alt+P is the accelerator for the Play menu. The Editor window containing the form with the menu strip should now look as shown in Figure 21-4.
Figure 21-4
Chapter 21
You can see that the name of the menu strip, menuStrip1, appears below the form window. This is just to make it easy for you to select it — to change properties, for example. The (Name) property for a control is the name of the variable in the code that references the control object so the value for the (Name) property for the MenuStrip control is menuStrip1. For controls such as the MenuStrip control that you won’t want to work with programmatically, you can accept whatever default name has been assigned, but where you will be working with the name in the code, the default name is sometimes rather cumbersome, so you’ll want to change it.
The Play menu won’t have a submenu but causes an event to fire when it is clicked. Because you’ll be handling the event, it is convenient to give the menu item a name that is shorter than the default. You can access the properties by right-clicking the control in the form and selecting Properties from the context menu, but this time try clicking menuStrip1 below the form and select Edit Items from the context menu. It displays the Items Collection Editor dialog box shown in Figure 21-5.
Figure 21-5
If you select the name in the left pane in the dialog box corresponding to the Play menu, the properties for it are displayed in the right pane. You can then edit the (Name) property value. Figure 21-5 shows the dialog box after the change has been made. The advantage of using this dialog box is that you can work through all the items on the menu strip adjusting the properties as necessary. You can also add new items to the menu strip or rearrange the menu sequence.
Adding Submenus
You can add three menu items, Upper, Lower, and Reset, to the Limits menu and an About menu item to the Help menu. You can add new menu items using the Items Collection Editor show in Figure 21-5. You just select the menu (or the menu strip) you want to add to, and click on the Add button. Alternatively you can work through the Editor pane and interact directly with the menu strip. To add the menu items for a menu, click the menu in the menu strip; then click in the menu item below it, and enter the text. The properties for the new menu items need to be modified so display the properties for the Upper menu first of all by right-clicking it and selecting Properties from the pop-up. You will be handling