Developing Microsoft .NET Applications For Windows in Visual C# 2002
Developing Microsoft .NET Applications For Windows in Visual C# 2002
NET ®
(Visual C# .NET). ™
Delivery Guide
Course Number: 2555A
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Contents
Introduction
Course Materials ......................................................................................................2
Prerequisites.............................................................................................................3
Course Outline .........................................................................................................4
Demonstration: Expense Report Application...........................................................6
Demonstration: Purchase Order Application ...........................................................9
Microsoft Certified Professional Program .............................................................15
Facilities.................................................................................................................17
Module 1: Introducing Windows Forms
Overview..................................................................................................................1
Lesson: Creating a Form..........................................................................................2
Lesson: Adding Controls to a Form.......................................................................17
Lesson: Creating an Inherited Form.......................................................................26
Lesson: Organizing Controls on a Form ................................................................35
Lesson: Creating MDI Applications ......................................................................43
Review ...................................................................................................................52
Lab 1.1: Creating Windows Forms ........................................................................54
Module 2: Working with Controls
Overview..................................................................................................................1
Lesson: Creating an Event Handler for a Control....................................................2
Lesson: Using Windows Forms Controls ..............................................................12
Lesson: Using Dialog Boxes in a Windows Forms Application............................33
Lesson: Adding Controls at Run Time ..................................................................43
Lesson: Creating Menus ........................................................................................49
Lesson: Validating User Input ...............................................................................59
Review ...................................................................................................................67
Lab 2.1: Working with Controls ............................................................................69
Module 3: Building Controls
Overview..................................................................................................................1
Lesson: Extending and Creating Controls................................................................2
Lesson: Adding Design-Time Support for Controls ..............................................19
Lesson: Licensing a Control ..................................................................................27
Review ...................................................................................................................38
Lab 3.1: Building Controls ....................................................................................40
Module 4: Using Data in Windows Forms Applications
Overview..................................................................................................................1
Lesson: Adding ADO.NET Objects to and Configuring ADO.NET Objects in a
Windows Forms Application ...................................................................................2
Lesson: Accessing and Modifying Data by Using DataSets..................................14
Lesson: Binding Data to Controls..........................................................................33
Lab 4.1: Accessing Data by Using ADO.NET ......................................................47
Lesson: Overview of XML Web Services .............................................................59
Lesson: Creating a Simple XML Web Services Client..........................................65
Lesson: Persisting Data..........................................................................................72
Lab 4.2: Calling an XML Web Service .................................................................83
Review ...................................................................................................................87
iv Developing Microsoft® .NET Applications for Windows® (Visual C#™ .NET).
Student prerequisites This course requires that students meet the following prerequisites:
Experience with a .NET Framework language such as Visual C# .NET
Microsoft MSDN® Training Course 2609A: Introduction to C#
Programming with Microsoft .NET and Course 2124C: Programming with
C# will help students gain skills in Visual C# .NET programming
techniques and meet the prerequisites for this course.
Experience developing applications
Course objectives After completing this course, the student will be able to:
Create and populate Windows Forms.
Organize controls on Windows Forms.
Create menus in a Windows Forms application.
Add code to form and control event procedures in a Windows Forms
application.
Create Multiple Document Interface (MDI) applications.
Use dialog boxes in Windows Forms applications.
Validate user input in a Windows Forms application.
Create and use user controls in a Windows Forms application.
Create licenses for controls.
Bind Windows Forms applications to various data sources by using
Microsoft ADO.NET.
viii Developing Microsoft® .NET Applications for Windows® (Visual C#™ .NET).
Course Timing
The following schedule is an estimate of the course timing. Your timing may
vary.
Day 1
Start End Module
9:00 9:30 Introduction
9:30 11:00 Module 1: Introducing Windows Forms
11:00 11:10 Break
11:10 11:40 Lab 1.1: Creating Windows Forms
11:40 12:30 Lunch
12:30 2:30 Module 2: Working with Controls
2:30 2:45 Break
2:45 3:15 Lab 2.1: Working with Controls
3:15 4:15 Module 3: Building Controls
4:15 4:45 Lab 3.1: Building Controls
Day 2
Start End Module
8:30 9:00 Day 1 review
9:00 11:00 Module 4: Using Data in Windows Forms Applications
11:00 11:15 Break
11:15 11:45 Module 4: Using Data in Windows Forms Applications
(continued)
11:45 12:30 Lab 4.1: Accessing Data by Using ADO.NET
12:30 1:00 Lunch
1:00 1:30 Module 4: Using Data in Windows Forms Applications
(continued)
1:30 1:45 Lab 4.2: Calling an XML Web Service
1:45 2:00 Break
2:00 3:00 Module 5: Interoperating with Managed Objects
3:00 3:30 Lab 5.1: Interoperating with COM and Calling Win32 APIs
3:30 5:00 Module 6: Printing and Reporting in Windows Forms
Applications
5:00 5:45 Lab 6.1: Printing Formatted Documents
x Developing Microsoft® .NET Applications for Windows® (Visual C#™ .NET).
Day 3
Start End Module
8:30 10:00 Module 7: Asynchronous Programming
10:00 10:15 Lab 7.1: Making Asynchronous Calls to an XML Web Service
10:15 10:30 Break
10:30 11:30 Module 8: Enhancing the Usability of Applications
11:30 12:15 Lunch
12:15 12:45 Lab 8.1: Enhancing the Usability of an Application
12:45 2:45 Module 9: Deploying Windows Forms Applications
2:45 3:00 Break
3:00 3:30 Lab 9.1: Deploying an Application
3:30 4:45 Module 10: Securing Windows Forms Applications
4:45 5:15 Lab 10.1: Adding and Testing Permission Requests
Developing Microsoft® .NET Applications for Windows® (Visual C#™ .NET). xi
Document Conventions
The following conventions are used in course materials to distinguish elements
of the text.
Convention Use
Contents
Introduction 1
Course Materials 2
Prerequisites 3
Course Outline 4
Demonstration: Expense Report Application 6
Demonstration: Purchase Order Application 9
Microsoft Certified Professional Program 15
Facilities 17
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Introduction iii
Instructor Notes
Presentation: The Introduction module provides students with an overview of the course
30 minutes content, materials, and logistics for Course 2555A, Developing Microsoft .NET
Applications for Windows® (Visual C#™ .NET).
Required materials To teach this course, you need the following materials:
Delivery Guide
Trainer Materials compact disc
iv Introduction
Facilities Explain the class hours, extended building hours for labs, parking, restroom
location, meals, phones, message posting, and where smoking is or is not
allowed.
Let students know if your facility has Internet access that is available for them
to use during class breaks.
Also, make sure that the students are aware of the recycling program if one is
available.
Introduction 1
Introduction
Name
Company affiliation
Title/function
Job responsibility
Programming and database experience
Microsoft® Visual C#™ and .NET experience
Expectations for the course
Course Materials
Name card
Student workbook
Student Materials compact disc
Course evaluation
Note To open the Web page, insert the Student Materials compact disc into
the CD-ROM drive, and then in the root directory of the compact disc,
double-click Autorun.exe or Default.htm.
Important There are starter and solution files associated with the labs in
this course. If you perform a default installation, the starter and the solution
files install to C:\Program Files\Msdntrain\2555. However, if you install to a
different location, you must reset the assembly references in the starter and
solution projects.
Prerequisites
-or-
Equivalent knowledge
Course Outline
4. Log on to the application. Specify mario for the user name and P@ssw0rd
for the password.
After the user has successfully logged on, the main control panel form for
the Business application appears.
5. On the View menu, click View Unsubmitted Orders to open the Pending
Orders form.
12 Introduction
The Pending Orders form allows users to view and edit orders that have not
been submitted. Clicking the OrdersOrderDetails link for an order
displays the individual order items of a particular order.
You can navigate from the parent and child tables by using the navigational
controls provided by the datagrid control. Modifications can be made and
are persisted when the Pending Orders form is closed.
In both views, some of the data columns are set to ReadOnly to maintain
data integrity.
6. On the View menu, click Submitted Orders to open the Report History
form.
Introduction 13
This form uses a Crystal Report Viewer to display all order history for a
given employee. Order information is displayed by CustomerName and by
OrderDate. You can also click each order in the report to display order
details.
14 Introduction
7. Show the print features by clicking the PrintPreview button on the toolbar.
Introduction 15
http://www.microsoft.com/traincert/
MCSA on Microsoft The Microsoft Certified Systems Administrator (MCSA) certification is designed for
Windows 2000 professionals who implement, manage, and troubleshoot existing network and system
environments based on Microsoft Windows 2000 platforms, including the Windows
.NET Server family. Implementation responsibilities include installing and configuring
parts of the systems. Management responsibilities include administering and supporting
the systems.
MCSE on Microsoft The Microsoft Certified Systems Engineer (MCSE) credential is the premier
Windows 2000 certification for professionals who analyze the business requirements and design and
implement the infrastructure for business solutions based on the Microsoft
Windows 2000 platform and Microsoft server software, including the Windows .NET
Server family. Implementation responsibilities include installing, configuring, and
troubleshooting network systems.
MCSD The Microsoft Certified Solution Developer (MCSD) credential is the premier
certification for professionals who design and develop leading-edge business solutions
with Microsoft development tools, technologies, platforms, and the Microsoft Windows
DNA architecture. The types of applications MCSDs can develop include desktop
applications and multi-user, Web-based, N-tier, and transaction-based applications. The
credential covers job tasks ranging from analyzing business requirements to maintaining
solutions.
16 Introduction
(continued)
Certification Description
MCDBA on Microsoft The Microsoft Certified Database Administrator (MCDBA) credential is the premier
SQL Server™ 2000 certification for professionals who implement and administer Microsoft SQL Server
databases. The certification is appropriate for individuals who derive physical database
designs, develop logical data models, create physical databases, create data services by
using Transact-SQL, manage and maintain databases, configure and manage security,
monitor and optimize databases, and install and configure SQL Server.
MCP The Microsoft Certified Professional (MCP) credential is for individuals who have the
skills to successfully implement a Microsoft product or technology as part of a business
solution in an organization. Hands-on experience with the product is necessary to
successfully achieve certification.
MCT Microsoft Certified Trainers (MCTs) demonstrate the instructional and technical skills
that qualify them to deliver Microsoft Official Curriculum through Microsoft Certified
Technical Education Centers (Microsoft CTECs).
Certification Requirements
The certification requirements differ for each certification category and are
specific to the products and job functions addressed by the certification. To
become a Microsoft Certified Professional, you must pass rigorous certification
exams that provide a valid and reliable measure of technical proficiency and
expertise.
For More Information See the Microsoft Training and Certification Web site at
http://www.microsoft.com/traincert/.
You can also send e-mail to mcphelp@microsoft.com if you have specific
certification questions.
Facilities
Class hours
Building hours
Parking
Restrooms
Meals
Phones
Messages
Smoking
Recycling
Contents
Overview 1
Lesson: Creating a Form 2
Lesson: Adding Controls to a Form 17
Lesson: Creating an Inherited Form 26
Lesson: Organizing Controls on a Form 35
Lesson: Creating MDI Applications 43
Review 52
Lab 1.1: Creating Windows Forms 54
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 1: Introducing Windows Forms iii
Instructor Notes
Presentation: This module provides students with an overview of using Windows Forms,
90 minutes which is part of the new Microsoft® .NET Framework. Students will create
Windows Forms and set their properties and controls to them. They will create
Lab: inherited forms and also learn how to organize controls on a form. In the
30 minutes module, students also learn how to create Multiple Document Interface (MDI)
applications.
After completing this module, students will be able to:
Create a form and add controls to it.
Create an inherited form by using Visual Inheritance.
Organize controls on a form.
Create MDI applications.
Required materials To teach this module, you need the following materials: Microsoft PowerPoint®
file 2555A_01.ppt.
Overview
Creating a Form
Adding Controls to a Form
Creating an Inherited Form
Organizing Controls on a Form
Creating MDI Applications
Windows Forms vs. Web The following table provides a comparison of different application criteria and
Forms how Windows Forms and Web Forms technologies address these criteria.
Feature/criterion Windows Forms Web Forms
(continued)
Feature/criterion Windows Forms Web Forms
Events
Events Button
Button
Form
Form Name
Name
Categorized
Categorized Button
Button
Alphabetic
Alphabetic Button
Button
Description
Description Pane
Pane
(Name) Sets the name of the form in your Form1 (Form2, Form3,
project. (This is not the name that and so on)
is displayed to the user in the
caption bar but rather the name that
you will use in your code to
reference the form.)
Important: If you change the
(Name) property of your form, you
must set the startup object for your
project to the new name or the
project will not start correctly. For
information about how to change
the startup object, see Form Life
Cycle in this lesson in this module.
AcceptButton Sets which button is clicked when None
the user presses the ENTER key.
Note: You must have at least one
button on your form to use this
property.
CancelButton Sets which button is clicked when None
the user presses the ESC key.
Note: You must have at least one
button on your form to use this
property.
8 Module 1: Introducing Windows Forms
(continued)
Property Description Default setting
Procedure: Setting form You can set form properties either by writing code or by using the Properties
properties window. Any property settings that you establish at design time are used as the
initial settings each time your application runs.
To set form properties at design time:
1. If the Properties window is not open, on the View menu, click Properties
Window.
2. In Design view, click the form for which you want to set a property. The
name of the form appears in the Object list at the top of the Properties
window.
Note When you select a property, a description of the property appears at the
bottom of the Properties window, in the Description pane.
1.
1. Form1
Form1 Show
Show 5.
5. Form2
Form2 Load
Load
7.
7. Form2
Form2 GotFocus
GotFocus
2.
2. Form1
Form1 Load
Load 4.
4. Form2
Form2 Show
Show 8.
8. Form2
Form2 Activated
Activated
3.
3. Form1
Form1 Activated
Activated
6. 9.
9. Focus
Focus shifts
shifts 10.
10. Form2
Form2 LostFocus
LostFocus
6. Form1
Form1 Deactivate
Deactivate
back
back to
to Form1
Form1 11.
11. Form2
Form2 Deactivate
Deactivate
12.
12. Form1
Form1 Activated
Activated
14.
14. Form1
Form1 Deactivate
Deactivate 13.
13. Close
Close Form2
Form2 15.
15. Form2
Form2 GotFocus
GotFocus
21.
21. Form1
Form1 Activated
Activated 16.
16. Form2
Form2 Activated
Activated
24.
24. Form1
Form1 Closing
Closing 17.
17. Form2
Form2 Closing
Closing
23.
23. Exit
Exit
25.
25. Form1
Form1 Closed
Closed Application
Application 18.
18. Form2
Form2 Closed
Closed
26. 19.
19. Form2 LostFocus
Form2 LostFocus
26. Form1
Form1 LostFocus
LostFocus
27. 20.
20. Form2
Form2 Deactivate
Deactivate
27. Form1
Form1 Deactivate
Deactivate
28. 22.
22. Form2
Form2 Disposed
Disposed
28. Form1
Form1 Disposed
Disposed
New The Initialize event is typically used to prepare an application for use.
Variables are assigned to initial values, and controls may be moved or resized
to accommodate initialization data.
In .NET, initialization code must be added to the form constructor after the call
to InitializeComponent() as shown in the following example:
public CalcUI()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// Add your initialization code here
//
}
Show The Show method includes an implied Load; this means that if the specified
form is not already loaded when the Show method is called, the application
automatically loads the form into memory and then displays it to the user. The
Show method can display forms as modal or modeless.
FrmSplash.Show();
You can use the ShowDialog() method to show a form as a dialog box.
Load The Load event is used to perform actions that must occur before the form
displays. It is also used to assign default values to the form and its controls.
The Load event occurs each time that a form is loaded into memory. A form’s
Load event can run multiple times during an application’s life. Load fires when
a form starts as the result of the Load statement, Show statement, or when a
reference is made to an unloaded form’s properties, methods, or controls.
Activated/Deactivate When the user moves among two or more forms, you can use the Activated and
Deactivate events to define the forms’ behaviors. The Activated event occurs
when the form is activated in code or by the user. To activate a form at run time
by using code, call the Activate method. You can use this event for tasks such
as updating the contents of the form based on changes made to the form’s data
when the form was not activated.
The Activated event fires when the form receives focus from another form in
the same project. This event fires only when the form is visible. For example, a
form loaded by using the Load statement isn’t visible unless you use the Show
method, or set the form’s Visible property to True. The Activated event fires
before the GotFocus event.
Use the following code to set the focus to a form.
FrmSplash.Focus();
Module 1: Introducing Windows Forms 11
Deactivate fires when the form loses focus to another form. This event fires
after the LostFocus event.
Both the Activated and Deactivate events fire only when focus is changing
within the same application. If you switch to a different application and then
return to the program, neither event fires.
Important If you need to add code that executes either when the form is being
displayed or when the form is being hidden, add the code to the Activated and
Deactivate event handlers instead of to the GotFocus and LostFocus event
handlers.
Closing The Closing event is useful when you need to know how the user is closing the
form. The Closing event occurs when the form receives a request to close. Data
validation can occur at this time. If there is a need to keep the form open (for
example, if data validation fails), the closing event can be canceled.
Closed The Closed event occurs when the form is closed and before the Dispose event.
Use the Closed event procedure to verify that the form should be closed or to
specify actions that take place when closing the form. You can also include
form-level validation code for closing the form or saving data to a file.
Dispose The .NET framework does not support the Terminate event. Termination code
must execute inside the Dispose method, before the call to base.Dispose().
protected override void Dispose( bool disposing )
{
// Termination code goes here.
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
The Dispose method is called automatically for the main form in an application;
you must call it explicitly for any other form.
Hide The Hide method removes a form from the screen without removing it from
memory. A hidden form’s controls are not accessible to the user, but they are
available to the running application. When a form is hidden, the user cannot
interact with the application until all code in the event procedure that caused the
form to be hidden has finished executing.
If the form is not already loaded into memory when the Hide method is called,
the Hide method loads the form but doesn’t display it.
frmMyForm.Hide();
12 Module 1: Introducing Windows Forms
Events
The .NET Framework uses a standard naming convention for event handlers.
The convention is to combine the name of the object that sends the event, an
underscore, and the name of the event. For example, the Click event of a form
named Form1 would be named Form1_Click.
Procedure To add an event handler:
1. Open the Properties windows for the form for which you want to add an
event handler.
2. Click the Event icon in the Properties window to view the events.
You will learn more about using events and event handlers in the .NET
Framework in Module 2, “Working with Controls” in Course 2555A,
Developing Microsoft .NET Applications for Windows (Visual C# .NET).
Module 1: Introducing Windows Forms 15
}
#endregion
Right-click the
Toolbox
Click Customize
Toolbox
Note The Customize Toolbox dialog box replaces the Customize dialog box
in previous versions of Microsoft Visual C++®.
22 Module 1: Introducing Windows Forms
Note You can add code fragments to the Toolbox by selecting the code
fragment or text and dragging it to the Toolbox. A new entry beginning with
text will appear in the Controls Toolbox.
Module 1: Introducing Windows Forms 23
ControlBox false
Font Trebuchet MS, 10pt
FormBorderStyle Fixed3D
Size 300, 175
Text Hello World
24 Module 1: Introducing Windows Forms
(Name) OutputLabel
BorderStyle Fixed3D
Font Trebuchet MS, 10pt, Bold
ForeColor ActiveCaption
Location 14,30
Size 264, 23
Text (Delete existing text and leave it
blank)
TextAlign MiddleCenter
3. Click Button1.
4. Set the following properties for the Button1 control to the values provided
in the following table.
Property Value
(Name) HelloButton
Location 57, 87
Size 75,25
Text &Say Hello
5. Click Button2.
6. Set the following properties for the Button2 control to the values provided
in the following table.
Property Value
(Name) ExitButton
Location 161, 87
Size 75,25
Text E&xit
Module 1: Introducing Windows Forms 25
7. Double-click the Say Hello button to create the Click event handler.
8. In the Click event handler for HelloButton, add the following line of code:
OutputLabel.Text = "Hello, World!";
9. Switch back to Design view of the form.
10. Double click the Exit button to create the Click event handler.
11. In the Click event handler for ExitButton, add the following line of code:
this.Close();
12. Switch back to Design view of the form.
13. Set the AcceptButton property to HelloButton and the CancelButton
property to ExitButton.
Access Modifiers
How to Create an Inherited Form
Practice: Creating an Inherited Form
Access Modifiers
Access
Access Modifier
Modifier Description
Description
Read-only
Read-only to a child form, all
all of
of its
its
Private
Private property
property values
values in
in the
the property
property
browser
browser are
are disabled
disabled
Accessible
Accessible within
within the
the class
class and
and from
from
Protected
Protected any
any class
class that
that inherits
inherits from
from the
the class
class
that
that declared
declared this
this member
member
Most
Most permissive
permissive level.
level. Public
Public controls
controls
Public
Public
have full accessibility
have full accessibility
The values of the control’s properties are the same as those on the parent object,
and when they are altered on the child form, that property becomes bold in the
Properties window. To reset all values to those held by the parent, right-click
the Properties window, and then click Reset.
Private
A Private control is read-only to a child form. Because a Private control
cannot be modified, all of its property values in the Properties window are
disabled. Copying this control elsewhere on the form or project produces a
fully editable version.
Protected
A protected member is accessible within the class and from any class that
inherits from the class that declared this member. If a change is made to a
Protected control on a child form, then those changes will remain even if a
change is made to the parent form. For the other types of controls, changes
to the parent form will override those made to the child.
Public
Public is the most permissive level. Public controls have full accessibility.
Note The Public, Protected, and Private property values are the three
property values that are common across all the .NET Language projects. C#
supports two other values, Internal and Protected Internal.
Module 1: Introducing Windows Forms 29
public
public class
class Form2
Form2 :: Namespace1.Form1
Namespace1.Form1
Note Make sure that you build the solution before you inherit from an
existing form in the project.
1. On the Project menu, click Add Inherited Form. The dialog box is
identical for C# and for Visual Basic.
2. In the Categories pane, click Local Project Items, and in the Templates
pane, click Inherited Form. In the Name box, type a name, and then click
Open. This will open the Inheritance Picker dialog box.
3. Click Browse, and locate the compiled executable of the project that
contains your form. Click OK.
The new form should now be added into the project and be based on your
inherited form. It contains the controls on the base form.
Module 1: Introducing Windows Forms 31
Important After the new form has been added and has been inherited from the
base form, the project must be rebuilt to complete the inheritance relationship.
The new form can then be displayed in Design view.
32 Module 1: Introducing Windows Forms
When creating complex user interfaces, you may want to layer controls on a
form. To layer controls on a form:
1. Select a control.
2. On the Format menu, point to Order, and then click Bring To Front or
Send To Back.
You can lock all controls on a form. This prevents any accidental moving or
resizing of controls if you are setting other properties for controls. To lock all
controls on a form, on the Format menu, click Lock Controls.
38 Module 1: Introducing Windows Forms
Anchoring
Ensures that the edges of
the control remain in the
same position with
respect to the parent
container
To anchor a control to the
form
Set its Anchor property
Default value: Top, Left
Other Styles: Bottom,
Right
Docking
Enables you to glue the edges of a control to
the edges of its parent control
To dock a control
Set the Dock property
12. While the two option buttons are selected, on the Format menu, click
Vertical spacing, and then click Increase. Perform this step a second time
further to increase the space between the two controls.
13. While the option buttons are selected, on the Format menu, click Center in
Form, and then click Horizontally.
14. While the option buttons are selected, on the Format menu, click Center in
Form, and then click Vertically.
SDI MDI
Displays
Displays multiple
multiple documents
documents
Only
Only one
one document
document is
is visible
visible at
at the
the same
same time
time
You
You must
must close
close one
one Each
Each document
document is
is displayed
displayed
document
document before
before you
you open
open in
in its
its own
own window
window
another
another
Only one document is visible at a time. Several documents are visible at the same time.
Must close one document before opening another. Each document is displayed in its own window.
Example: Microsoft WordPad Example: Microsoft Excel
Scenario: A calendar application (because you may not Scenario: An insurance application in which the user
need more than one instance of a calendar open at a needs to work with multiple application forms.
time).
Module 1: Introducing Windows Forms 45
protected
protected void
void MenuItem2_OnClick(object
MenuItem2_OnClick(object sender,
sender, System.EventArgs
System.EventArgs e)
e)
{{
Form2
Form2 NewMdiChild
NewMdiChild == new
new Form2();
Form2();
//
// Set
Set the
the Parent
Parent Form
Form of
of the
the Child
Child window.
window.
NewMdiChild.MdiParent
NewMdiChild.MdiParent == this;
this;
//
// Display
Display the
the new
new form.
form.
NewMdiChild.Show();
NewMdiChild.Show();
}}
Note When you are setting properties in the Properties window, you can
also set the WindowState property to Maximized. This allows you to easily
manipulate MDI child windows when the parent form is maximized.
MDI child forms are critical for MDI applications because users interact with
the application through child forms.
To create the child form at design time:
• In the same project that contains the parent form, create a new form.
46 Module 1: Introducing Windows Forms
MenuItem1 &File
MenuItem2 &Window
Procedure: Determining When you are completing certain procedures in an application, it is important to
the active child form determine the active form.
Because an MDI application can have many instances of the same child form,
the procedure must know which form to use. To specify the correct form, use
the ActiveMdiChild property, which returns the child form that has the focus
or that was most recently active.
Use the following code to determine the active child form.
Form activeChild = this.ActiveMdiChild;
48 Module 1: Introducing Windows Forms
Procedure: Arranging To arrange child windows on a parent form, you can use the LayoutMdi
child windows on the method with the MdiLayout enumeration to rearrange the child forms in an
parent form MDI parent form.
There are four different MdiLayout enumeration values that can be used by the
LayoutMdi method. These values help you display the form as cascading,
horizontally or vertically tiled, or as child form icons arranged along the lower
portion of the MDI form.
To arrange child forms, in an event, use the LayoutMdi method to set the
MdiLayout enumeration for the MDI parent form.
You can use the following members of the MdiLayout enumeration when
calling the LayoutMdi method of the Form class.
Member Description
11. Click the entry below the Format menu, and set the text to &Toggle
Foreground.
12. Set the Name property of the Toggle Foreground menu item to
ToggleMenuItem.
13. Double-click the Toggle Foreground menu, and add the following code to
the Click event handler:
if (ToggleMenuItem.Checked)
{
ToggleMenuItem.Checked = false;
ChildTextBox.ForeColor = System.Drawing.Color.Black;
}
else
{
ToggleMenuItem.Checked = true;
ChildTextBox.ForeColor = System.Drawing.Color.Blue;
}
Review
Creating a Form
Adding Controls to a Form
Creating an Inherited Form
Organizing Controls on a Form
Creating MDI Applications
5. When creating a form, what class must the form inherit from to make it a
Windows Form?
System.Windows.Forms.Form
7. When creating a form that inherits from a base form, what must be available
to override the base version of the methods of a control on the base form?
The Modifier property of the control on the base form must be set to
either protected or public to override its functionality in the derived
form.
54 Module 1: Introducing Windows Forms
Prerequisites Before working on this lab, you must have the knowledge and skills to develop
a simple Windows Forms application by using a Visual Studio .NET–
compatible programming language.
Scenario The Internal Business Application shell provides a common access point to
various internal business applications. To ensure that the information provided
by the application is viewed by the appropriate user, the application requires a
logon form.
The logon form will prompt the user for his or her user name and password.
The logon form will then attempt to authenticate the user’s credentials to
determine if the user is permitted to access various internal applications.
In this lab, you will add a new form to the Internal Business Application shell
and populate it with controls. You will also implement the Click event handler
for the buttons on the logon form. In addition, you will create the About dialog
box by inheriting a new form from an existing form.
Estimated time to
complete this lab:
30 minutes
Module 1: Introducing Windows Forms 55
Exercise 1
Creating a New Windows Form
In this exercise, you will update the Internal Business Application shell by adding a logon form and
populating it with controls. You will also set form and control properties and implement the Click
event handlers for the buttons on the logon form.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab01_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab01_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in Visual a. For more information about opening a project file
Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab01_1\Ex01\Starter to resource:
find this project. • The Visual Studio .NET Help documentation.
Note: The project will not build until you complete For additional information about opening a
this exercise. project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application from within Designer, in Index,
search by using the phrase Debugging
Windows Applications.
2. Add a new form to the project. Use the form a. For more information about Windows Forms, see
name LoginForm, and use the file name the following resources:
LoginForm.cs. • Practice: Creating a Form in Module 1,
“Introducing Windows Forms,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
This practice contains information about how
to add a new form to a project.
• Lesson: Creating a Form in Module 1,
“Introducing Windows Forms,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
This lesson contains information about how to
create a form.
• The Windows Forms section of the .NET
Framework SDK documentation.
56 Module 1: Introducing Windows Forms
3. Set form properties. Use the following table to set a. For more information about form properties and
the properties of the form. Windows Forms, see the following resources:
Property Value • Practice: Creating a Form in Module 1,
(Name) LoginForm “Introducing Windows Forms,” in Course
ControlBox False 2555A, Developing Microsoft .NET
FormBorderStyle Fixed3D Applications for Windows (Visual C# .NET).
MaximizeBox False This practice contains information about how
MinimizeBox False to set form properties.
Size 322, 210 • Lesson: Creating a Form in Module 1,
Text Internal Business “Introducing Windows Forms,” in Course
Application Logon 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section of the .NET
Framework SDK documentation.
4. Add controls to the form. Add two labels, two a. For more information about adding controls to a
text boxes, and two buttons to the form. form and Windows Forms, see the following
resources:
• Practice: Creating a Form, in Module 1,
“Introducing Windows Forms,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Creating a Form, in Module 1,
“Introducing Windows Forms,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section of the .NET
Framework SDK.
Module 1: Introducing Windows Forms 57
5. Set the control properties. Use the following a. For more information about control properties
tables to set the properties of the controls. and Windows Forms, see the following resources:
Label1 Property Value • Practice: Creating a Form, in Module 1,
(Name) UserNameLabel “Introducing Windows Forms,” in Course
Location 64, 31 2555A, Developing Microsoft .NET
Size 63, 14 Applications for Windows (Visual C# .NET).
Text User name: This practice contains information about how
to set control properties.
6. Set the tab order for the controls on the form. The a. For more information about setting tab order on a
tab order should resemble the following diagram. form and Windows Forms, see the following
resources:
• Lesson: Organizing Controls on a Form, in
Module 1, “Introducing Windows Forms,” in
Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section in the .NET
Framework SDK.
7. Complete the form properties. Use the following a. For more information about setting form
table to set the remaining properties of the form. properties and Windows Forms, see the following
Property Value resources:
11. Implement the Click event handler for the Log Additional information is not necessary for this task.
On button. Open the LoginFormCode.txt file, and
copy the required code under the heading Create
a Click event handler for the Log On button and
add the following code to the event handler.
12. Build and run the application. Specify mario for a. For more information about working with forms
the user name and P@ssw0rd for the password. and Windows Forms, see the following resources:
• Practice: Creating a Form, in Module 1,
“Introducing Windows Forms,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Creating a Form, in Module 1,
“Introducing Windows Forms,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section of the .NET
Framework SDK.
60 Module 1: Introducing Windows Forms
Exercise 2
Inheriting a New Form from an Existing Windows Form
In this exercise, you will update the Internal Business Application shell by adding an About dialog
by inheriting from a generic Windows Form.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab01_1\Ex02\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab01_1\Ex02\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in Visual a. For more information about opening a project file
Studio .NET. Browse to install_folder\Labfiles\ and starting an application, see the following
Lab01_1\Ex02\Starter to find this project. resource:
• The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application from within Designer, in Index,
search by using the phrase Debugging
Windows Applications.
2. Open the BaseAboutForm form in Design view. a. For more information about adding new forms to
a project and Windows Forms, see the following
resources:
• Practice: Creating an Inherited Form, in
Module 1, “Introducing Windows Forms,” in
Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Creating an Inherited Form, in
Module 1, “Introducing Windows Forms,” in
Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section of the .NET
Framework SDK.
Module 1: Introducing Windows Forms 61
3. Use the following table to set the Modifier a. For more information about adding new forms to
property of each control. To set a property for a project and Windows Forms, see the following
multiple controls simultaneously, use the CTRL resources:
key to select the controls. • Practice: Creating an Inherited Form, in
Control Modifier Property Value Module 1, “Introducing Windows Forms,” in
ProductNameLabel protected Course 2555A, Developing Microsoft .NET
VersionNumber protected Applications for Windows (Visual C# .NET).
CopyrightLabel protected • Lesson: Creating an Inherited Form, in
AllRightsReservedLabel protected Module 1, “Introducing Windows Forms,” in
AboutOkButton protected Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section of the .NET
Framework SDK.
4. Save the BaseAboutForm, and build the project. Additional information is not necessary for this task.
5. Add a new form to the project by using the a. For more information about adding new forms to
Inheritance Picker dialog box. Use the form a project and Windows Forms, see the following
name AppControlAboutForm. Inherit the form resources:
from the BaseAboutForm form. Save the new • Practice: Creating an Inherited Form, in
form, and build the project. Module 1, “Introducing Windows Forms,” in
Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Creating an Inherited Form, in
Module 1, “Introducing Windows Forms,” in
Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Windows Forms section of the .NET
Framework SDK.
6. Complete the properties on the a. For more information about working with
AppControlAboutForm form. Use the following inherited forms and Windows Forms, see the
table to set the properties of the form. following resources:
Form Value • Practice: Creating an Inherited Form, in
BackColor Control Module 1, “Introducing Windows Forms,” in
Size 500, 212 Course 2555A, Developing Microsoft .NET
Text About Internal Business Applications for Windows (Visual C# .NET).
Application This practice contains information about how
to set inherited form and control properties.
Use the following table to set the properties of the • Lesson: Creating and Inherited Form, in
controls. Module 1, “Introducing Windows Forms,” in
Course 2555A, Developing Microsoft .NET
Control Property Value Applications for Windows (Visual C# .NET).
ProductNameLabel.Text Internal Business This lesson contains information about how to
Application work with inherited forms.
VersionNumber.Text Version 1.0.3153 • The Windows Forms section of the .NET
CopyrightLabel.Text Copyright © 2002 Framework SDK.
Contoso, Ltd.
62 Module 1: Introducing Windows Forms
7. In AppControlForm, implement click event a. For more detailed information about the tasks that
handler for the About menu item. you must perform, see the TODO comments in
the code.
b. For more information about Windows Forms, see
the following resource:
• The Windows Forms section of the .NET
Framework SDK.
8. Run the application to test the inherited About a. For more information about Windows Forms, see
dialog box. the following resources:
• The Windows Forms section of the .NET
Framework SDK.
Module 2: Working with
Controls
Contents
Overview 1
Lesson: Creating an Event Handler for a
Control 2
Lesson: Using Windows Forms Controls 12
Lesson: Using Dialog Boxes in a Windows
Forms Application 33
Lesson: Adding Controls at Run Time 43
Lesson: Creating Menus 49
Lesson: Validating User Input 59
Review 67
Lab 2.1: Working with Controls 69
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 2: Working with Controls iii
Instructor Notes
Presentation: This module provides students with an overview of using Windows Controls to
120 minutes create Microsoft® .NET Framework Windows Forms applications. In the
module, students will create event handlers for controls and use some of the
Lab: controls in a Windows Forms application. They will also learn how to use
30 minutes dialog boxes and menus in a Windows Forms application. Students will then
create controls at run time and validate user input in an application.
After completing this module, students will be able to:
Create an event handler for a control.
Select and use the appropriate controls in a Windows Forms application.
Use dialog boxes in a Windows Forms application.
Add controls to a form at run time.
Create and use menus in a Windows Forms application.
Validate user input in a Windows Forms application.
Required materials To teach this module, you need Microsoft® PowerPoint® file 2555A_02.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Complete the practices, demonstrations, and lab.
iv Module 2: Working with Controls
Overview
Delegate
Binds events to methods
Can be bound to single or multiple methods
When an event is recorded by an application
The control raises the event by invoking the delegate
for the event
The delegate in turn calls the bound method
public
public delegate
delegate void
void AlarmEventHandler(object
AlarmEventHandler(object
sender,
sender, AlarmEventArgs e);
AlarmEventArgs e);
Event delegates are multicast, which means that they can hold references to
more than one event handling method. Delegates allow for flexibility and fine-
grain control in event handling. A delegate acts as an event dispatcher for the
class that raises the event by maintaining a list of registered event handlers for
the event. For more information on Delegates, see “Delegate Class” in the
Visual Studio .NET Help documentation.
Module 2: Working with Controls 5
}}
*****************************ILLEGAL FOR NON-TRAINER USE******************************
Introduction Functionality is added to controls by raising and consuming events. Before your
application can respond to an event, you must create an event handler. The
event handler (event procedure) contains the program logic that runs when the
event is raised.
Definition An event handler is a method that is bound to an event. When the event is
raised, the code in the event handler runs. You can use the same event handler
to handle more than one event. For example, you can create a single event
handler to handle events of a button and a menu item that are used for the same
purpose. Similarly, if you have a group of RadioButton controls on a form, you
could create a single event handler and have each control’s Click event bound
to the single event handler.
Example of event The following code example is an event handler for the Click event of a button.
handler
private void button1_Click(object sender, System.EventArgs e)
{
}
6 Module 2: Working with Controls
The following code example shows how you can use a single event handler to
handle events for multiple controls.
// inside the Windows Form Designer generated code region
…
this.button1.Click += new
System.EventHandler(this.button1_Click);
Event handler Each event handler provides two parameters that allow you to handle the event
parameters properly.
The first parameter (Sender in the previous code example) provides a
reference to the object that raised the event. It specifies the source that
raised the event.
The second parameter (e in the previous code example) passes an object
specific to the event being handled. This parameter contains all of the data
that is required to handle the event.
Module 2: Working with Controls 7
private
private void
void button1_Click(object
button1_Click(object sender,
sender,
System.EventArgs
System.EventArgs e)
e)
{{
MessageBox.Show("MyHandler
MessageBox.Show("MyHandler received
received the
the event");
event");
}}
}
8 Module 2: Working with Controls
this.button2.Click
this.button2.Click +=
+= new
new
System.EventHandler(this.button1_Click);
System.EventHandler(this.button1_Click);
this.button2.Click
this.button2.Click -=
-= new
new
System.EventHandler(this.button1_Click);
System.EventHandler(this.button1_Click);
}
Module 2: Working with Controls 9
5. What is the purpose of the second parameter (e) that is passed to this event
handler?
The e parameter contains event data. It is either an EventArgs object
(the base class which actually contains no event data) or it is an instance
of a derived class like MouseEventArgs. To see a complete list of the
derived classes, search by using the phrase EventArgs Class in Visual
Studio .NET Help documentation and following the link to 'Derived
classes'.
____________________________________________________________
____________________________________________________________
____________________________________________________________
____________________________________________________________
Text category controls The following text controls are used to enable users to enter text and edit the
text contained in these controls at run time:
Textbox
Displays text entered at design time that can be edited by users at run time,
or changed programmatically.
RichTextBox
Enables text to be displayed with formatting in plain text or rich-text format
(RTF).
The following additional text controls can be used to display text but do not
allow application users to directly edit the text content that they display:
Label
Displays text that users cannot directly edit.
StatusBar
Displays information about the application’s current state by using a framed
window. A status bar is usually located at the bottom of a parent form.
Options category The following selection controls allow users to select a value from a list:
controls
CheckedListBox
Displays a scrollable list of items, each accompanied by a check box.
ComboBox
Displays a drop-down list of items.
DomainUpDown
Displays a list of text items that users can scroll through by using up and
down buttons.
ListBox
Displays a list of text and graphical items (icons).
ListView
Displays items in one of four different views. Views include text only, text
with small icons, text with large icons, and a report view.
NumericUpDown
Displays a list of numerals that users can scroll through by using up and
down buttons.
TreeView
Displays a hierarchical collection of node objects, which can consist of text
with optional check boxes or icons.
Module 2: Working with Controls 15
Containers category Container controls can be used to group other controls on a form. Some
controls examples of container controls are:
Panel
Groups a set of controls on an unlabeled, scrollable frame.
GroupBox
Groups a set of controls (such as radio buttons) on a labeled, nonscrollable
frame.
TabControl
Provides a tabbed page for organizing and accessing grouped objects
efficiently.
Dialog boxes category Visual Studio .NET provides a set of common dialog boxes. These include
controls ColorDialog, FontDialog, PageSetupDialog, PrintDialog, OpenFileDialog,
and so on. You will learn more about dialog boxes in the lesson Using Dialog
Boxes in a Windows Forms Application in this module.
Menus category controls The following are the categories of menu controls:
MainMenu
Provides a design-time interface for creating menus.
ContextMenu
Implements a menu that appears when the user right-clicks an object.
16 Module 2: Working with Controls
Use the Add and Remove buttons to add and remove panels from
the StatusBar control
Click OK to close the dialog box and create the panels you
specified
5. Click OK to close the dialog box and create the panels you specified.
6. In the Properties window, set the ShowPanels property to True.
18 Module 2: Working with Controls
Add other controls to the container control, drawing each inside the
panel
To display scroll bars for the Panel control, set its AutoScrollbar
property to True
Visual Studio .NET includes container controls such as GroupBox and Panel
that allow you to group radio buttons, check boxes, or any other controls that
you want to treat as part of a control collection. The Panel control is similar to
the GroupBox control; however, the Panel control can have scroll bars, and
only the GroupBox control displays a caption.
Procedure: Creating and To create and populate a container control:
populating container
controls 1. Drag a container (Panel or GroupBox) control from the Windows Forms
tab of the Toolbox onto a form.
2. Add other controls to the container control, drawing each inside the panel.
3. If you have existing controls that you want to enclose in the container, drag
them into the container.
4. To display scroll bars for the Panel control, set its AutoScrollbar property
to True.
5. To display a caption on the GroupBox, set its Text property to an
appropriate caption.
Module 2: Working with Controls 21
Procedure: Using the The Windows Forms ImageList control is used to store images, which can then
ImageList be displayed by controls, and is a good example of a control from the graphics
category of controls. For example, you can enable the button to display
different images by changing the ImageIndex property. You can also associate
the same image list with multiple controls. You can use an image list with any
control that has an ImageList property—or, in the case of the ListView control,
the SmallImageList and LargeImageList properties. The controls that can be
associated with an image list include the ListView, TreeView, ToolBar,
TabControl, Button, CheckBox, RadioButton, and Label controls.
To associate the image list with a control, set the control’s ImageList property
to the name of the ImageList control. The key property of the ImageList
control is Images, which contains the pictures to be used by the associated
control. Each individual image can be accessed by its index value. The
ColorDepth property determines the number of colors that the images are
rendered with. The images are all displayed at the same size; this is determined
by the ImageSize property. Images that are larger will be scaled to fit.
Procedure: Triggering If your Windows Forms application features a ToolBar control with buttons,
events for the toolbar you will want to know which button the user clicks. To determine which button
buttons is clicked, add an event handler to the ButtonClick event of ToolBar control.
Use a Select Case statement and the ToolBarButtonClickEventArgs class to
determine the toolbar button that is clicked. The following example shows how
to use the Button property of the ToolBarButtonClickEventArgs object to
determine which button is clicked.
Module 2: Working with Controls 25
Note The following code example uses the Tag property to determine the
control that is clicked, but you can also do this by using the index value of a
control. However, using the index value of controls makes it difficult to keep
track of controls and their corresponding index values. For example, if you have
a separator in your form, the separator will also use an index value, and you
need to take the separator into account when referencing the index value.
}
26 Module 2: Working with Controls
____________________________________________________________
9. Click OK.
12. Click OK, and then save the changes to your application.
13. Run the application. Does anything happen when you click a ToolBar
button? What event must be handled to respond to ToolBar button clicks?
The ButtonClick event of the ToolBar is used to handle ToolBar button
clicks. ToolBarButtonClickEventArgs is used to determine which
button was clicked.
____________________________________________________________
____________________________________________________________
this.StatusBar1.Panels[0].Text = panelText;
7. What are some of the reasons for using the Tag property to determine which
ToolBar button was clicked?
You do not need to update code when the button order changes and you
do not need to consider button separators.
____________________________________________________________
____________________________________________________________
8. Run the application. Test the ToolTips for the ToolBar buttons by
positioning the mouse pointer over a button. Test the ButtonClick event
handler by clicking the ToolBar buttons.
9. If time permits, examine the code used to construct the StatusBar control.
10. Save your project and then close Visual Studio.
30 Module 2: Working with Controls
7. Notice that the mouse pointer changes to indicate that this control will
accept dropped data.
8. With the mouse positioned over the lower-right TextBox control, release the
left mouse button.
9. Close the application.
PrintDialog
PrintDialog Selects
Selects a printer
printer and
and other
other printer-related
printer-related settings
settings
PageSetupDialog
PageSetupDialog Sets
Sets up page details
details for
for printing
printing
Displays
Displays aa document
document as it would appear when it isis
PrintPreviewDialog
PrintPreviewDialog
printed
printed
PrintDialog The PrintDialog control is used to select a printer, choose the pages to print,
and determine other print-related settings in Windows applications. You can
provide users with options such as print all, print a specified page range, or
print a selection.
PageSetupDialog The PageSetupDialog control is used to set page details for printing in
Windows applications. You can enable users to set border and margin
adjustments, headers and footers, and portrait or landscape orientation.
The PageSetupDialog allows users to set properties that relate to either a single
page (PrintDocument class) or any document (PageSettings class).
Additionally, the PageSetupDialog control can be used to determine specific
printer settings, which are stored in the PrinterSettings class.
PrintPreviewDialog The PrintPreviewDialog control is used to display how a document will appear
when printed. The control contains buttons for printing, zooming in, displaying
one or multiple pages, and closing the dialog box.
36 Module 2: Working with Controls
Procedure: Displaying a You can display a message box by using the Show method of the MessageBox
message box class. The Show method requires that you supply the text of the message and
you can optionally specify the following: the dialog box caption, the buttons,
the icon, the default button, and options relating to how the message box and
the text that it contains will display.
public void PerformCalculations()
{
MessageBox.Show ("The search is now complete",
"My Application",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Asterisk);
}
38 Module 2: Working with Controls
DialogResult Property
DialogResult Property
Example
Example
In the Code Editor, navigate to the event handler or the method for
which you want to set the DialogResult property
public
public void
void DisplayValue()
DisplayValue()
{{
DialogResult
DialogResult userResponse
userResponse == openFileDialog1.ShowDialog();
openFileDialog1.ShowDialog();
{{
if
if (userResponse
(userResponse ==
== DialogResult.OK)
DialogResult.OK)
filePath
filePath == openFileDialog1.FileName.ToString();
openFileDialog1.FileName.ToString();
MessageBox.Show("You
MessageBox.Show("You successfully
successfully opened:
opened: '"
'" ++ filePath
filePath
++ "'",
"'", "Success",
"Success", MessageBoxButtons.OK,
MessageBoxButtons.OK,
MessageBoxIcon.Information,MessageBoxDefaultButton.Button1);
MessageBoxIcon.Information,MessageBoxDefaultButton.Button1);
}}
……
}}
____________________________________________________________
____________________________________________________________
Controls Collection
How to Add Controls at Run Time
Practice: Adding and Removing Controls at Run Time
Controls Collection
Controls Collection
Represents a collection of Control objects
Form1.Controls.Remove(textbox1);
Form1.Controls.Remove(textbox1);
Add the control to the container using the Add method of the
Controls property
//
// add
add the
the new
new control
control to
to the
the collection
collection
GroupBox1.Controls.Add(signatureCheckBox);
GroupBox1.Controls.Add(signatureCheckBox);
GroupBox1.Controls.Add(signatureCheckBox);
____________________________________________________________
9. If time permits, open Form1.cs in Design view and perform the following
steps:
a. Drag the Use local dataset when available CheckBox from
GroupBox1 to GroupBox2 and then drag it back to its original position
on GroupBox1.
This is now the last control added to GroupBox1.
b. Run the application and test your code by clicking the radio buttons.
c. Remove Print report automatically from GroupBox1 and then replace
it.
Print report automatically is now the last control in the
ControlCollection of GroupBox1.
d. Test your application again to see that your code now adds controls to
GroupBox1 in the desired locations.
10. Save your project, and then close Visual Studio .NET.
Module 2: Working with Controls 49
Note You can have multiple main menus for an application. If your application
is large, then you could use different menus for different parts of an application.
Lesson objectives After completing this lesson, you will be able to:
Create context menus.
Add menu items at run time.
Create shortcuts for menus.
Enable the checked property for menu items.
50 Module 2: Working with Controls
}}
}
2. Create an instance of the context menu.
Add the code as shown to create an instance of the context menu.
ContextMenu mnuContextMenu = new ContextMenu();
this.ContextMenu = mnuContextMenu;
Module 2: Working with Controls 51
Within the method, set the Text property for each menu item
menuItemNew.Text
menuItemNew.Text == "&New";
"&New";
Note You can add images to menu items. To add images to menu items, create
an instance of the MenuItem class, override the OnPaint() method, and draw
an image to the left of the menu item text.
52 Module 2: Working with Controls
}
2. Write the code to handle the MenuItem.Click event.
private void menuItem1_Click(object sender,
System.EventArgs e)
{
MessageBox.Show("You clicked menuItem1",
"Menu Event");
}
Module 2: Working with Controls 53
Procedure: Displaying You can use the Checked and RadioCheck property to identify the selected
checked menu items menu item in a group of mutually exclusive menu items. You can also place a
check mark on a menu item in a group of items to identify the size of the font to
be displayed for the text in an application.
For example, mutually exclusive items on the View menu in Windows Explorer
use a check or a radio button to show the selected option.
Module 2: Working with Controls 55
Procedure: Enabling and You may want to disable certain menu items for users depending on their roles,
disabling menu items permission, or their input. You can use the Enable property to enable or disable
menu item. If the value of the Enable property is set to True, the menu item is
enabled. However, if the value is set to False, the menu item is disabled.
To enable or disable menu items:
1. Select the menu item.
2. Set the Enabled property to True or False.
56 Module 2: Working with Controls
8. Click the Reports tab, open the File menu, and then open the View menu
again.
9. When would you use more than one MainMenu control in an application?
It can be helpful to use (display) more than one MainMenu object when
the context of your application changes, or when your application has
multiple states.
____________________________________________________________
____________________________________________________________
10. Close the View menu, and then close the application.
____________________________________________________________
____________________________________________________________
____________________________________________________________
CausesValidation The CausesValidation property works with the Validating event to limit when
property a control can lose focus. You can set the CausesValidation property to
determine whether the Validating event will occur on a second control from
which the focus is being shifted. If the Validating event is being handled for a
TextBox, and the user clicks a button that has its CausesValidation property
set to True, the Validating event for the text box will fire. However, if the
CausesValidation property for the button is set to False, the Validating event
will not fire. By default, the CausesValidation property is set to True for all
controls.
Module 2: Working with Controls 61
ErrorProvider Control
ErrorProvider
Displays errors when validating user input on a form
Displays errors within a dataset
Key Properties
DataSource
DataSource ContainerControl
ContainerControl Icon
Icon
Key Method
SetError
SetError
ErrorProvider methods The key method of the ErrorProvider control is the SetError method, which
specifies the control that the error icon should appear next to, and the value of
the error message string.
Module 2: Working with Controls 63
CodeExample
Stop the focus from shifting away from the current control
1. In the Task List, double-click TODO: don’t let the focus shift.
2. Add the following code statement below the TODO line:
e.Cancel = true;
3. Run the application, type 15 and then click Submit Data and Exit.
4. Type 5 and then click Submit Data and Exit.
5. Close the application.
Review
2. In the user interface of a hotel room reservation application, you want to let
users choose a mode of payment (credit, cash, or check). What controls
could you use to create this feature in your application?
There are several ways to provide the user with several options and
restrict them to a single selection. Since there are only three options in
this example, one of the simplest solutions would be to provide three
RadioButton controls on the form. For situations involving a larger
number of options, one of the list controls would be a better choice (for
example, the ListBox control).
4. How can you determine the action taken by a user when the user closes a
dialog box?
The DialogResult property of the parent form is used to capture the
action taken to close a dialog box. For example, DialogResult can be
used to determine whether the OpenFileDialog was closed by clicking
Open or by clicking Cancel.
Note This lab focuses on the concepts in Module 2, “Working with Controls,”
in Course 2555A, Developing Microsoft .NET Applications for Windows
(Visual C# .NET). As a result, this lab may not comply with Microsoft security
recommendations.
Exercise 1
Creating and Using Controls
In this exercise, you will begin by opening an existing Windows Forms application. You will add a
ToolBar control to the main form of the application, add the appropriate number of buttons to the
ToolBar control, and set values for each of the buttons. After the design for the toolbar is complete,
you will develop the code that handles the ButtonClick event of the toolbar and responds
appropriately for each of the different buttons. You will then develop the code statements required
to create an instance of a composite control, associate a context menu with the control, and then add
the control to the control collection of a Panel control that already exists on the form. You will
finish this exercise by creating the event handler for a ContextMenu control, developing the code
that determines which control raised the event, and removing that control from the controls
collection of the Panel control to which it belongs. This exercise assesses your knowledge of events
and event handlers as well as your ability to use Windows Forms controls and ContextMenus at
run time.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab02_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab02_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
Scenario
You have been given the task of adding a toolbar to the Purchase Order application and completing
some code sections that are used to display purchase item data. You have been given the following
table that contains design specification data for the toolbar. You will use this design information to
construct the toolbar and the buttons that it contains.
Item Item property Property value
(continued)
Item Item property Property value
After you have created the toolbar, you will develop code for the ToolBar.ButtonClick event. The
following table identifies the actions that should be taken when each button is clicked.
Toolbar button name Action taken when this button is clicked
RefreshToolBarButton DataRefreshMenuItem.PerformClick()
AddOrderItemToolBarButton NewOrderItemButton.PerformClick()
SaveOrderToolBarButton SaveOrderButton.PerformClick()
PrintPreviewToolBarButton PrintPreview()
SubmitToolBarButton DataSubmitMenuItem.PerformClick()
ViewUnsubmittedToolBarButton ViewUnsubmittedOrdersMenuItem.PerformClick()
ViewSubmittedToolBarButton ViewSubmittedOrdersMenuItem.PerformClick()
Module 2: Working with Controls 73
After the toolbar is complete, you will develop the code to add and remove an instance of a
composite control from the controls collection of a container control (the Panel control,
ProductOrderPanel, has already been added to the main form of the Purchase Order application).
Each composite control represents a single purchase item; together, these purchase items make up a
purchase order. Although users can add a new purchase item by using either
NewOrderItemButton or AddOrderItemToolBarButton, you will add your code to the event
handler for the NewOrderItemButton.Click event. You will add code to this event handler that
creates an instance of the composite control (PurchaseOrder.OrderItemControl), sets the
ContextMenu property of the new control (the context menu is used by the application user to
remove a purchase item from the Panel control), and adds the control to the controls collection. To
finish up this task, you will create an event handler that responds to a context menu click event, and
you will develop the code that removes a purchase item (the purchase item that raised the context
menu click event) from the controls collection of ProductOrderPanel.
1. Open the a. For more information about opening a project file and starting an
Lab02Application.sln file in application, see the following resource:
Visual Studio .NET. The • The Visual Studio .NET Help documentation. For additional
solution file is located in information about opening a project file, in Search, select the
install_folder\Labfiles\ Search in titles only check box, then search by using the phrase
Lab02_1\Ex01\Starter\ Open Project Dialog Box. For additional information about
Lab02Application. starting an application from Designer, search the Index by using the
phrase Debugging Windows Applications.
2. In the Design view, add a a. For more information about the ToolBar control, see the following
ToolBar control to resources:
MainForm.cs. Configure the • Lesson, Using Windows Forms Controls, in Module 2, “Working
toolbar as specified in the with Controls,” in Course 2555A, Developing Microsoft .NET
scenario. Applications for Windows (Visual C# .NET).
• Practice, Creating and Using a ToolBar Control, in Module 2,
“Working with Controls,” in Course 2555A, Developing
Microsoft .NET Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase Introduction to the Windows Forms ToolBar Control.
3. Use the Task List to locate a. For more information about the ToolBar.ButtonClick event and
the code section ‘TODO: determining which button on a toolbar caused the ButtonClick event to
create an event handler for be raised, see the following resources:
the POToolBar.ButtonClick • Lesson, Using Windows Forms Controls, in Module 2, “Working
event’, and then create an with Controls,” in Course 2555A, Developing Microsoft .NET
event handler for the Applications for Windows (Visual C# .NET).
POToolBar.ButtonClick
event. Develop the code that • Practice, Creating and Using a ToolBar Control, in Module 2,
will invoke the appropriate “Working with Controls,” in Course 2555A, Developing
action when a ToolBar Microsoft .NET Applications for Windows (Visual C# .NET).
button is clicked. • The Visual Studio .NET Help documentation. For additional
information about handling the ButtonClick event of a ToolBar
control and to see an example demonstrating a method for
determining which button of a toolbar raised the ButtonClick
event, search by using the phrase ToolBar.ButtonClick Event.
74 Module 2: Working with Controls
4. Run your application to test a. For more information about the purchase order sample application, see
the toolbar and the the following resources:
ButtonClick event handler. • Demonstration, Purchase Order Application, in Module 0,
You can position the mouse “Introduction,” in Course 2555A, Developing Microsoft .NET
over the ToolBar buttons to Applications for Windows (Visual C# .NET).
display ToolTips and click
the buttons to make sure that
your ButtonClick event
handler is working correctly.
5. Use the Task List to locate a. For more information about using a ContextMenu control at run time,
the code section 'TODO: see the following resources:
create a purchase item', and • Lesson, Creating Menus, in Module 2, “Working with Controls,” in
then create an instance of Course 2555A, Developing Microsoft .NET Applications for
the Windows (Visual C# .NET).
PurchaseOrder.OrderItem
Control control named • Practice, Updating Menus at Run Time, in Module 2, “Working
tempProductOrder that with Controls,” in Course 2555A, Developing Microsoft .NET
uses ProductContextMenu Applications for Windows (Visual C# .NET).
as a context menu. • The Visual Studio .NET Help documentation. Search by using the
phrase Adding Context Menus to Windows Forms.
6. Use the Task List to locate a. For more information about adding controls to a control collection, see
the code section 'TODO: the following resources:
add a purchase item to • Lesson, Adding Controls at Run Time, in Module 2, “Working
ProductOrderPanel', and with Controls,” in Course 2555A, Developing Microsoft .NET
then add the new purchase Applications for Windows (Visual C# .NET).
item to the controls
collection of the • Practice, Adding and Removing Controls at Run Time, in Module
ProductOrderPanel 2, “Working with Controls,” in Course 2555A, Developing
control. Microsoft .NET Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase Control.Controls Property.
7. Use the Task List to locate a. For more information about determining which control displayed a
the code section 'TODO: context menu, see the following resources:
determine the index number • Lesson, Creating Menus, in Module 2, “Working with Controls,” in
of the control that will be Course 2555A, Developing Microsoft .NET Applications for
deleted', and then assign the Windows (Visual C# .NET).
index number of the control
that displayed the context • Practice, Updating Menus at Run Time, in Module 2, “Working
menu to a variable named with Controls,” in Course 2555A, Developing Microsoft .NET
currentControlIndex. Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase ContextMenu.SourceControl.
Module 2: Working with Controls 75
8. Use the Task List to locate a. For more information about removing controls from
the code sections 'TODO: ControlCollection, see the following resources:
remove a control from the • Lesson, Adding Controls at Run Time, in Module 2, “Working
middle of the with Controls,” in Course 2555A, Developing Microsoft .NET
ProductOrderPanel control Applications for Windows (Visual C# .NET).
collection' and 'TODO:
remove a control from the • Practice, Adding and Removing Controls at Run Time, in Module
end of the 2, “Working with Controls,” in Course 2555A, Developing
ProductOrderPanel control Microsoft .NET Applications for Windows (Visual C# .NET).
collection' and then, in each • The Visual Studio .NET Help documentation. Search by using the
case, create a code statement phrase Control.ControlCollection.Remove Method.
that will remove the control
that displayed the context
menu from the controls
collection of
ProductOrderPanel.
9. Run your application to test Additional information is not necessary for this task.
the code that you just
created. You should now be
able to add and remove
purchase items from the
controls collection of
ProductOrderPanel.
10. Save your changes, and then Additional information is not necessary for this task.
close Visual Studio .NET.
THIS PAGE INTENTIONALLY LEFT BLANK
Module 3: Building
Controls
Contents
Overview 1
Lesson: Extending and Creating Controls 2
Lesson: Adding Design-Time Support for
Controls 19
Lesson: Licensing a Control 27
Review 38
Lab 3.1: Building Controls 40
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 3: Building Controls iii
Instructor Notes
Presentation: This module provides students with an overview of developing and authoring
60 minutes their own controls. In the module, students will learn about the various options
for authoring controls. Students learn how to extend existing controls and create
Lab: new controls. They also learn how to specify property attributes for controls.
30 minutes Finally, they also learn how to license controls.
After completing this module, students will be able to:
Extend an existing control.
Create a composite control by combining functionality of several existing
Microsoft® .NET Framework Windows Forms controls.
Describe the design-time support options for components provided by
Microsoft Visual Studio® .NET.
Add attributes that provide information to the Visual Designer.
Create and validate licenses for controls.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_03.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Complete the practices, demonstrations, and lab.
iv Module 3: Building Controls
Overview
Component
Standard IComponent Impl
Control
Basic HWND Wrapper
Extended Controls
UserControl
Composite Controls
Extended controls
public
public class
class NumericTextBox
NumericTextBox ::
System.Windows.Forms.TextBox
System.Windows.Forms.TextBox
Composite controls
Controls that are composed of other controls
Designed to act as containers for other controls
Custom controls
CodeExample
Because this control inherits from TextBox, all the members associated with
the TextBox control are exposed in the extended control. For example, you can
use the functionality of the Clear() method of the of TextBox control from the
extended control.
myNumericControl = new NumericTextBox();
myNumericControl.Clear();
4 Module 3: Building Controls
Composite controls Another way of creating your own controls is to combine existing controls to
create composite controls. Create composite controls when you need complex
functionality that requires the use of more than one control.
You can create new controls by using class composition to combine existing
controls. A composite control renders a user interface that reuses the
functionality of existing controls. A composite control can synthesize properties
from the properties of its child controls and handle events raised by its child
controls. It can also expose custom properties and events. All composite
controls derive from System.Windows.Forms.UserControl. There is full
design-time support for creating composite controls with the Visual Studio
.NET Windows Forms Designer.
Composite controls can act as containers for other controls because they extend
the ContainerControl class.
The ContainerControl class defines a logical boundary for controls that it
contains. This class provides focus management, which means that it is aware
of active controls and can change focus from one control to another. It also
supports methods for adding, removing, and retrieving child controls. The
Form class also inherits from the ContainerControl class.
For more information about the ContainerControl class, see
“ContainerControl Class” in the Visual Studio .NET Help documentation.
Custom controls If you do not want to combine or extend existing controls, you have the option
of creating your own custom controls.
Custom controls display user interface (UI) elements by making calls to a GDI+
Graphics object in the OnPaint event. Custom controls are generally derived
from the base class System.Windows.Forms.Control.
public class VerticalLabel : System.Windows.Forms.Control
To create a custom control, you generally inherit from the Control class, which
draws a blank square on your form, override the OnPaint event of the Control
class and use GDI+ to draw your own UI. For more information about using
GDI+ in greater detail, see Module 6, “Printing and Reporting in Windows
Forms Applications,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C#™ .NET).
You can add as well as override properties, methods, and events of the base
class (Control). The base class provides the plumbing required for visual
display in client-side Windows applications. The Control class provides a
window handle, manages message routing, and provides mouse and keyboard
events as well as many other user interface events. It provides advanced layout
and has properties specific to visual display, such as ForeColor, BackColor,
Height, Width, and many others.
Module 3: Building Controls 5
Overriding properties
CodeExample
The following code example shows how to expose the ContextMenu property
of a control contained in a composite control.
public ContextMenu QuantityTextBox_ContextMenu
{
get
{
return QuantityTextBox.ContextMenu;
}
set
{
QuantityTextBox.ContextMenu = value;
}
}
The get and set methods are generally not different from other methods. They
can perform any program logic, throw exceptions, be overridden, and be
declared with any modifiers allowed by the programming language
Procedure: Overriding When you extend an existing control, you can override the properties of the
properties base class to provide custom functionality. The following code overrides the
Text property of the TextBox control and allows only numeric characters to be
set on the property.
public class NumericTextBox : System.Windows.Forms.TextBox
To override events
protected
protected override
override void
void
OnKeyPress(System.Windows.Forms.KeyPress
OnKeyPress(System.Windows.Forms.KeyPress
EventArgs
EventArgs e)
e)
Procedure: Overriding The Control class provides a base set of events that allow you to monitor
an event activities such as property modifications and user actions. When you create
controls, you can access events exposed by the Control class and other base
classes and override them. Each base event provides event-specific information
with the EventArgs parameter. This parameter (and parameters that derive from
it such as KeyEventArgs and MouseEvtsArgs) provides event specific
information, such as which key was pressed or the X,Y position of the mouse
cursor.
Module 3: Building Controls 9
The following code shows how to override an event. The example overrides the
OnKeyPress event of a TextBox control. The event contains a
KeyPressEventArgs parameter that contains data about the keys that were
pressed (e.KeyChar) and a Boolean value (e.Handled) that allows you to
indicate if the event was handled (True) or if the event should be passed to
Windows for processing (False). If the event is handled in the procedure, then it
raises a custom event and passes an instance of the object along with the
KeyPressEventArgs passed to the event.
protected override void
OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
int asciiInteger = Convert.ToInt32(e.KeyChar);
if (asciiInteger >= 47 && asciiInteger <= 57)
{
e.Handled = false;
return;
}
if (asciiInteger == 8)
{
e.Handled = false;
return;
}
e.Handled = true;
if (InvalidUserEntry != null)
InvalidUserEntry(this, e);
}
10 Module 3: Building Controls
Add UserControl to
the Toolbox
UserControl1
Label LocalTimeLabel “”
Timer Timer1 N/A
Note Notice that two new controls are added to the Toolbox: UserControl1,
which was added with the new Windows Control Library project, and
DigitalClock.
If time permits
Test the DigitalClock in separate instances of Visual Studio .NET
1. Open a new instance of Visual Studio .NET.
2. On the File menu, click Add Project, and then click New Project.
3. Create a new Windows application and name it TestClock2.
4. On the Tools menu, click Customize Toolbox.
5. Click the .NET Framework Components tab, and then click Browse.
6. In the Open dialog box, navigate to the DigitalClock.dll located in the \bin
directory of the DigitalClock project, click Open, and then click OK.
7. Add a DigitalClock control to Form1.
18 Module 3: Building Controls
8. Switch back to the Visual Studio .NET instance that includes the
DigitalClock source code and set the BackColor property of
LocalTimeLabel to ControlLightLight.
9. On the Build menu, click Rebuild Solution.
10. Switch back to the Visual Studio instance that includes the TestClock2
project and run it by pressing F5.
The control displays the original value (ControlDark) and not the most
recent one (ControlLightLight). To update the TestClock2 project to use
the most recent DigitalClock control, you must refresh the reference to the
control.
Module 3: Building Controls 19
Property Attributes
Property Attributes
Allow you to specify the behavior of properties at
design time
Property attributes allow you to specify
Grouping options for custom properties in the Properties
window of the Visual Studio .NET environment
Default values
Custom editors for custom properties
Examples of Property Attributes
Browsable Description
Category DefaultProperty
TypeConverter Editor
List of property The following table lists some of the property attributes and their descriptions.
attributes
Property Attributes Description
(continued)
Property Attributes Description
In addition to property attributes, there are some control attributes, such as the
ToolBoxBitMap attribute, that allow you to specify control behavior. The
ToolBoxBitMap allows you to specify a bitmap or icon image to represent a
control in the Toolbox of the Visual Studio .NET IDE.
22 Module 3: Building Controls
using
using System.ComponentModel;
System.ComponentModel;
Custom UI editors
In some situations, a simple value-to-string conversion that allows a
property to be displayed as text in the Properties window might not be
adequate. For instance, in the case of a color property, a visual
representation is more desirable. A UI type editor allows such a
representation and is intended for use with property browsers and other
advanced design-time hosts.
To implement a custom UI type editor for Windows Forms, you define a
class that is derived from System.Drawing.Design.UITypeEditor. You
then apply the Editor attribute to a property to associate the property with
the UI editor.
Custom Designers
Designers are classes that allow you to modify the design-time appearance
and behavior of components and controls. Although the usual goal of any
WYSIWYG form designer is to minimize differences between design-time
and run-time appearance, some special design-time cues are necessary. For
example, a System.Windows.Forms.Panel object might not have a visible
border at run time. However, without a border the panel is invisible to the
developer designing a form that contains the panel. Therefore, the designer
for the System.Windows.Forms.Panel object draws a dotted line border
around the panel.
To create a custom designer, create a class that implements the IDesigner
interface and apply the Designer attribute to the control.
Extenders
Extender providers add properties to other controls. In the .NET
Framework, extender providers do not require any special support. At
design time, extender properties appear in the Properties window as
properties on the objects that they extend, rather than on the actual extender
object.
An example of an extender is the ToolTip control. The ToolTip property is
not available to controls on a form until you add the ToolTip control to the
form.
To create an extender control, create a class that implements the
System.ComponentModel.IExtenderProvider interface.
Note Controls support two modes of behavior, design-time and run-time. You
can use the DesignMode property to determine the behavior mode of a control.
Module 3: Building Controls 25
Note There are two modes of consumption for licensed controls, design-time
and run-time. At design time, a license provider can obtain a valid license from
anywhere, such as a .LIC file from a hard disk or from an XML Web service.
Then at run time for client apps, this license is converted into a license key and
embedded into the executing assembly.
Lesson objectives After completing this lesson, you will be able to:
Describe the files needed for licensing a control.
Enable licensing for a control.
Explain how licensing works in the .NET Framework.
Module 3: Building Controls 29
Files in Licensing
LIC file
Design-time license file that exists anywhere that the
LicenseProvider class specifies
“Namespace.ClassName
“Namespace.ClassName is
is aa licensed
licensed component”
component”
LICX file
Design-time license that resides with the assembly that
consumes a licensed component
“Namespace.ClassName,
“Namespace.ClassName, ClassName,
ClassName, Version,
Version,
Culture,
Culture, PublicKeyToken“
PublicKeyToken“
.Licenses file
Binary run-time license file used at run time
Note If the control is in the same solution project (like when you are
testing it) as the project that is using it, the .LIC file must reside in the
\obj\Debug folder.
30 Module 3: Building Controls
.LICX file
This is a design-time file that resides with the assembly that consumes a
licensed component. It is a text file that resides in the Project folder of an
application. It lists all the licensed components used in an application. The
.LICX file has a specific format as shown below.
“Namespace.ClassName, ClassName, Version, Culture,
PublicKeyToken“
This file is created automatically when you add a licensed component to an
application.
.Licenses file
This is the binary runtime license file used at run time. This file is created
automatically in Visual Studio .NET. It can be generated manually by using
the LC.exe utility. This file resides in the same folder as the built assembly.
Module 3: Building Controls 31
Example The following code is a simple example of licensing a Windows Forms control.
using System;
using System.ComponentModel;
using System.Windows.Forms;
public class MyControl : Control
{
private License license = null;
public MyControl ()
{
license = LicenseManager.Validate(typeof(MyControl),
this);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (license != null)
{
license.Dispose();
license = null;
}
}
base.Dispose(disposing);
}
~MyControl()
{
Dispose();
}
}
34 Module 3: Building Controls
[ToolBoxBitmap(typeof(NumericTextBox),
"NumericTextBox.ico")]
[LicenseProvider(typeof(LicFileLicenseProvider))]
public class NumericTextBox : System.Windows.Forms.TextBox
Module 3: Building Controls 35
When you build the application and run it, the LC.exe utility (license
complier) looks at the .LICX file for a list of licensed classes,
instantiates these classes, extracts the runtime license key, and
embeds the collection of runtime keys in a binary .Licenses file
Review
Extending and Creating Controls
Adding Design-Time Support for Controls
Licensing a Control
Scenario You are a developer in a trading company called Northwind Traders. The
department you work in is developing a purchase order application that will be
used by the Northwind Traders sales force. When developing purchase order
applications that cater to different people, you often write the same code (code
that has the same functionality) for different applications. Instead of writing the
same code repeatedly, you decide to take advantage of component-based
development and develop classes and controls that can be reused in other
applications.
A common task that you perform in applications is writing code that prevents
users from entering non-numeric values in text boxes that display information
such as account balances and telephone numbers. You decide to create a group
of extended controls that inherit from the TextBox class and enforce the
required logic. Some may enforce numeric constraints; others may enforce
string formatting.
In addition, to increase the efficiency of your development time and provide a
consistent interface for the purchase order applications, you decide to create a
custom composite control that includes all the constituent controls required to
display order information.
Estimated time to
complete this lab:
30 minutes
42 Module 3: Building Controls
Exercise 1
Defining an Event and Raising It from an Extended Control
In this exercise, you will define an event for the NumericTextBox control, raise it from the control,
pass event information, and respond to it from a host application.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab03_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab03_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
Scenario
The NumericTextBox control is an extended control that inherits from the TextBox class. The
control accepts only numeric characters and allows the use of the BACKSPACE key. Your users
are complaining because the current version of the control does not provide feedback when an
invalid character is entered. You have been asked to expose an event on the NumericTextBox
control that passes event arguments to host applications when an invalid key is pressed. The host
applications can then display the source and details of the error in the control to the user.
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resources:
NumericTextBox.sln file. • The Visual Studio .NET Help documentation. For additional
To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab03_1\Ex01\Starter\
NumericTextBox.
2. Use the Task List in the a. For more information about creating extended controls and why you
NumericText.cs file to should use them, see the following resources:
locate the code section • Lesson: Extending and Creating Controls in Module 3, “Building
'TODO: 1. Modify the Controls,” in Course 2555A, Developing Microsoft .NET
statement so that the Applications for Windows (Visual C# .NET).
NumericTextBox class
inherits from the • The .NET Framework SDK documentation. For additional
System.Windows.Forms. information about creating extended controls, search by using the
TextBox class. phrase Windows Forms Control Development C#.
3. Use the Task List in the a. For more information declaring an event, see the following resources:
NumericText.cs file to • Lesson: Extending and Creating Controls in Module 3, “Building
locate the code section Controls,” in Course 2555A, Developing Microsoft .NET
'TODO: 2. Declare the Applications for Windows (Visual C# .NET).
InvalidUserEntry event
that passes an Object type • Practice: Creating a Composite Control in Module 3, “Building
and KeyPressEventArgs Controls,” in Course 2555A, Developing Microsoft .NET
event arguments. Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. For additional
information about raising events from custom controls, search by
using the phrase Defining an Event.
Module 3: Building Controls 43
4. Use the Task List in the a. For more information about how to raise an event, see the following
NumericText.cs file to resources:
locate the code section • Lesson: Extending and Creating Controls in Module 3, “Building
'TODO: 3. Raise the Controls,” in Course 2555A, Developing Microsoft .NET
InvalidUserEntry event, Applications for Windows (Visual C# .NET).
passing the current instance
of the NumericTextBox • Practice: Creating a Composite Control in Module 3, “Building
control and the instance of Controls,” in Course 2555A, Developing Microsoft .NET
the KeyPressEventArgs Applications for Windows (Visual C# .NET).
event. • The .NET Framework SDK documentation. For additional
information about raising events from custom controls, search by
The InvalidUserEntry using the phrase Defining an Event.
event will fire every time a
user enters an invalid
character.
5. Rebuild the a. For more information about building your application, see the
NumericTextBox project. following resource:
• The Visual Studio .NET Help documentation. Search by using the
phrase Default and Custom Builds.
6. Add a Windows Application a. For more information about adding a project to an existing solution for
project to the testing, see the following resources:
NumericTextBox solution, • Lesson: Extending and Creating Controls in Module 3, “Building
and name it Test. Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. For help with the code
editor, search by using the phrase Debugging Preparation:
Windows Control Libraries.
7. Open Design view of Form1 a. For more information about customizing the Toolbox, see the
in the Test project, and add following resources:
the NumericTextBox • Code Walkthrough: Creating Controls in Module 3, “Building
control to the Toolbox. Controls,” in Course 2555A, Developing Microsoft .NET
Then, add a Applications for Windows (Visual C# .NET).
NumericTextBox control
from the Toolbox to Form1. • The Visual Studio .NET Help documentation. Search by using the
phrase Using the Toolbox.
Make sure to reference the
version of the control in the
Debug folder.
44 Module 3: Building Controls
8. Add an event handler to a. For more information about creating event handlers, see the following
Form1 for the resources:
NumericTextBox • Lesson: Creating an Event Handler for a Control in Module 2,
InvalidUserEntry event. In “Working with Controls,” in Course 2555A, Developing Microsoft
the event handler, use the .NET Applications for Windows (Visual C# .NET).
KeyPressEventArgs event
arguments to display the • Practice: Creating an Event Handler for a Control in Module 2,
value of the invalid key that “Working with Controls,” in Course 2555A, Developing Microsoft
is pressed in a message box. .NET Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. Search by using the
phrase Consuming Events.
9. Set the Test project as the a. For more information about building and debugging your applications,
Startup Project, rebuild the see the following resource:
project, and then start the • The Visual Studio .NET Help documentation. Search by using the
NumericTextBox solution. phrases Default and Custom Builds and Using the Debugger.
Enter a non-numeric
character in the
NumericTextBox control.
The InvalidUserEntry
event procedure should run
and display a message box
that includes the value of the
invalid key that was pressed.
Module 3: Building Controls 45
Exercise 2
Creating a Composite Control
In this exercise, you will create a composite control by using the Windows Control Library
template and define properties procedures that read, write, and format the properties of constituent
controls. You will then test the composite control in a host application.
Scenario
As a developer at Northwind Traders, you realize that many applications are being built to enable
the sales force to create purchase orders. Rather than create individual controls that offer this
functionality in each application, you decide to create a single composite control that contains all
the controls required to accomplish this task. You decide to first create the composite control and
define all the properties. You will add the data binding code to the control afterward.
The composite control will be called OrderItemControl. The OrderItemControl control includes
four TextBox controls and a ComboBox control that will be used to display the quantity, product
name, price, discount, and quantity/unit of orders.
The following image shows what the OrderItemControl control looks like.
1. Open Visual Studio .NET, a. For more information about creating a project, see the following
create a new Windows resources:
Control Library project, and • Practice: Creating a Composite Control in Module 3, “Building
name it OrderItemControl. Controls,” in Course 2555A, Developing Microsoft .NET
Save the project in Applications for Windows (Visual C# .NET).
install_folder\Labfiles\
Lab03_1\Ex02. • The Visual Studio .NET Help documentation. Search by using the
phrase Adding Projects and Items to the New Application.
2. Add a new UserControl a. For more information about adding new items to a project, see the
component to the following resources:
OrderItemControl project, • Practice: Creating a Composite Control in Module 3, “Building
and name it Controls,” in Course 2555A, Developing Microsoft .NET
OrderItemControl.cs. Applications for Windows (Visual C# .NET).
Delete UserControl1 from
the project. • The Visual Studio .NET Help documentation. Search by using the
phrase Adding Projects and Items to the New Application.
You need to delete the
existing UserControl from
the project or else it will
generate errors.
46 Module 3: Building Controls
3. Add a TextBox control to a. For more information about adding controls to a User Control and
OrderItemControl. Set the configuring properties, see the following resource:
Name property to • The Visual Studio .NET Help documentation. Search by using the
QuantityTextBox. Use the phrases User Control Designer and Setting Properties for
image of the Controls, Documents, and Forms.
OrderItemControl shown in
the illustration to determine
where to place the
QuantityTextBox control.
4. Add a ComboBox to a. For more information about adding controls to a User Control,
OrderItemControl. Set the configuring properties, and setting the Items collection of a
Name to ComboBox, see the following resources:
ProductNameComboBox. • Lesson: Extending and Creating Controls in Module 3, “Building
Set the Items property to A, Controls,” in Course 2555A, Developing Microsoft .NET
B, C—placing each value on Applications for Windows (Visual C# .NET).
a separate line. Use the
image of the • Practice: Creating a Composite Control in Module 3, “Building
OrderItemControl shown in Controls,” in Course 2555A, Developing Microsoft .NET
the illustration to determine Applications for Windows (Visual C# .NET).
where to place • The Visual Studio .NET Help documentation. Search by using the
ProductNameComboBox. phrases User Control Designer, Setting Properties for Controls,
Documents, and Forms and String Collection Editor.
5. Add a TextBox to Additional information is not necessary for this task.
OrderItemControl. Set the
Name to PriceTextBox. Set
the Enabled property to
False. Use the image of the
OrderItemControl shown in
the illustration to determine
where to place
PriceTextBox.
6. Add a TextBox to Additional information is not necessary for this task.
OrderItemControl. Set the
Name to DiscountTextBox.
Use the image of the
OrderItemControl shown in
the illustration to determine
where to place
DiscountTextBox.
7. Add a TextBox to Additional information is not necessary for this task.
OrderItemControl. Set the
Name to
QuantityPerUnitTextBox.
Set the Enabled property to
False. Use the image of the
OrderItemControl shown in
the illustration to determine
where to place
QuantityPerUnitTextBox.
Module 3: Building Controls 47
8. In OrderItemControl, a. For more information about creating property procedures, see the
create a Public property following resources:
named OrderQuantity that • Lesson: Extending and Creating Controls in Module 3, “Building
returns a String and gets Controls,” in Course 2555A, Developing Microsoft .NET
and sets the Text property of Applications for Windows (Visual C# .NET).
QuantityTextBox.
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. Search by using the
phrase Properties Overview.
9. In OrderItemControl, a. For more information about creating property procedures, see the
create a Public property following resources:
named OrderProductName • Lesson: Extending and Creating Controls in Module 3, “Building
that returns a String and Controls,” in Course 2555A, Developing Microsoft .NET
gets and sets the Text Applications for Windows (Visual C# .NET).
property of
ProductNameComboBox. • Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. Search by using the
phrase Properties Overview.
10. In OrderItemControl, a. For more information about creating property procedures and using the
create a Public property Format function, see the following resources:
named OrderPrice that • Lesson: Extending and Creating Controls in Module 3, “Building
returns a String and gets Controls,” in Course 2555A, Developing Microsoft .NET
and sets the Text property of Applications for Windows (Visual C# .NET).
PriceTextBox. In the Set
block, use the Format • Practice: Creating a Composite Control in Module 3, “Building
function to convert Value to Controls,” in Course 2555A, Developing Microsoft .NET
Currency. Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. Search by using the
Using property procedures phrases Properties Overview and Format Function.
gives you greater control
over how properties are set
and retrieved.
11. In OrderItemControl, a. For more information about creating property procedures, see the
create a Public property following resources:
named OrderDiscount that • Lesson: Extending and Creating Controls in Module 3, “Building
returns a String and gets Controls,” in Course 2555A, Developing Microsoft .NET
and sets the Text property of Applications for Windows (Visual C# .NET).
DiscountTextBox.
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. Search by using the
phrase Properties Overview.
48 Module 3: Building Controls
12. In OrderItemControl, a. For more information about creating property procedures, see the
create a Public property following resources:
named • Lesson: Extending and Creating Controls in Module 3, “Building
OrderQuantityPerUnit Controls,” in Course 2555A, Developing Microsoft .NET
that returns a String and Applications for Windows (Visual C# .NET).
gets and sets the Text
property of • Practice: Creating a Composite Control in Module 3, “Building
QuantityPerUnitTextBox. Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase Properties Overview.
13. Add a Windows Application a. For more information about adding a project to an existing solution for
project to the testing, see the following resources:
OrderItemControl solution, • Lesson: Extending and Creating Controls in Module 3, “Building
and name it Test. Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. For help with the code
editor, search by using the phrase Debugging Preparation:
Windows Control Libraries.Control Libraries.
14. Open Design view of Form1 a. For more information about adding user controls from the Toolbox, see
in the Test project, and add the following resources:
an OrderItemControl • Lesson: Extending and Creating Controls in Module 3, “Building
control from the Toolbox. Controls,” in Course 2555A, Developing Microsoft .NET
Resize Form1 to make the Applications for Windows (Visual C# .NET).
control fit.
• Practice: Creating a Composite Control in Module 3, “Building
When you use User Controls Controls,” in Course 2555A, Developing Microsoft .NET
to create composite controls, Applications for Windows (Visual C# .NET).
they are automatically added • The Visual Studio .NET Help documentation. Search by using the
to the Toolbox in the design phrase Using the Toolbox.
time environment of the
solution. When you develop
extended controls and
custom controls, you must
manually add them to the
ToolBox.
Module 3: Building Controls 49
15. Add a Button control to a. For more information about creating event handlers, see the following
Form1, accept the default resources:
name, and in the Click event • Lesson: Creating an Event Handler for a Control in Module 2,
procedure, perform the “Working with Controls,” in Course 2555A, Developing
following steps: Microsoft .NET Applications for Windows (Visual C# .NET).
• Assign the • Practice: Creating an Event Handler for a Control in Module 2,
OrderItemProduct “Working with Controls,” in Course 2555A, Developing
Name property of the Microsoft .NET Applications for Windows (Visual C# .NET).
OrderItemControl
control to the • The .NET Framework SDK documentation. Search by using the
OrderItemQuantity phrase Consuming Events.
property.
• Assign the
OrderDiscount
property of the
OrderItemControl
control to the
OrderPrice property.
• Assign the
OrderDiscount
property of the
OrderItemControl
control to the
OrderQuantityPerUnit
property.
Exercise 3
Adding Design-Time Support
In this exercise, you will add attributes to properties of the OrderItemControl control. You will
then test the design-time support features that you added.
Scenario
As the developer of the OrderItemControl, you do not know how developers will use it and the kind
of support that they will require to be able to use the control. You decide to add some design-time
support to the control to enable other developers to use the control easily. You will add description
and category information to the properties that you created in the previous exercise so that it is easy
for other developers to understand the function of each property.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab03_1\Ex03\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab03_1\Ex03\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open Visual Studio .NET, a. For more information about opening a project file and starting an
and open the application, see the following resource:
OrderItemControl.sln file. • The Visual Studio .NET Help documentation. For additional
To open the solution files, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab03_1\Ex03\Starter\
OrderItemControl.
2. Add Category and a. For more information about adding design-time support to control
Description attributes to properties, see the following resources:
each property of the • Lesson: Adding Design-Time Support for Controls in Module 3,
OrderItemControl. Use “Building Controls,” in Course 2555A, Developing Microsoft .NET
OrderItemControl as the Applications for Windows (Visual C# .NET).
Category.
• Practice: Adding Design-Time Support for Controls in Module 3,
“Building Controls,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase Attributes and Design-Time Support.
Module 3: Building Controls 51
3. Build the OrderItemControl a. For more information about building and debugging your applications,
project. Add a Windows see the following resource:
Application project to the • The Visual Studio .NET Help documentation. Search by using the
OrderItemControl solution, phrases Default and Custom Builds and Using the Debugger.
and name it Test. Add an
OrderItemControl from the
ToolBox, and view the
custom properties in the
Properties window. Make
sure to enable the
Categorized button so that
you can see how your
control properties are sorted.
THIS PAGE INTENTIONALLY LEFT BLANK
Module 4: Using Data in
Windows Forms
Applications
Contents
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 4: Using Data in Windows Forms Applications iii
Instructor Notes
Presentation: The module provides an overview of how to use data in a Windows Forms
180 minutes application. Windows Forms are a part of the new Microsoft® .NET
Framework. The module explains how to use the Microsoft ADO.NET object to
Labs: access, display, and update data from a database. In this module, students also
60 minutes learn how to create and test a simple XML Web service client application and
how to persist application settings.
After completing this module, students will be able to:
Describe the objects in the ADO.NET object model.
Add and configure ADO.NET objects in a Windows Forms application.
Access and modify data from a database by using DataSets.
Bind data to controls.
Describe the XML Web services model and the roles of HTML, Simple
Object Access Protocol (SOAP), and XML in the Web services model.
Create and test a simple XML Web service client application.
Persist data to files, serialize objects, use isolated storage, and persist
application settings.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_04.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Review the animation for this module.
Complete the demonstrations, practices, and labs.
iv Module 4: Using Data in Windows Forms Applications
Overview
ADO.NET Objects
DataSet
DataAdapter Data Source
DataTable
SelectCommand
SelectCommand
Fill
Fill
Update
Update Connection
Connection
UpdateCommand
UpdateCommand
DataAdapter
DataTable
SelectCommand
SelectCommand
Fill
Fill
Update
Update
UpdateCommand
UpdateCommand
Command object You can use Command objects to access data directly in the database in a
connected environment. Command objects use SQL statements or stored
procedures to retrieve data. Commands travel across connections, and result
sets are returned in the form of streams that can be read by DataReaders or
pushed into DataSet objects. Command objects contain a Parameters
collection that populates the input and output arguments of SQL statements or
stored procedures. For example, if you have a SQL statement that returns all of
the rows in the Orders table where the EmployeeID is equal to a value
determined at run time, you add the value EmployeeID to the Parameters
collection of the Command object.
A Command object contains a reference to a SQL statement or stored
procedure that you can execute directly. The two Command classes are
described in the following table.
Command class Description
DataReader object The DataReader is a fast, forward-only cursor that loops through a stream of
rows. When you execute a Command object that returns a set of rows, you use
a DataReader to loop through the set of rows. You can use a Command object
and the ExecuteReader method to return a DataReader. You can execute any
SELECT statement or a stored procedure that contains a SELECT statement.
The DataReader provides strongly typed methods to get the value of a specific
column in the current row. You can also obtain metadata about the rows, such
as the column name and the column data type.
When you process a result set with a DataReader, the associated connection is
kept busy until you close the DataReader. For this reason, you should close the
DataReader as soon as you finish processing the result set.
DataSet object Datasets store data in a disconnected cache. The structure of a dataset is similar
to that of a relational database; it exposes a hierarchical object model of tables,
rows, and columns. In addition, it contains constraints and relationships defined
for the dataset.
Module 4: Using Data in Windows Forms Applications 5
DataAdapter object The DataSet object represents a local copy of data from a data source and is
one of the key innovations of the Microsoft .NET Framework. By itself, the
DataSet object is useful for reference. However, to serve as a true data-
management tool, a DataSet must be able to interact with a data source. To
accomplish this, the .NET Framework provides the DataAdapter class. A
DataAdapter object serves as a bridge between a DataSet and a data source for
retrieving and saving data. The DataAdapter class represents a set of database
commands and a database connection that you use to fill a DataSet and update
the data source. DataAdapter objects are part of the Microsoft ADO.NET data
providers, which also include connection objects, data-reader objects, and
command objects. Microsoft Visual Studio® .NET makes two primary
DataAdapters available for use with databases. In addition, other
DataAdapters can be integrated with Visual Studio. The primary
DataDdapters are:
OleDbDataAdapter, which is suitable for use with any data source that is
exposed by an OLE DB provider.
SqlDataAdapter, which is specific to a SQL Server version 7.0 or later
database. The SqlDataAdapter is faster than the OleDbDataAdapter
because it works directly with SQL Server and does not go through an OLE
DB layer.
6 Module 4: Using Data in Windows Forms Applications
What Is a DataSet?
DataRow
DataTable
DataRelation
Tables in a DataSet The DataSet class has a Tables property that gets a collection of DataTable
objects in the DataSet, and a Relations property that gets a collection of the
DataRelation objects in the DataSet.
A DataTable object contains several collections that describe the data in the
table and cache the data in memory. The following table describes the most
important collections.
Type of object
Collection name in collection Description of object in collection
Typed datasets
Derive from the base DataSet class
Provide type checking at compile time
Provide faster access to tables and columns in the dataset
Generated from XML Schema (.xsd) files by using the
XSD.exe tool
To access tables and columns
Untyped dataset
PubsDataSet.Tables(""Titles
PubsDataSet.Tables( Titles"");
);
Typed dataset
PubsDataSet.Titles;
PubsDataSet.Titles;
However, with a typed dataset, you can directly access the Titles table by using
the following code:
PubsDataSet.Titles;
Advantages of typed Typed datasets are not only easier to read, but they are also fully supported by
datasets the Microsoft IntelliSense® technology in the Code Editor in
Visual Studio .NET. In addition to being easier to work with, the syntax for the
typed dataset provides type checking at compile time; this greatly reduces the
possibility of errors in assigning values to dataset members. Access to tables
and columns in a typed dataset is also slightly faster at run time because access
is determined at compile time—not through collections at run time.
You can generate a strongly typed dataset from within the Visual Studio .NET
integrated development environment (IDE) by selecting tables from an existing
database or by creating one using the XML Designer.
Module 4: Using Data in Windows Forms Applications 9
Select New and then specify a name for the new dataset
Note When you use data design tools, you need not create explicit connections
to a data source; however, there are times when you need to create just a
connection. For more information about how to create a connection, in the
Visual Studio .NET documentation, search by using the phase Creating
ADO.NET Connection Objects.
10 Module 4: Using Data in Windows Forms Applications
Procedure: Adding Data Adapter Configuration Wizard helps you set the properties of a new or
ADO.NET objects existing data adapter. A data adapter contains SQL commands or stored
procedures that your application can use to read data into a dataset from a
database and write it back again. The wizard can also create a data connection
that allows the adapter to communicate with a database.
To use DataAdapter Configuration Wizard:
1. Drag an OleDbDataAdapter or SqlDataAdapter object from the Toolbox
onto a form or component.
2. Specify connection and SQL command information.
The wizard displays several dialog boxes:
• If you ask to create a connection, the wizard displays the Connection
tab of the Data Link Properties dialog box, which allows you to
specify a provider, server name, database name, user name, and
password for the connection.
• To help you create SQL statements, the wizard provides the Query
Builder, a utility that allows you to create and test a Select statement by
using visual tools. To launch it, click the Query Builder button when
asked for a SQL statement.
3. In Component Designer, select the adapter or adapters that will transfer data
between the data source and the dataset.
Typically, each data adapter accesses data in a single table. Therefore, to
create a dataset that contains multiple data tables, select all the adapters for
the tables that you want to work with.
4. On the Data menu, choose Generate Dataset.
The Generate DataSet dialog box appears.
5. Click New, and then specify a name for the new dataset. If you want to add
the dataset to your form or component, click Add an instance of this
DataSet to the designer.
This generates a typed dataset.
Module 4: Using Data in Windows Forms Applications 11
Passing parameters to It is often necessary to pass parameters to a SQL statement. For example, when
SELECT statements accessing rows from a data source, you use the SELECT statement, which uses
a unique identifier to identify the rows to be accessed. The unique identifier is
commonly the value of a primary key field. The SELECT statement uses
parameters that contain the unique identifier, and the columns and values to be
updated, as shown in the following SQL statement:
SELECT stor_id, ord_num, qty, ord_date, payterms, title_id
FROM sales WHERE (stor_id = @stor_id)
In the previous example, the stor_id field must be populated with a value from
the @stor_id parameter for the SQL statement to return results.
16 Module 4: Using Data in Windows Forms Applications
A Parameter object holds the input and output parameters of SQL statement
and stored procedures. The Parameters collection of a Command object is
where you add the required arguments of SQL statements or stored procedures.
There are a variety of ways to add Parameter objects to the Parameters
collection. The following code uses the SelectCommand property to access a
Command object and then assigns the value of stor_id to the Value property of
the Parameter object in the Parameters collection that is identified by
@stor_id:
salesSqlDataAdapter.SelectCommand.Parameters["@stor_id"].Value
= stor_id;
After all the arguments for a SQL statement or stored procedure are defined in
Parameter objects, you can call the Fill method of the DataAdapter to get the
results.
salesSqlDataAdapter.Fill(StoreSalesDataSet1.sales);
Module 4: Using Data in Windows Forms Applications 17
Editing rows
changeDataRow.BeginEdit(
changeDataRow.BeginEdit( );
);
changeDataRow["Title"]
changeDataRow["Title"] == changeDataRow["Title"].ToString()
changeDataRow["Title"].ToString()
++ "" 1";
1";
changeDataRow.EndEdit(
changeDataRow.EndEdit( );
);
Deleting data
DataRow
DataRow deleteDataRow
deleteDataRow ==
pubsDataSet.Tables["Titles"].Rows[0];
pubsDataSet.Tables["Titles"].Rows[0];
pubsDataSet.Tables["Titles"].Rows.Remove(deleteDataRow);
pubsDataSet.Tables["Titles"].Rows.Remove(deleteDataRow);
Procedure: Deleting data Use either of the following methods to delete a row:
in a dataset
Remove method
Call the Remove method of the DataRows collection. This permanently
removes the row from the dataset.
Delete method
Call the Delete method of the DataRow object. This only marks the row for
deletion in the dataset, and calling RejectChanges will undo the deletion.
The following code shows how to delete an existing row from a dataset:
DataRow deleteDataRow =
pubsDataSet.Tables["Titles"].Rows[0];
pubsDataSet.Tables["Titles"].Rows.Remove(deleteDataRow);
Module 4: Using Data in Windows Forms Applications 19
SqlCommand
SqlCommand insertTitlesCommand
insertTitlesCommand == new
new SqlCommand
SqlCommand
("Insert
("Insert titles
titles (title_id,
(title_id, title,
title, type)
type)
values
values (@title_id,@title,@type)");
(@title_id,@title,@type)");
insertTitlesCommand.Parameters.Add
insertTitlesCommand.Parameters.Add
("@title_id",
("@title_id", SqlDbType.VarChar,
SqlDbType.VarChar, 6,
6, "title_id");
"title_id");
insertTitlesCommand.Parameters.Add
insertTitlesCommand.Parameters.Add
("@title",
("@title", SqlDbType.VarChar,
SqlDbType.VarChar, 80,
80, "title");
"title");
insertTitlesCommand.Parameters.Add
insertTitlesCommand.Parameters.Add
("@type",
("@type", SqlDbType.Char,
SqlDbType.Char, 12,
12, "type");
"type");
titlesSQLDataAdapter.InsertCommand
titlesSQLDataAdapter.InsertCommand == insertTitlesCommand;
insertTitlesCommand;
titlesSQLDataAdapter.Update(pubsDataSet,
titlesSQLDataAdapter.Update(pubsDataSet, "titles");
"titles");
The following code shows how to use the InsertCommand property to add a
row to the Titles table in the pubs database:
SqlCommand insertTitlesCommand = new SqlCommand
("Insert titles (title_id, title, type) values
(@title_id,@title,@type)");
insertTitlesCommand.Parameters.Add
("@title_id", SqlDbType.VarChar, 6, "title_id");
insertTitlesCommand.Parameters.Add
("@title", SqlDbType.VarChar, 80, "title");
insertTitlesCommand.Parameters.Add
("@type", SqlDbType.Char, 12, "type");
titlesSQLDataAdapter.InsertCommand = insertTitlesCommand;
titlesSQLDataAdapter.Update(pubsDataSet, "titles");
Module 4: Using Data in Windows Forms Applications 21
You must assign the @stor_ID parameter a value to get the required results.
You use the Parameters collection of the SQLCommand object to assign this
value.
1. Locate TODO: 4 in the Code Editor of Form1.
2. Under TODO: 4, use the SelectCommand property of
SalesSqlDataAdapter to access SalesSQLSelectCommand and set the
Value property of the @storeid parameter in the Parameters collection to
storeID. Your code should look like this:
SalesSQLDataAdapter.SelectCommand.Parameters["@stor_id"].
Value = storeID;
3. Locate TODO: 5 in the Code Editor of Form1.
4. Under TODO: 5, use the Clear method of Sales DataTable in
StoreSalesDataSet1 to clear the Sales table of any existing data. Your code
should look like this:
StoreSalesDataSet1.sales.Clear();
5. Locate TODO: 6 in the Code Editor of Form1.
6. Under TODO: 6, use the Fill method of SalesSQLDataAdapter to populate
the sales property of StoreSalesDataSet1. Your code should look like this:
SalesSqlDataAdapter.Fill(StoreSalesDataSet1.sales);
Tip You may want to set breakpoints in your code to follow the execution
path.
24 Module 4: Using Data in Windows Forms Applications
3. Click the bottom row of the DataGrid to create a new row, and enter the
following fields.
Note The date in the following table is in the mm/dd/yy format for the
purposes of practicing the concepts learned in the lesson. However, when
you create an application for an international audience, you should use a
different method of capturing the date - like a pop-up calendar to select the
date, or three individual list boxes: for the month, day, and year.
Field Value
stor_id 7067
ord_num P2122
qty 12
ord_date 6/13/2002
payterms Net 60
title_id PC9999
4. Click Update.
5. Switch to the Visual Studio .NET IDE, and use Server Explorer to verify
that the database was updated.
6. Switch back to the Store Orders application, set the qty field of the new row
to 24, and then click Update.
7. Switch to the Visual Studio .NET IDE, and use Server Explorer to verify
that the database was updated.
8. To refresh the view, right-click the results, and then click Run.
9. Switch back to the Store Orders application, delete the new row, and then
click Update.
10. Switch to the Visual Studio .NET IDE, and use Server Explorer to verify
that the database was updated.
Module 4: Using Data in Windows Forms Applications 25
Test the behavior of the dataset and notice that a relation exists
1. Press F5 to compile and run the application.
2. Notice that the first row of the Products DataGrid displays the product Chai,
which has a SupplierID of 1.
3. Select the first row in the Suppliers DataGrid (where SupplierID = 1), and
press DELETE.
Because the DataRelation exists, the dataset cascades the deletion of all the
products that are associated with the Supplier parent and maintains referential
integrity.
Module 4: Using Data in Windows Forms Applications 29
Use the XmlReadMode parameter to specify what the XML file contains and
what information should be loaded from the file. This parameter is optional. If
no XmlReadMode value is supplied, the default value Auto is used.
30 Module 4: Using Data in Windows Forms Applications
XmlReadMode The following table shows the values for the XmlReadMode parameter of the
parameter values ReadXml method of the DataSet object.
XmlReadMode value Description
ReadSchema Reads any inline schema and then loads the schema and
data:
If the dataset already contains a schema, any new
tables that are defined by an inline schema are added
to the dataset.
If the inline schema defines a table that is already in
the dataset, an exception is thrown.
If the dataset does not contain a schema, and there is
no inline schema, no data is read.
IgnoreSchema Ignores any inline schema and loads data into the existing
dataset. Any data that does not match the existing schema
is discarded.
InferSchema Ignores any inline schema and infers a new schema based
on the structure of the XML data. If the dataset already
defines a schema, tables are added to this schema.
The data is then loaded into the dataset.
DiffGram Reads a DiffGram and adds the data to the current schema
in the dataset. A DiffGram is an XML format that is used
to identify current and original versions of data elements.
Fragment Reads XML fragments and appends data to appropriate
dataset tables. This setting is typically used to read XML
data generated directly from SQL Server.
Auto Examines the XML file and chooses the most appropriate
option.
If the dataset contains a schema or the XML contains
an inline schema, ReadSchema is used.
If the dataset does not contain a schema and the XML
does not contain an inline schema, InferSchema is
used.
For best performance, specify an XmlReadMode rather
than Auto.
Module 4: Using Data in Windows Forms Applications 31
Example of loading a The following example first loads a schema into a new dataset by using the
schema and data into a ReadXmlSchema method and then loads the data from an XML file by using
dataset the ReadXml method with the IgnoreSchema option of the XmlReadMode
parameter:
private void ReadXmlDataOnly()
{
try
{
DataSet purchaseDataSet = new DataSet();
Console.WriteLine("Reading the Schema file");
purchaseDataSet.ReadXmlSchema
("C:\\sampledata\\PurchaseData.xsd");
Console.WriteLine("Loading the XML data file");
purchaseDataSet.ReadXml
("C:\\sampledata\\PurchaseData.xml",
XmlReadMode.IgnoreSchema);
dataGrid1.DataSource = purchaseDataSet.Tables[0];
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.ToString());
}
}
Partial syntax for writing The following code shows partial syntax for the WriteXml method of the
to an XML file DataSet object:
Overloads Public Sub WriteXml (ByVal filename As String |
stream As Stream | writer as TextWriter | writer as XmlWriter,
{ByVal mode As XmlWriteMode})
XmlWriteMode values When you use the WriteXml method, you can specify an optional value for the
XmlWriteMode parameter. This parameter specifies whether to generate a file
that contains only XML data, XML data with an inline XSD schema, or a
DiffGram.
The following table describes the different values for the XmlWriteMode
parameter of the WriteXml method of the DataSet object.
XmlWriteMode value What is generated
Example of writing XML The following code saves the data stored in a dataset as an XML file but does
data to a file not write any schema information:
private void SaveXMLDataOnly()
{
try
{
DataSet purchaseDataSet = new DataSet();
//Load an inline schema and data from an XML file
purchaseDataSet.ReadXml
("C:\\sampledata\\PurchaseOrder.xml",
XmlReadMode.ReadSchema);
//Save the data portion of the DataSet to a file
purchaseDataSet.WriteXml
("C:\\sampledata\\CurrentOrders.xml",
XmlWriteMode.IgnoreSchema);
}
catch (Exception exp)
{
Console.WriteLine("Exception: " + exp.ToString());
}
}
Module 4: Using Data in Windows Forms Applications 33
Property
Property of
of the
the control
control to
to
which
which data
data is
is bound
bound
txtCustomerAddress.DataBindings.Add("Text",
txtCustomerAddress.DataBindings.Add("Text",
dsNorthwindData1.Customers,
dsNorthwindData1.Customers, "Address");
"Address");
txtCustomerCity.DataBindings.Add("Text",
txtCustomerCity.DataBindings.Add("Text",
dsNorthwindData1.Customers,
dsNorthwindData1.Customers, "City");
"City");
Table
Table from
from the
the data
data source
source Column
Column in
in the
the table
table
5. Expand the data source that you want to bind to until you find the single
data element that you want.
For example, if you are binding to a column value in a dataset’s table,
expand the name of the dataset, and then expand the table name to display
column names.
6. Click the name of an element to bind to it.
Procedure: Performing You can also create a Binding object programmatically at run time. To do so,
simple binding at run use the Add method of the DataBindings collection. The method expects the
time following arguments:
Name of the property of the control that will consume the data
Data source
Name of the field in the data source to bind to
The following code binds the Text property of the txtCustomer text box to the
Address column of the Customers tables in the dsNorthwind1 typed dataset:
txtCustomerAddress.DataBindings.Add("Text",
dsNorthwindData1.Customers, "Address");
Procedure: Performing To bind a data-bound control to a data source at run time, add the following
complex data binding at lines of code that set the DataSource and DisplayMember properties:
run time
DataGrid1.DataSource = productsDataSet;
DataGrid1.DataMember = "Products";
If the DataSource property is not ambiguous, you can use it without defining
the DataMember. The following code accomplishes the same results as the
previous line of code:
DataGrid1.DataSource = productsDataSet.Tables["Products"];
Module 4: Using Data in Windows Forms Applications 37
Note The ComboBox control allows you to bind the ValueMember property
to an alternate value that is not displayed in the ComboBox. This is often used
when you want to display a user–friendly value to the user and bind to another
field that is used programmatically, such as a primary key.
Data Source 1
Currency
Currency Manager2
Manager2
Datagrid
Data Source 2
CurrencyManager
CurrencyManager cm;
cm;
cm
cm == (CurrencyManager)this.BindingContext[pubsDataSet,
(CurrencyManager)this.BindingContext[pubsDataSet,
"Authors"];
"Authors"];
cm.Position
cm.Position +=+= 1;
1;
CurrencyManager The following table lists some of the properties of the CurrencyManager
properties object that helps it track data.
Property Description
Procedure: Maintaining Every Windows Form has a BindingContext object. The BindingContext
the currency by using object tracks all of the CurrencyManager objects on a form. Thus, any
the CurrencyManager Windows Form with data-bound controls has at least one BindingContext
object that tracks one (or more) CurrencyManager object (or objects) that
track one data source (for each CurrencyManager).
For example, if you add a TextBox control to a form and bind it to a column of
a table in a dataset, the control communicates with the BindingContext object
for that form. The BindingContext object, in turn, communicates with the
specific CurrencyManager object for that data association. If you query the
CurrencyManager’s Position property, it reports the current record for that
TextBox control’s binding.
You use the BindingContext of a form to access the various
CurrencyManagers. To do so, you must specify the data source that the
CurrencyManger is managing. For example, to access the CurrenyManager
that manages the Authors table of DataSet1 you would use the following code:
CurrencyManager cm;
cm = (CurrencyManager)this.BindingContext[pubsDataSet,
"Authors"];
Display and discuss the code generated for the navigation buttons
1. Locate the Click event of the btnNavNext button in the Code Editor of
DataForm1, and discuss the following line of code:
this.BindingContext[objOrdersDataSet,"Orders"].Position =
(this.BindingContext[objOrdersDataSet,"Orders"].Position +
1);
2. Locate the objOrdersDataSet_PositionChanged() procedure, and discuss
the following line of code:
this.lblNavLocation.Text =
((((this.BindingContext[objOrdersDataSet,
"Orders"].Position + 1)).ToString() + " of ") +
this.BindingContext[objOrdersDataSet,
"Orders"].Count.ToString());
3. Locate the Click event of the btnLast button in the Code Editor of
DataForm1, and discuss the following line of code:
this.BindingContext[objOrdersDataSet,"Orders"].Position =
(this.objOrdersDataSet.Tables["Orders"].Rows.Count - 1);
4. In Solution Explorer, right-click the BindingContextNavigation project,
and then click Properties.
5. Add code to the Load event of Form1 to display DataForm1.
6. Press F5 to compile and run the application, and then demonstrate the use of
the navigation buttons.
7. Close the application.
Module 4: Using Data in Windows Forms Applications 43
10 $10
Format TextBox1
TextBox1
10 Parse $10
Procedure: Using the The following code creates event delegates for the Parse and Format events of
Format and Parse a Binding object and then uses event procedures to format the data between a
events String and a Decimal:
private void BindControl()
{
Binding priceBinding = new
Binding("Text",titlesDataSet1,"titles.price");
priceBinding.Format += new
ConvertEventHandler(this.FormatDecimalToString);
priceBinding.Parse += new
ConvertEventHandler(this.ParseStringToDecimal);
PriceTextBox.DataBindings.Add(priceBinding);
}
Create an event procedure invoked by the Parse event that converts the
Value of ConvertEventArgs from a String to a Decimal
1. Show TODO comments in the Task List.
To show TODO comments, click the View menu, point to Show Tasks, and
then click All.
2. Locate TODO: 1 in the Code Editor of Form1.
3. Under TODO: 1, create a procedure called ParseStringToDecimal that
accepts two arguments: sender as an Object and convertArgs as a
ConvertEventArgs.
4. Assign the Value of convertArgs to a String named stringValue.
46 Module 4: Using Data in Windows Forms Applications
5. Call the Parse method of the Decimal object and pass the two arguments:
stringValue as the string to be formatted and NumberStyles.Currency as
the NumberStyles constant.
6. Assign the results of the Parse method to Value property of convertArgs.
Your code should look like this:
private void ParseStringToDecimal(object sender,
ConvertEventArgs convertArgs)
{
convertArgs.Value =
Decimal.Parse(convertArgs.Value.ToString(),
NumberStyles.Currency);
}
The Parse method converts the String representation of a number in a
specified style to its decimal equivalent by using the specified formatting
style.
Create an event delegate for the Parse event that references the
FormatDecimalToString procedure
1. Locate TODO: 2 in the Code Editor of Form1.
2. Under TODO: 2, use AddHandler to create an event delegate for the Parse
event of the priceBinding object that references the
ParseStringToDecimal procedure. Your code should look like this:
priceBinding.Parse += new
ConvertEventHandler(this.ParseStringToDecimal);
3. The priceBinding object is a Binding object that is added to the
DataBindings collection of PriceTextBox. Review the following code:
Binding priceBinding = new
Binding("Text",titlesDataSet1,"titles.price");
PriceTextBox.DataBindings.Add(priceBinding);
Estimated time to
complete this lab:
45 minutes
Module 4: Using Data in Windows Forms Applications 49
Exercise 1
Generating and Populating DataSets
In this exercise, you will create a SQLDataAdapter by using Data Adapter Configuration Wizard,
and populate a dataset with data from a database at run time. You will use Component Designer to
add and configure ADO.NET objects. You can use Component Designer to add subcomponents to a
class, configure them, and code their events.
Scenario
You begin to build the data access features into the Purchase Order application. Your development
team has built some of the preliminary data access code that you need to complete. Your
responsibility is to create a DataAdapter that can access and update the Order table of the
Northwind database.
The application uses employee information to load and create order entries. Each order is associated
with a single employee. The Orders table includes an EmployeeID column that maps to the
EmployeeID column in the Employees table. The DataAdapter that you create will use the value
of the employeeID variable to determine which rows to return. You decide to use Data Adapter
Configuration Wizard to configure the SELECT command of the DataAdapter and allow it to
generate the Update command for you.
50 Module 4: Using Data in Windows Forms Applications
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab04_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab04_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resource:
OrderApplication.sln file. • The Visual Studio .NET Help documentation. For additional
To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab04_1\Ex01\Starter\
OrderApplication.
2. Add a SQLDataAdapter a. For more information about adding controls to Component Designer or
control to by using Data Adapter Configuration Wizard, see the following
OrderApplicationData resources:
Class. In Data Adapter • Lesson: Adding ADO.NET Objects to and Configuring ADO.NET
Configuration Wizard, use Objects in a Windows Forms Application in Module 4, “Using
the NorthwindConnection Data in Windows Forms Applications,” in Course 2555A,
information, and create the Developing Microsoft .NET Applications for Windows (Visual C#
following SQL Select .NET).
statement:
• Practice: Adding ADO.NET Objects to and Configuring ADO.NET
SELECT * FROM Orders Objects in a Windows Forms Application in Module 4, “Using
WHERE (EmployeeID = Data in Windows Forms Applications,” in Course 2555A,
@EmployeeID) Developing Microsoft .NET Applications for Windows (Visual C#
.NET).
• Ensure that the wizard
created the Insert, • The Visual Studio .NET Help documentation. Search by using the
Update, and Delete phrase Component Designer or the phrase Data Adapter
commands. Configuration Wizard.
4. Use the Task List to locate a. For more information about assigning values to the Parameters
the code section 'TODO: 2', collection of Command objects, see the following resources:
and add @employeeID (the • Lesson: Accessing and Modifying Data by Using DataSets in
global employee ID) to the Module 4, “Using Data in Windows Forms Applications,” in
Parameters collection of Course 2555A, Developing Microsoft .NET Applications for
the SelectCommand Windows (Visual C# .NET).
property of
OrdersDataAdapter and • Practice: Populating and Updating DataSets in Module 4, “Using
OrderDetailsDataAdapter. Data in Windows Forms Applications,” in Course 2555A,
Developing Microsoft .NET Applications for Windows (Visual C#
.NET).
• The Visual Studio .NET SDK documentation. Search by using the
phrase Using Parameters with a DataAdapter.
5. Use the Task List to locate a. For more information about filling DataSets with data by using a
the code section TODO: 3', DataAdapter, see the following resources:
and call the Fill method of • Lesson: Accessing and Modifying Data by Using DataSets in
OrdersDataAdapter and Module 4, “Using Data in Windows Forms Applications,” in
OrderDetailsDataAdapter Course 2555A, Developing Microsoft .NET Applications for
to fill the Orders and Windows (Visual C# .NET).
OrderDetails tables of
tempDataSet. • Practice: Populating and Updating DataSets in Module 4, “Using
Data in Windows Forms Applications,” in Course 2555A,
Developing Microsoft .NET Applications for Windows (Visual C#
.NET).
• The.NET Framework SDK documentation. For additional
information about assigning values to the Parameters collection of
Command objects, search by using the phrase Populating a
DataSet from a DataAdapter.
6. Place a breakpoint at the a. For more information about building and debugging your applications,
beginning of the see the following resource:
RefreshLocalData • The Visual Studio .NET Help documentation. Search by using the
procedure. Compile and run phrases Default and Custom Builds and Using the Debugger.
the application. From the
Data menu, click Refresh
Data, and step through each
line of code. Locate and
review the contents of the
NorthwindData.XML file,
which is in the most recent
folder version folder of
C:\Documents and
Settings\All Users\
Application Data\
Northwind Traders\
PurchaseOrder\.
52 Module 4: Using Data in Windows Forms Applications
Exercise 2
Modifying a DataSet
In this exercise, you will review the code that creates data tables objects, insert new data rows, and
append the information to an existing dataset.
Scenario
The Orders table uses an auto incrementing column named OrderID to generate primary keys
when new rows are created in the database. This value is also generated by datasets when a new
row is inserted in the Orders table. The Purchase Order application uses a global dataset named
pendingOrdersData to store all the orders until they are submitted to the database. Each order is
associated with one or more order details. The Orders table includes an OrderID column that maps
to the OrderID column of the Order Details table.
One of your colleagues has written a procedure called SaveOrders that creates new rows in the
Orders table, captures the value of the OrderID generated by the dataset, and uses it to create rows
in the Order Details table. After all of the rows in the Order Details table are created, the procedure
persists the order information in an XML file named PendingOrders.XML. You decide to review
the code more closely to understand how it works.
There are solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab04_1\Ex02\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
Module 4: Using Data in Windows Forms Applications 53
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resource:
OrderApplication.sln file. • The Visual Studio .NET Help documentation. For additional
To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab04_1\Ex02\Solution\
OrderApplication.
2. Place a breakpoint at the a. For more information about building and debugging your applications,
beginning of the see the following resource:
SaveOrders procedure in • The Visual Studio .NET Help documentation. Search by using the
MainForm. Compile and run phrases Default and Custom Builds and Using the Debugger.
the application. On the
toolbar, click the Refresh
button, and choose an
employee name. To create
different order items, click
the New Order Item button
and then click the Save
Order button. Step over
each line of code by
pressing F10 and review the
flow of the code.
When reviewing the code,
look for the following
things:
• The SaveOrders
procedure creates a new
row in the Orders table
and assigns the columns
to values from the
controls of MainForm.
When the row is added
to the table, the auto
incrementing OrderID
generated by the
DataSet is stored in a
variable named
clientOrderID.
• The SaveOrders
procedure then creates
rows in the Order
Details table and uses
the value of
clientOrderID to
populate the OrderID
column for each row
inserted into the Order
Details table.
54 Module 4: Using Data in Windows Forms Applications
Exercise 3
Updating a DataSet to a Data Source
In this exercise, you will create a relationship between two tables to create a typed dataset and then
update the changes from the dataset to a DataSource.
Scenario
In the Northwind database, each order is associated with one or more order details. The Orders
table includes an OrderID column that maps to the OrderID column of the Order Details table.
When you create a new row in the Orders table, the SaveOrders procedure ensures that all child
rows in the Order Details table have the same OrderID as the parent in the Orders table. When you
update the dataset to a data source, you must first update the Orders table and then the Order Details
table. When you update a row in the Orders table, however, a new OrderID will be generated by the
database that might not match the child values in the Order Details table. This causes an error when
you attempt to update the Order Details table.
One way to resolve this problem is to write code that uses DataSet events to capture the new
OrderID generated by the database and assign it to all child rows in the Order Details table.
However, other options are available when you use typed datasets and DataAdapters for each table
in a database. Instead of writing code for DataSet events, you can use the Refresh the DataSet
option in Data Adapter Configuration Wizard. With this option enabled, the wizard adds a
SELECT statement after the Insert and Update statements to retrieve the Identity column
generated by the database.
When you create a relation between tables by using XML Designer, you can choose how table
relationships are handled when the parent table is modified. For example, if you set the Delete Rule
to Cascade (the default), and you delete rows in a parent table, all the related rows in the child table
are also deleted. When you create a relation between the Orders and Order Details tables, it is
important that you set the value of the Update Rule option to Cascade (the default) so that any
changes made to a parent table are cascaded to the child tables.
When you update a row in the Orders table, the DataAdapter returns the OrderID value generated
by the database and changes the value in the Orders table of the dataset. With the cascading update
rule, all the child rows in the Order Details table of the dataset will automatically be changed to the
new OrderID of the parent. Now when you update the Order Details table to the database it will
have the same OrderID as the parent.
Module 4: Using Data in Windows Forms Applications 55
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab04_1\Ex03\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab04_1\Ex03\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resource:
OrderApplication.sln file. • The Visual Studio .NET Help documentation. For additional
To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab04_1\Ex03\Starter\
OrderApplication.
2. Use XML Designer to a. For more information about using XML Designer, see the following
create a relation between the resources:
Orders and Order Details • Lesson: Accessing and Modifying Data by Using DataSets in
tables in the Module 4, “Using Data in Windows Forms Applications,” in
NorthwindDataSet.xsd file. Course 2555A, Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
• Demonstration: Creating Database Schema by Using the XML
Schema Designer in Module 4, “Using Data in Windows Forms
Applications,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase XML Designer.
3. Use the Task List to locate a. For more information about updating a data source, see the following
the code section 'TODO: 1' resources:
in the code view of • Lesson: Accessing and Modifying Data by Using DataSets in
OrderApplicationDataClass. Module 4, “Using Data in Windows Forms Applications,” in
cs, and update the database Course 2555A, Developing Microsoft .NET Applications for
by using the Update method Windows (Visual C# .NET).
of OrdersDataAdapter and
OrderDetailsDataAdapter. • Practice: Populating and Updating DataSets in Module 4, “Using
Data in Windows Forms Applications,” in Course 2555A,
The Cascading Update rule Developing Microsoft .NET Applications for Windows (Visual C#
enforced by the relation .NET).
between the two tables • The Visual Studio .NET Help documentation. Search by using the
should automatically phrase Updating the Database with a DataAdapter and the
retrieve the OrderID DataSet.
generated by the server.
When an Order row is
created, it is assigned to
related rows in the Order
Details table on the client
computer.
56 Module 4: Using Data in Windows Forms Applications
4. Compile and run the a. For more information about building and debugging your applications
application . On the toolbar, and using Server Explorer, see the following resource:
click the Refresh button, • The Visual Studio .NET Help documentation. Search by using the
and choose an employee phrases Default and Custom Builds, Using the Debugger, and
name. To create an order, Server Explorer Window.
click the New Order Item
button. To save the order,
click the Save Order
button, and then click the
Submit button on the
Toolbar. Use Server
Explorer to verify that the
order was saved to the
database.
Module 4: Using Data in Windows Forms Applications 57
Exercise 4
Binding and Formatting Data in Controls
In this exercise, you will bind data to controls and format the data by using the events of the
Binding class.
Scenario
The OrderItemControl control is under development and requires code to bind constituent
controls to data from the Products table. A method within the control called GetProductData has
been created, and it accepts a parameter named productsTable that contains data from the Products
table. You need to bind data from this table to the constituent controls. You also need to convert the
values in the Price column to currency when you bind them to UnitPriceTextBox control.
There are starter and solution files associated with this exercise. Browse to the
install_folder\Labfiles\Lab04_1\Ex04\Starter folder to find the starter files, and browse to the
install_folder\Labfiles\Lab04_1\Ex04\Solution folder to find the solution files. If you performed a
default installation of the course files, install_folder corresponds to C:\Program
Files\Msdntrain\2555.
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resources
OrderApplication.sln file. • The Visual Studio .NET Help documentation. For additional
To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab04_1\Ex04\Starter\
OrderApplication.
2. Use the Task List to locate a. For more information about binding controls to data, see the following
the code section 'TODO: 1 resources:
in the code window of • Lesson: Binding Data to Controls in Module 4, “Using Data in
OrderItemControl.cs' , and Windows Forms Applications,” in Course 2555A, Developing
assign the DataSource of Microsoft .NET Applications for Windows (Visual C# .NET).
ProductNameComboBox
to the DataTable passed to • Practice: Binding Controls to Data in Module 4, “Using Data in
the GetProductData Windows Forms Applications,” in Course 2555A, Developing
procedure. Assign the Microsoft .NET Applications for Windows (Visual C# .NET).
DisplayMember and • The.NET Framework SDK documentation. For additional
ValueMember of information about binding controls to data, search by using the
ProductNameComboBox phrase Data Binding and Windows Forms.
to the ProductName and
ProductID columns,
respectively.
58 Module 4: Using Data in Windows Forms Applications
3. Use the Task List to locate a. For more information about binding data to controls, see the following
the code section 'TODO: 2', resources:
and declare a Binding • Lesson: Binding Data to Controls in Module 4, “Using Data in
object, and use it to bind the Windows Forms Applications,” in Course 2555A, Developing
Text property of Microsoft .NET Applications for Windows (Visual C# .NET).
UnitPriceTextBox to the
UnitPrice column of the • Practice: Binding Controls to Data in Module 4, “Using Data in
DataTable passed to the Windows Forms Applications,” in Course 2555A, Developing
GetProductData procedure. Microsoft .NET Applications for Windows (Visual C# .NET).
• The.NET Framework SDK documentation. For additional
information about binding controls to data, search by using the
phrase Data Binding and Windows Forms.
4. Use the Task List to locate a. For more information about creating event procedures for Binding
the code section 'TODO: 3', objects, see the following resources:
and create an event • Lesson: Binding Data to Controls in Module 4, “Using Data in
procedure named Windows Forms Applications,” in Course 2555A, Developing
DecimalToCurrency that Microsoft .NET Applications for Windows (Visual C# .NET).
converts the
ConvertEventArgs event • Practice: Formatting Data Bound Controls in Module 4, “Using
argument to a currency Data in Windows Forms Applications,” in Course 2555A,
format. Developing Microsoft .NET Applications for Windows (Visual C#
.NET).
• The.NET Framework SDK documentation. For additional
information about binding controls to data, search by using the
phrase Data Binding and Windows Forms.
5. Use the Task List to locate a. For more information about creating event handlers, see the following
the code section 'TODO: 4', resources:
and create an event handler • Lesson: Creating an Event Handler for a Control in Module 2,
for the Format event of the “Working with Controls,” in Course 2555A, Developing
Binding object created in Microsoft .NET Applications for Windows (Visual C# .NET).
step 4.
• Practice: Creating an Event Handler for a Control in Module 2,
“Working with Controls,” in Course 2555A, Developing
Microsoft .NET Applications for Windows (Visual C# .NET).
• The Visual Studio .NET SDK documentation. For additional
information about binding controls to data, search by using the
phrase Creating Event Handlers at Run Time for Windows
Forms.
6. Compile and run the a. For more information about building and debugging your applications,
application. On the toolbar, see the following resource:
click the Refresh button, • The Visual Studio .NET Help documentation. Search by using the
and choose an employee phrases Default and Custom Builds and Using the Debugger.
name. To populate the
OrderItemControl control,
click the New Order Item
button. Navigate through the
products by using the
ProductNameComboBox
control.
Module 4: Using Data in Windows Forms Applications 59
UDDI
(Web service broker)
sh
Fin
bli
d
Pu
Internet
Bind
Methods, arguments,
Get
Get description
description of
of return values WSDL
XML Web
Web service
service
Proxy
Proxy calls
calls XML
XML Proxy transparently handles
Web service
service network communication
methods
methods
For more information about static and dynamic discovery of XML Web
services, see the lesson titled Creating a Simple XML Web Services Client in
Module 4, “Using Data in Windows Forms Applications,” in Course 2555A,
Developing Microsoft .NET Applications for Windows (Visual C#™ .NET).
XML Web service An XML Web service can be used either internally by a single application or
description exposed externally over the Internet for use by any number of applications.
Because it is accessible through a standard interface, an XML Web service
allows heterogeneous systems to work together as a single web of computation.
Proxy calls XML Web An XML Web service consumer must be able to construct the messages that are
service methods sent to a Web service and parse the messages that are received from a Web
service. Manually writing the code to construct and parse the messages is time-
consuming and prone to error. It is better to encapsulate this code in a class that
can be reused. A class like this is called a proxy class.
When you reference an XML Web service from a consumer application, the
.NET Framework generates a proxy for you.
62 Module 4: Using Data in Windows Forms Applications
What is SOAP?
AP
SO
SO
AP
Web Server
Any
XML
Web service
SOAP client
The advantages of using By using SOAP as an underlying protocol for XML, messages can pass data by
SOAP reference and contain complex structures such as objects, structures, and data
sets.
Module 4: Using Data in Windows Forms Applications 63
What is WSDL?
WSDL
An XML grammar used for describing a Web service in terms of the
messages it accepts and generates
WSDL document
Defines the types used in the operations (methods) of a Web service
and the documents that are exchanged for each operation
CodeExample
Example The following code is an example of some of the contents of the WSDL
document for the ExpenseReportWebService XML Web service that your client
application will call in Lab 4.2: Calling an XML Web Service in Course
2555A, Developing Microsoft .NET Applications for Windows
(Visual C# .NET):
<?xml version="1.0" encoding="utf-8" ?>
- <definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:s0="http://localhost/ExpenseReportWebService"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://localhost/ExpenseReportWebService"
xmlns="http://schemas.xmlsoap.org/wsdl/">
- <types>
- <s:schema elementFormDefault="qualified"
targetNamespace="http://localhost/ExpenseReportWebService">
<s:import namespace="http://www.w3.org/2001/XMLSchema" />
- <s:element name="AuthenticateUser">
- <s:complexType>
- <s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="username"
type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="password"
type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="passwordToken"
type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
...
Usually this information is transparent to the developer. The XML Web service
description is just used by the .NET Framework when you add a reference to an
XML Web service to your client application. You will see a more user-friendly
display of the details of the methods, arguments, and return values associated
with an XML Web service that you reference in the lesson titled Creating a
Simple XML Web Services Client in Module 4, “Using Data in Windows
Forms Applications,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
Module 4: Using Data in Windows Forms Applications 65
Firewall
Internet
Note For more information about how to make asynchronous calls to XML
Web services to avoid blocking the user interface, see Module 7,
“Asynchronous Programming,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
Lesson objective After completing this lesson, you will be able to create and test a simple XML
Web service client application.
66 Module 4: Using Data in Windows Forms Applications
Static Discovery
Provide explicit URL
Disco file
Dynamic Discovery
UDDI
Vsdisco file
Note A static discovery document usually has the extension .disco and a
dynamic discovery document has the extension .vsdisco.
Module 4: Using Data in Windows Forms Applications 67
Procedure: Generating In Visual Studio .NET, you can generate a proxy by adding a Web Reference to
the proxy your client application project.
68 Module 4: Using Data in Windows Forms Applications
Alternatively, you can use WSDL to generate a proxy. The following code
generates a proxy by using the default language (C#) and default protocol
(SOAP).
wsdl http://www.contoso.com/ExpenseReportWebService/
ExpenseReportWebService.asmx?wsdl
Procedure: Instantiating As shown in the code on the slide, the following statement generates the proxy
the proxy to call the ExpenseReportWebService WS XML Web service:
ExpenseReportWebService WS = new ExpenseReportWebService();
Procedure: Calling the As shown in the code on the slide, you can call the methods of the XML Web
XML Web service service, as appropriate, to get the data that your application needs:
methods
DataSet ds = WS.GetReportsForEmployee(username, passwordToken,
0, 10, ref totalReports);
Module 4: Using Data in Windows Forms Applications 69
8. Find the next TODO comment, which instructs you instantiate the XML
Web service proxy class. Add the code to instantiate the proxy.
WS = new ExpenseReportWebService();
9. Find the last TODO comment, which instructs you to add a call to the
GetReportsForEmployee method of the Web service. Add the code to
make the call to the method.
WS.GetReportsForEmployee(null, null, 0, 10,
ref TotalReports);
10. Build the project.
Class
Class Description
Description
These
These classes
classes read
read and
and write
write primitive
primitive types
types
BinaryReader
BinaryReaderand
and as
as binary
binary values
values in
in aa specific
specific encoding
encoding to to and
and
BinaryWriter
BinaryWriter from
from aa stream.
stream.
StreamReader
StreamReaderand
and The
The implementations
implementations of
of these
these classes
classes are
are
StreamWriter
StreamWriter designed
designed for
for character
character input
input and
and output.
output.
StringReader
StringReaderand
and The
The implementations
implementations of of these
these classes
classes are
are
StringWriter
StringWriter designed
designed for
for string
string input
input and
and output.
output.
BinaryReader and BinaryWriter These classes read and write primitive types as
binary values in a specific encoding to and from
a stream.
StreamReader and StreamWriter The implementations of these classes are
designed for character input and output.
StringReader and StringWriter The implementations of these classes are
designed for string input and output.
A reader or writer is attached to a stream so that the required types can be read
or written to easily.
74 Module 4: Using Data in Windows Forms Applications
The following code shows how to write data of type Integer to and read from a
new, empty file stream that is named Test.data. After creating the data file in
the current directory, the BinaryWriter class writes the integers 0 through 10
to Test.data. Then, the BinaryReader class reads the file and displays the file’s
content to the console.
using System;
using System.IO;
class MyStream {
private const string FILE_NAME = "Test.data";
public static void Main(String[] args) {
// Create the new, empty data file.
if (File.Exists(FILE_NAME)) {
Console.WriteLine("{0} already exists!", FILE_NAME);
return;
}
FileStream fs = new FileStream(FILE_NAME,
FileMode.CreateNew);
// Create the writer for data.
BinaryWriter w = new BinaryWriter(fs);
// Write data to Test.data.
for (int i = 0; i < 11; i++) {
w.Write( (int) i);
}
w.Close();
fs.Close();
// Create the reader for data.
fs = new FileStream(FILE_NAME, FileMode.Open,
FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
// Read data from Test.data.
for (int i = 0; i < 11; i++) {
Console.WriteLine(r.ReadInt32());
w.Close();
}
}
}
Module 4: Using Data in Windows Forms Applications 75
In the following example, the code defines a string and converts it to an array of
characters, which can then be read as required by using the appropriate
StringReader.Read method:
using System;
using System.IO;
System.Text.Encoding Internally, the common language run time represents all characters as Unicode.
However, Unicode can be inefficient when transferring characters over a
network or when persisting in a file. To improve efficiency, the .NET
Framework class library provides several types that are derived from the
System.Text.Encoding abstract base class. These classes know how to encode
and decode Unicode characters to ASCII, UTF-7, UTF-8, Unicode, and other
arbitrary code pages. When you construct a BinaryWriter or StreamWriter,
you can choose any of these encodings. The default encoding is UTF-8.
76 Module 4: Using Data in Windows Forms Applications
Binary serialization
XML serialization
Serialize
Serialize the
the object
object to
to aa file
file
Deserialize
Deserialize the
the file
file into
into an
an object
object
Procedure: Saving data There are three main steps to saving data by using binary serialization.
by using binary
serialization 1. Add the Serializable attribute to the class to be serialized.
[Serializable]
public class MyObject {
public int n1 = 0;
public int n2 = 0;
public String str = null;
}
2. Serialize the object to a stream by using a BinaryFormatter object.
MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin",
FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();
3. When your application needs the persisted data, deserialize the file to an
object, by using a BinaryFormatter object.
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open,
FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(stream);
stream.Close();
Procedure: Saving data There are two main steps to saving data by using XML serialization.
by using XML
serialization 1. Serialize the object to a file.
public class OrderForm {
public DateTime OrderDate;
}
XmlElement objects
XmlNode objects
DataSet objects
As with binary serialization, the .NET Framework provides attributes and other
techniques to control XML serialization more finely. In addition, XML
serialization is used by the .NET Framework to create SOAP messages for
XML Web service calls. For more information about XML serialization, see the
XML Serialization section of the .NET Framework SDK documentation.
Module 4: Using Data in Windows Forms Applications 79
Comparison of binary Generally speaking, binary serialization is best for storing private state and data
and XML serialization used by one application or assembly. It produces compact files that are fast to
save and load. XML serialization produces larger files and has more overhead
but is better for cases when data will be shared across systems, such as with
XML Web services.
Binary serialization XML serialization
Stores all members, both public and Only stores public members by default.
private, by default.
Usually produces very compact serialized Usually produces larger serialized
representations of objects, with little representations of objects, with more
overhead. overhead.
Makes interoperation difficult, because Interoperation is easier, because it uses
object state is stored in a proprietary open standards such as XML and SOAP.
format.
80 Module 4: Using Data in Windows Forms Applications
Open
Open the
the store
store
Create
Create aa stream for reading or writing files in the
the store
store
Close
Close the
the stream
stream and store
CodeExample
Procedure: Accessing There are three main steps to accessing isolated storage:
isolated storage
1. Open the store.
IsolatedStorageFile isoStore = null;
isoStore = IsolatedStorageFile.GetUserStoreForDomain();
2. Create a stream for reading or writing files in the store.
IsolatedStorageFileStream dataFile = null;
dataFile = new IsolatedStorageFileStream("myfile.txt",
FileMode.Open, isoStore);
// code to read from or write to file goes here
3. Close the stream and store.
dataFile.Close();
isoStore.Close();
82 Module 4: Using Data in Windows Forms Applications
Choose a technique
Use a DataSet object
Good for tabular or relational data
Use reader/writer objects
Complete control, but developer must write
and maintain more code
Use serialization
Good choice when application stores state in objects
Choose a storage location
The file system
Isolated storage
Lab setup There are starter and solution files associated with this lab. Browse to
install_folder\Labfiles\Lab04_2\Ex01\Starter to find the starter files, and
browse to install_folder\Labfiles\Lab04_2\Ex01\Solution to find the solution
files. If you performed a default installation of the course files, install_folder
corresponds to C:\Program Files\Msdntrain\2555.
Estimated time to
complete this lab:
15 minutes
Module 4: Using Data in Windows Forms Applications 85
Exercise 1
Calling an XML Web Service
In this exercise, you will call some methods of an XML Web Service.
1. Open the ExpenseReport project in a. For more information about opening a project file
Visual Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab04_2\Ex01\Starter to resource:
find the project files. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using the
phrase Open Project Dialog Box. For
additional information about starting an
application from in the Designer, in Index,
search by using the phrase Debugging
Windows Applications.
2. Add a Web reference to the test XML Web a. For more information about how to add a Web
service on your local computer. The URL for this reference, see the following resources:
XML Web service is: • Practice: Calling an XML Web Service in
http://localhost/ Module 4, “Using Data in Windows Forms
ExpenseReportWebService/ Applications,” in Course 2555A, Developing
ExpenseReportWebService.asmx Microsoft .NET Applications for Windows
(Visual C# .NET).
• Lesson: Creating a Simple XML Web
Services Client in Module 4, “Using Data in
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
3. Open the ExpenseReportUtilities file. Find the a. For more information about how to create an
TODO comment toward the bottom of the file. XML Web service proxy object, see the following
Add the code to create the XML Web service resources:
proxy object and store it in the WSInternal • Practice: Calling an XML Web Service in
member of the class. Module 4, “Using Data in Windows Forms
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• Lesson: Creating a Simple XML Web
Services Client in Module 4, “Using Data in
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
86 Module 4: Using Data in Windows Forms Applications
4. Open the ExpenseReportList form, and view its a. For more information about how to call a method
code. Find the two TODO comments in the of an XML Web service, see the following
constructor. Add the code to make the XML Web resources:
service calls after the comments. In each case, • Practice: Calling an XML Web Service in
you will retrieve the XML Web service proxy Module 4, “Using Data in Windows Forms
from the static (shared) Utilities object, by using Applications,” in Course 2555A, Developing
the following syntax: Microsoft .NET Applications for Windows
Utilities.WS (Visual C# .NET).
a. The first method call will be to the • Lesson: Creating a Simple XML Web
GetReportsForEmployee method. Store the Services Client in Module 4, “Using Data in
return value from this call in the Windows Forms Applications,” in Course
ExpRepDataSet data member, and pass the 2555A, Developing Microsoft .NET
following parameters. Applications for Windows (Visual C# .NET).
Parameter Value
username UCred.UserNameString
passwordToken UCred.PasswordTokenString
reportIndex RecordCursor
numberReports 10
totalNumberReports ref TotalNumRecords
b. The second method call will be to the
GetReportsForManagerApproval method.
Again, store the return value from this call in
the ExpRepDataSet data member, and pass
the same parameters as in step 4a.
5. Build and run the application. Click the View Additional information is not necessary for this task.
Submitted Reports button and make sure the list
of expense reports is populated.
Module 4: Using Data in Windows Forms Applications 87
Review
3. How do you access tables and columns in a typed and untyped dataset?
Typed dataset
PubsDataSet.Titles;
Untyped dataset
PubsDataSet.Tables(“Titles”);
88 Module 4: Using Data in Windows Forms Applications
6. What is CurrencyManager?
The CurrencyManager object is used to keep data-bound controls
synchronized with a data source. The CurrencyManger is important
because data sources, such as tables in datasets, do not track the
currently selected row. You need an intermediary object that is aware
of the currently selected position in a data source and can notify
databound controls when the position changes. That intermediary
object is a CurrencyManager object.
7. What are the main steps that you take in your application to call an XML
Web service?
The main steps that you take in your application to call an XML Web
service are to:
• Generate the proxy that will call the XML Web service methods.
• Instantiate the proxy.
• Call the XML Web service methods that are required by your
application.
Module 4: Using Data in Windows Forms Applications 89
Overview 1
Lesson: Using .NET and COM Components
in a Windows Forms Application 2
Lesson: Calling Win32 APIs from Windows
Forms Applications 17
Review 28
Lab 5.1: Interoperating with COM and
Calling Win32 APIs 30
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 5: Interoperating with Managed Objects iii
Instructor Notes
Presentation: This module provides students with knowledge of how to use COM
60 minutes components in Microsoft® .NET Framework-based applications. The module
also covers how to call Microsoft Win32® APIs from a .NET-based application.
Lab:
30 minutes After completing this module, students will be able to:
Use .NET and COM components in a Microsoft .NET Framework Windows
Forms application.
Call Microsoft Win32 APIs from a Windows Forms application.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_05.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Complete the practices, demonstrations, and lab.
iv Module 5: Interoperating with Managed Objects
Overview
This module introduces you to the concepts and mechanics of the interoperation
of .NET managed code with COM unmanaged code and platform services.
Objectives After completing this module, you will be able to:
Use .NET and COM components in a Microsoft .NET Framework Windows
Forms application.
Call Microsoft Win32® APIs from a Windows Forms application.
2 Module 5: Interoperating with Managed Objects
COM vs .NET
How to Call COM Components from .NET
Role of the RCW
How to Generate Interop Assemblies
Private, Shared, and Primary Interop Assemblies
Practice: Using COM Components in .NET-Based
Applications
In this lesson, you will learn how to call COM components from the .NET
Framework.
Module 5: Interoperating with Managed Objects 3
Lesson objectives After completing this lesson, you will be able to:
Identify the differences between COM and .NET programming models.
Explain how to call COM components from the .NET Framework.
Describe the role of the runtime callable wrapper (RCW) in interoperating.
Generate interop assemblies.
Describe private, shared, and primary interop assemblies.
Note This module does not cover using .NET objects from a COM client by
using the COM callable wrapper (CCW). For more information about the
CCW, see “COM Callable Wrapper” in the .NET Framework software
development kit (SDK) documentation.
4 Module 5: Interoperating with Managed Objects
COM vs .NET
HResults Exceptions
Immutable Resilient
Coding model Interface based. COM objects Object based. .NET Framework
always communicate through objects can pass data directly to each
interfaces. other, without implementing
interfaces.
Identity Globally unique identifiers (GUIDs). Strong names. Strong names consist
GUIDs identify a specific of a unique assembly name in
unmanaged type and provide no addition to a type name. Because the
location information for that type. assembly name uniquely identifies
the type, you can reuse a type name
across multiple assemblies. An
assembly also introduces publisher
key, version, and location
information to a managed type.
Type compatibility Binary standard. The internal binary Type standard. The .NET common
layout of classes must comply with type system specification establishes
COM rules. a framework that enables cross-
language integration, type safety, and
so on.
Type definition Type library. Type information is Metadata. Type information is stored
stored only for public types. as metadata and is mandatory for all
Moreover, a type library is optional. types. Metadata is embedded inside
assemblies.
Module 5: Interoperating with Managed Objects 5
(continued)
Characteristic COM .NET Framework
Type safety Not type-safe. Unmanaged compilers Optionally safe. Managed code
do not provide type checking on requires a higher level of trust.
pointer types. Therefore, the code Therefore, although you can use
becomes susceptible to potentially pointers in managed code, the code
harmful activity. has restrictions because of its unsafe
behavior.
Error-handling mechanism HRESULTs. A COM method returns Exceptions. Managed code
an HRESULT to indicate whether incorporates exceptions.
the call succeeded or failed.
Object-lifetime management Reference counting. Clients of COM Garbage collection. The common
objects manage object lifetime by language runtime manages the
means of reference counting. lifetime of objects by means of
garbage collection.
Versioning Immutable. COM interfaces are Resilient. Managed types can evolve,
immutable. In other words, if you retaining the same name.
change an interface, you must
rename it with a new GUID.
6 Module 5: Interoperating with Managed Objects
COM Object
Object A RCW
RCW .NET
.NET Client
Client
COM Object
Object B RCW
RCW .NET
.NET Client
Client
Unmanaged Managed
COM
COM IDispatch .NET
.NET
RCW
RCW
Object
Object Client
Client
INew
Unmanaged Managed
Note There are some limitations to using the RCW. For example, Success
HRESULTS are not returned from unmanaged code. Variable length arrays
also pose challenges. For more information about these limitations and how
to fix them, refer to the “Interop Marshaling” section of the .NET
Framework SDK.
A B
COM object
object
A
Tlbimp.exe
Tlbimp.exe Interop
Interop B
Assembly
Assembly C
D
C D
COM
COM object
object
Unmanaged Managed
Procedure: Add a You can build metadata by using the TLBIMP tool. The TLBIMP provides
reference to a type command-line switches to adjust metadata in the resulting interop file, imports
library by using the types from an existing type library, and generates an interop assembly and a
TLBIMP tool namespace. The TLBIMP provides a finer degree of control when creating
interop assemblies.
Use the following syntax to generate an interop assembly by using the TLBIMP
tool:
Tlbimp TlbFile [/out: name] [/reference: file] [/silent] [/verbose] [/strictref]
[/unsafe][ [/primary]][/publickey: file] [/keyfile: file][/keycontainer: name]
TLBIMP uses the command line switches described in the following table.
Command Line Switch Description
/keycontainer:containername
Example The following command line creates an interop assembly by using the Com1.tlb
COM type library.
tlbimp COM1.tlb /keyfile:myPublicKeyFile.sn
/reference:COM2InteropAssembly.dll
/out:COM1InteropAssembly.dll
The example uses the myPublicKeyFile.sn file to assign a strong name to the
assembly by using a public key. The COM1 component calls members of
another COM class called COM2. However, if you have already created an
interop assembly for COM2 called COM2InteropAssembly.dll, this will be a
duplication of work. To prevent the TLBIMP tool from generating an interop
assembly that contains information for both COM1 and COM2, add a reference
to the existing COM2InteropAssembly.dll. This will ensure that metadata for
COM2 will not be generated in the COM1InteropAssembly.
Module 5: Interoperating with Managed Objects 11
C:\Application1 C:\Application2
Metadata
Metadata Metadata
Metadata
MSIL
MSIL MSIL
MSIL
Application1.exe
Application1.exe Application2.exe
Application2.exe
Private Interop
Metadata
Metadata Metadata
Metadata Assemblies
Productlib.dll
Productlib.dll Productlib.dll
Productlib.dll
GAC
Metadata
Metadata Strong Named
Productlib.dll Assemblies
Productlib.dll
PIAs are important because they provide unique type identity. They distinguish
the official type definitions from all other definitions provided by other interop
assemblies, thereby ensuring type compatibility between applications that share
the types defined in a PIA.
When available, always use the primary interop assembly published by the
author of the COM component you intend to incorporate in your managed code.
Types in the primary interop assembly are imported for you and are ready to
activate and call from managed code. Avoid using interop assemblies that are
not primary interop assemblies.
Module 5: Interoperating with Managed Objects 13
Note The path in step 2 will change if the starter files for the practices and
demonstrations are installed in a different location on your computer.
Tip You can also drag the NorthwindData_COM.dll file from Microsoft
Windows Explorer to the Run dialog box or to the Command window,
append regsrv32 to the beginning of the file name, and then press ENTER.
Unmanaged Managed
Assembly
Assembly
DLL
DLL Platform
invoke Metadata
Metadata Managed
Managed
DLL
DLL Compiler
Compiler source
source
function
function IL
IL code
code code
code
Common
Common language
language
runtime
runtime
Standard
marshaling service
3. Locates the address of the function in memory and pushes its arguments
onto the stack, marshaling data as required.
4. Transfers control to the unmanaged function.
5. Returns exceptions generated by the unmanaged function to the managed
caller.
20 Module 5: Interoperating with Managed Objects
Procedure Apply the DllImport attribute to the empty function. The first parameter is the
name and location of the DLL containing the function that you are calling. You
do not need to specify the path for files located in the Windows system
directories. The second parameter is a named argument that specifies the name
of the function in the Windows API.
[DllImport("KERNEL32.DLL", EntryPoint="MoveFileW",
SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern bool MoveFile(String src, String dst);
22 Module 5: Interoperating with Managed Objects
Create
Create aa new
new project
project in
in Visual
Visual Studio
Studio .NET
.NET
Import
Import the
the System.Runtime.InteropServices
System.Runtime.InteropServices namespace
namespace
using
using System.Runtime.InteropServices;
System.Runtime.InteropServices;
Define
Define aa function
function using
using DllImport
DllImport
Add
Add code
code to
to call
call the Win32
Win32 API
API from
from aa Windows
Windows Form
Form
bool
bool result;
result;
System.IntPtr
System.IntPtr resourceHandle
resourceHandle == System.IntPtr.Zero;
System.IntPtr.Zero;
result
result ==
Win32PlaySoundClass.PlaySound_DllImport(soundFileNam
Win32PlaySoundClass.PlaySound_DllImport(soundFileNam
e,resourceHandle,0);
e,resourceHandle,0);
Notice that the arguments of the API use unmanaged C++ variable types. You
must understand these variables types to convert them to an equivalent .NET
type.
For more information and a list of unmanaged data types and their managed
equivalents, see the “Platform Invoke Data Types” section of the .NET
Framework SDK.
Module 5: Interoperating with Managed Objects 25
The PlaySound function takes three arguments and returns a Boolean value
indicating whether or not the function was able to play the sound file. The
arguments include:
pszSound
A string that defines the name of the sound file.
hmod
Handle to the executable file that contains the resource to be loaded. This
parameter must be NULL unless SND_RESOURCE is specified in
fdwSound.
fdwSound
Flags that are used to determine how the sound is played. Examples of flags
include whether the sound should play asynchronously or whether it should
loop.
Instructions
Open the practice project
1. Using Windows Explorer, navigate to
install_folder\Practices\Mod05\Mod05_02\Starter.
Parameter Value
pszSound soundFileName
hmod resourceHandle
fdwSound 0
Note If there are no speakers available to test the sound, test the value of the
result variable in the debug mode.
____________________________________________________________
____________________________________________________________
Note You can also correct this error by setting the EntryPoint parameter to
PlaySoundA; however, you must also set the CharSet parameter to
CharSet.Ansi.
28 Module 5: Interoperating with Managed Objects
Review
4. What are the two most common methods used for generating interop
assemblies?
Visual Studio .NET IDE and TLBIMP tool.
Scenario You are a developer in a trading company called Northwind Traders. The
department that you work in is developing a purchase order application that will
be used by the Northwind Traders sales force. As you develop the Purchase
Order application, you realize that there are some required functionalities that
are either too difficult to include in the first version of the application or are
inaccessible from the .NET Framework. One of these functionalities is the
ability to do a live lookup on the database to determine how many units of a
specified product remain in the inventory. The other functionality is to include
sound files that play when a user successfully completes an operation.
You realize that you can re-use existing COM components in your application.
A COM component called NorthwindData_COM already exists, and it
performs the required lookup task. In addition, NorthwindData_COM was
installed with a previous application on all the client computers on which the
Purchase Order application will be installed.
You also realize that you can expose and invoke the Win32 APIs that play
media files and use them in the Purchase Order application.
Estimated time to
complete this lab:
30 minutes
32 Module 5: Interoperating with Managed Objects
Exercise 1
Using a COM Component in a .NET-Based Application
In this exercise, you will create a reference to a COM object, view the Interop assembly by using
ILDASM, and invoke the COM component from a Windows Forms application.
Scenario
The sales staff of Northwind Traders has put in a request that the Purchase Order application be
able to display the number of units in inventory for a specified product. Without knowing how
much inventory is available, it is difficult for the sales staff to estimate the time it will take to
deliver the order. By knowing the number of units in stock, they can anticipate late deliveries and
warn the customer in advance.
You decide to use an existing COM component that was installed on the sales staff’s laptops with a
previous application. The existing COM component is called NorthwindData_COM, and it includes
a class called RemainingInventoryClass. The RemainingInventoryClass class includes a method
called ShowUnitsInStock that returns a string that identifies the product name and the number of
units remaining in inventory.
All the functions that are available in NorthwindData_COM use ADO 2.6 and require a live
connection to the database, so the salesperson must be connected to the database for the component
to return the expected results. You intend to provide a disconnected feature that provides a similar
function in the next version of the Purchase Order application.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab05_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab05_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
Module 5: Interoperating with Managed Objects 33
1. Open Visual Studio .NET, and a. For more information about opening a project file, see the following
open the resource:
PurchaseOrderApplication.sln • The Visual Studio .NET Help documentation. For additional
file. To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab05_1\Ex01\Starter\
OrderApplication.
2. Register the a. For more information about the adding a reference and creating an
NorthwindData_COM.dll Interop assembly, see the following resources:
located in • Lesson: Using .NET and COM Components in a Windows Forms
install_folder\Labfiles\ Application in Module 5, “Interoperating with Managed
Lab05_1\Ex01\Starter\ using Objects,” in Course 2555A, Developing Microsoft .NET
the REGSVR32 utility and Applications for Windows (Visual C# .NET).
add a reference to the
component. • Practice: Using COM Components in .NET-Based Applications
in Module 5, “Interoperating with Managed Objects,” in Course
When you use the IDE to 2555A, Developing Microsoft .NET Applications for Windows
create a reference to a COM (Visual C# .NET).
component, it uses TLBIMP • The Visual Studio .NET Help documentation. For additional
to create an Interop assembly. information about creating References, search by using the
• If you already registered phrase Adding and Removing References.
this component in • The.NET Framework SDK documentation. For additional
Practice: Using COM information about creating Interop assemblies, search by using
Components in .NET the phrase Importing a Type Library as an Assembly.
Applications in Module 5,
“Interoperating with
Managed Objects,” in
Course 2555A,
Developing Microsoft
.NET Applications for
Windows (Visual C#
.NET), then just add a
reference to the
NorthwindData_COM.dll
component.
3. Run ILDASM, and view the a. For more information about how to use ILDASM, see the following
information for resource:
Interop.NorthwindData_COM • The .NET Framework SDK documentation. Search by using the
.dll. This DLL is located in phrase MSIL Disassembler (Ildasm.exe).
install_folder\Labfiles\
Lab05_1\Ex01\Starter\
OrderApplication\Bin\Debug.
Interop.NorthwindData_COM
.dll is the Interop assembly
that was generated when you
added a reference to the
NorthwindData_COM.dll.
34 Module 5: Interoperating with Managed Objects
4. Open MainForm in the Code a. For more information about using COM components in managed
Editor. Use the Task List to code, see the following resources:
locate the code section 'TODO • Lesson: Using .NET and COM Components in a Windows Forms
1. Create an instance of the Application in Module 5, “Interoperating with Managed
NorthwindData_COM Objects,” in Course 2555A, Developing Microsoft .NET
RemainingInventoryClass Applications for Windows (Visual C# .NET).
COM component.
• Practice: Using COM Components in .NET-Based Applications
in Module 5, “Interoperating with Managed Objects,” in Course
2555A, Developing Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation. For additional
information about using COM components in .NET code, search
by using the phrase Using COM Types in Managed Code.
5. Use the Task List to locate the a. For more information about using the SourceControl method of the
code section 'TODO 2. Create ContextMenu class, see the following resource:
an instance of the • The.NET Framework SDK documentation. Search by using the
OrderItemControl control phrase ContextMenu.SourceControl Property.
and assign it the
SourceControl property of
the ProductContextMenu
control.
6. Use the Task List to locate the a. For more information about the OrderItemControl, see the
'TODO 3. Create a variable of following resource:
the type Short and assign it • Lab 3.1: Building Controls in Module 3, “Building Controls,” in
the OrderProductID property Course 2555A, Developing Microsoft .NET Applications for
of the OrderItemControl. Windows (Visual C# .NET).
7. Use the Task List to locate the a. For more information about creating a Try Catch block and using
code section 'TODO 4. Create COM components in managed code, see the following resources:
a try, catch block and call the • Lesson: Using .NET and COM Components in a Windows Forms
ShowUnitsInStock method of Application in Module 5, “Interoperating with Managed
the Objects,” in Course 2555A, Developing Microsoft .NET
RemainingInventoryClass Applications for Windows (Visual C# .NET).
class, passing the Short
variable containing the • Practice: Using COM Components in .NET-Based Applications
ProductID and the name of a in Module 5, “Interoperating with Managed Objects,” in Course
SQL Server with the 2555A, Developing Microsoft .NET Applications for Windows
Northwind database installed. (Visual C# .NET).
Display the results in a • The.NET Framework SDK documentation. For additional
message box. information about using Try Catch blocks, search by using the
phrase Using the Try/Catch Block to Catch Exceptions.
The name of the SQL Server • The Visual Studio .NET SDK documentation. For help with
uses syntax similar to using COM components in managed code, search by using the
LONDON\MOC. phrase Using COM Types in Managed Code.
Module 5: Interoperating with Managed Objects 35
8. Compile and run the a. For more information about building and debugging your
application. Add an applications, see the following resource:
OrderItemControl control by • The Visual Studio .NET Help documentation. Search by using
clicking the New Order Item the phrases Default and Custom Builds and Using the
button. Right-click the Debugger.
ComboBox within the
OrderItemControl, and click
Show Inventory. Repeat this
for other products.
Exercise 2
Calling Win32 APIs from a .NET-Based Application
In this exercise, you create a class that exposes a Win32 API. You will then invoke the Win32 API
by using your class from a Windows Forms application. The PlaySound function takes three
arguments and returns a Boolean value that indicates whether or not the function was able to play
the sound file. The arguments include:
pszSound
A string that defines the name of the sound file.
hmod
Handle to the executable file that contains the resource to be loaded. This parameter must be NULL
unless SND_RESOURCE is specified in fdwSound.
fdwSound
Flags that are used to determine how the sound is played. Examples of flags include whether the
sound should play asynchronously or whether it should loop.
Scenario
You decide to add sound effects to the Purchase Order application that will notify users when they
successfully save an order and when they successfully update their orders to the database. However,
the Win32 APIs that are responsible for playing media files are not exposed by the .NET
Framework. You must create a class that exposes the winmm.dll and allows you to call the
PlaySound API.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab05_1\Ex02\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab05_1\Ex02\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open Visual Studio .NET. a. For more information about opening a project file, see the following
Open the resource:
PurchaseOrderApplication.sln • The Visual Studio .NET Help documentation. For additional
file. To open the solution file, information about opening a project file, in Search, select the
browse to Search in titles only check box, then search by using the phrase
install_folder\Labfiles\ Open Project Dialog Box.
Lab05_1\Ex02\Starter\
OrderApplication.
2. Add the Save.wav sound file a. For more information about adding new items to a project, see the
located in following resource:
install_folder\Labfiles\ • The Visual Studio .NET Help documentation. Search by using
Lab05_1\Ex02\Starter to the the phrase Adding Projects and Items to the New Application.
Bin directory of the
PurchaseOrderApplication
project.
Module 5: Interoperating with Managed Objects 37
3. Add a new class to the a. For more information about adding new items to a project, see the
PurchaseOrderApplication following resource:
project and name it • The Visual Studio .NET Help documentation. Search by using
Win32PlaySound.cs. the phrase Adding Projects and Items to the New Application.
4. Create a function that exposes a. For more information about creating functions that expose WIN32
the Win32 PlaySound DLLs, see the following resources:
function in the winmm.dll. • Lesson: Calling Win32 APIs from Windows Forms Applications
in Module 5, “Interoperating with Managed Objects,” in Course
2555A, Developing Microsoft .NET Applications for Windows
(Visual C# .NET).
• Practice: Calling Win32 APIs in Module 5, “Interoperating with
Managed Objects,” in Course 2555A, Developing
Microsoft .NET Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation. For help with using
COM components in managed code, search by using the phrase
Consuming Unmanaged DLL Functions.
5. Open MainForm in the Code a. For more information about creating functions that expose WIN32
Editor. Use the Task List to DLLs, see the following resources:
locate the code section 'TODO • Lesson: Calling Win32 APIs from Windows Forms Applications
1. Use the Win32PlaySound in Module 5, “Interoperating with Managed Objects,” in
class and call the Win32 Course 2555A, Developing Microsoft .NET Applications for
PlaySound function if the Windows (Visual C# .NET).
soundOn Boolean value is
True. Call the PlaySound • Practice: Calling Win32 APIs in Module 5, “Interoperating with
function with “Save.wav” as Managed Objects,” in Course 2555A, Developing
the name of the media file, a 0 Microsoft .NET Applications for Windows (Visual C# .NET).
for the second argument, and a • The .NET Framework SDK documentation. For help with using
0 for the third argument. COM components in managed code, search by using the phrase
Consuming Unmanaged DLL Functions.
6. Compile and run the a. For more information about building and debugging your
application. Click the New applications, see the following resource:
Order Item button, and then • The Visual Studio .NET Help documentation. Search by using
click the Save Order button to the phrases Default and Custom Builds and Using the
save an order. Debugger.
Overview 1
Lesson: Printing from a Windows Forms
Application 2
Lesson: Using the Print Preview,
Page Setup, and Print Dialogs 16
Lesson: Constructing Print Document
Content by Using GDI+ 32
Lesson: Creating Reports by Using
Crystal Reports 47
Review 56
Lab 6.1: Printing Formatted Documents 58
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 6: Printing and Reporting in Windows Forms Applications iii
Instructor Notes
Presentation: This module provides students with an overview of how to print and create
90 minutes reports in Windows Forms applications, which are a part of the new
Microsoft® .NET Framework.
Lab:
45 minutes After completing this module, students will be able to:
Print documents in a Windows Forms application.
Use the printing dialog boxes of Microsoft Visual Studio® .NET in a
Windows Forms application.
Use GDI+ to construct print document content.
Create and format reports by using Crystal Reports.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_06.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Complete the demonstration, practices and lab.
iv Module 6: Printing and Reporting in Windows Forms Applications
Overview
What
What
About
About User
User
How?
How? 1. PrintDocument object Support?
Support?
• Enables printing
5. Print method
• Sends content to printer
4. Standard Dialog boxes for
But
But How
How Do
Do II printing
Actually • PrintPreviewDialog
Actually • PageSetupDialog
Print?
Print? • PrintDialog
4. Use the standard print dialog boxes available in Visual Studio .NET.
User support can be added by using the three standard dialog boxes that are
provided in the Design view of Toolbox. The standard dialog boxes provide
an easy way of adding powerful end user support in your applications with a
familiar user interface (UI).
PrintDocument Object
PrintDocument object
Provides the ability to print a document
Provides properties that describe what to print
PrintDocument
PrintDocument PrintDocument
PrintDocument PrintDocument
PrintDocument
Properties
Properties Events
Events Methods
Methods
DefaultPageSettings
DefaultPageSettings BeginPrint
BeginPrint Dispose
Dispose
DocumentName
DocumentName EndPrint
EndPrint Print
Print
PrintController
PrintController PrintPage
PrintPage
PrinterSettings
PrinterSettings QueryPageSettings
QueryPageSettings
Note: The check marks indicate the most commonly used properties, events,
and methods of the PrintDocument object
PrintDocument events The PrintPage event is used to generate the content of the print document, and
it is in the PrintPage event handler that you must include your own code to
indicate when the document has additional pages of content to print.
The following table describes some additional events of the PrintDocument
object that enable you to print output.
Event Description
BeginPrint Occurs when the Print method is called and before the
first page of the document prints. One example of when
to use BeginPrint is when you want to notify the user
about how many pages there are in a print job.
EndPrint Occurs when the last page of the document has printed.
One example of when EndPrint can be used is when you
want to signal the user that the print job has completed.
QueryPageSettings Occurs immediately before each PrintPage event. You
can use QueryPageSettings when you want to use
different PageSettings for one or more pages of a print
document.
For more information and a complete list of the events of the PrintDocument
object, in the Visual Studio .NET Help documentation, search by using the
phrase PrintDocument members.
PrintDocument methods After you have established the printer and default page settings and constructed
the contents of the print document, you will use the Print method to start the
print process. The Print method sends the contents of the print document to the
printer by passing the print device a Graphics object that acts as a container for
the content. The Graphics object is discussed in more detail in the PrintPage
Event and PrintPageEventArgs topic in this module.
The Dispose method releases the resources used by the PrintDocument
component.
For more information and a complete list of the methods of the PrintDocument
object, in the Visual Studio .NET Help documentation, search by using the
phrase PrintDocument members.
Module 6: Printing and Reporting in Windows Forms Applications 7
PrintPage Event
Note To modify page settings, you must handle the QueryPageSettings event
of the PrintDocument object.
Note More information about constructing print content by using the Graphics
object supplied by the PrintPageEventArgs parameter is included in the lesson
titled Constructing Print Document Content by Using GDI+ in Module 6,
“Printing and Reporting in Windows Forms Applications,” in Course 2555A,
Developing Microsoft .NET Applications for Windows (Visual C# .NET).
Module 6: Printing and Reporting in Windows Forms Applications 9
PrintDocument
PrintDocument Object
Object
•• Specify
Specify print
print settings
settings
•• Add
Add printing
printing logic
logic to
to PrintPage
PrintPage
Print Event
Event
Print Method
Method •• Call
Call the
the Print
Print method
method
•• Calls
Calls PrintPage
PrintPage
•• Checks
Checks HasMorePages
HasMorePages
DIALOGS
DIALOGS
•• Document
Document property
property of
of the
the
Dialogs
Dialogs set
set to
to the
the
PrintDocument
PrintDocument object
object
3. Add support for previewing your print document so that you can test the
code that you developed up to this point. One simple way to preview your
print document is to add a PrintPreviewControl to your Form from the
Toolbox.
4. Add additional programming logic to the PrintDocument1_PrintPage
procedure that uses the HasMorePages property to indicate whether or not
more pages must be printed. The manner in which you determine whether
HasMorePages should be set to True depends on how your print document
is being constructed.
12 Module 6: Printing and Reporting in Windows Forms Applications
____________________________________________________________
____________________________________________________________
____________________________________________________________
____________________________________________________________
14 Module 6: Printing and Reporting in Windows Forms Applications
6. In the Task List, double-click TODO: create the PrintPage event handler.
7. Add the following code statements below the TODO line and press ENTER.
private void MyPrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawString("Page " + currentPage.ToString() +
" text will go here.", myFont, myBrush, X, Y);
}
}
8. Press F5, and then click Print Preview.
9. Close the PrintPreviewDialog dialog box.
10. Use the NumericUpDown control to add a second page to your print
document, and then preview your document again.
11. Why doesn’t your application display more than one page?
The HasMorePages property of the PrintPageEventArgs object is False
by default. You must develop the programming logic for a print loop
when the print job includes more than one document page.
____________________________________________________________
____________________________________________________________
Create a print loop to ensure that all of the document pages are printed
1. Modify the contents of the if statement near the bottom of your
MyPrintPage procedure so that it appears as follows:
if (currentPage < totalPages)
{
currentPage += 1;
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
2. Start the PrintProcess application.
3. Use the NumericUpDown control to add a second page to your document,
and then preview your print document again. You should now be able to see
both pages of your print document.
Module 6: Printing and Reporting in Windows Forms Applications 15
PrintPreviewDialog
CodeExample
Example The following code shows an example of how to use the PrintPreviewDialog
control to display a print preview of a document. The example assumes that a
PrintPreviewDialog control and a PrintDocument control were added to a
Form and that the PrintPreview procedure is called from an event handler.
private void PrintPreview()
{
// ensure that the first page of the print document is shown
printPreviewDialog1.PrintPreviewControl.StartPage = 0;
____________________________________________________________
20 Module 6: Printing and Reporting in Windows Forms Applications
If time permits Examine some additional methods for displaying a print document
1. In Design view, enable the two other buttons on Form1.
2. Start the application, and use each button to display the print document.
3. Close the application, and examine the code used to display the document.
4. When would you want to use a PrintPreviewControl rather than a
PrintPreviewDialog to display a print document?
You would use a PrintPreviewControl to display a document when you
need to customize the print preview capabilities of an application.
____________________________________________________________
____________________________________________________________
3. Use the ShowDialog method to display the dialog box at run time.
To display the dialog box at run time, use the ShowDialog method as shown
in the following code.
PageDlg.ShowDialog();
4. Apply the modified page settings to your PrintDocument object.
To apply the new page settings to your document, use the
DefaultPageSettings property of the PrintDocument object.
printDocument1.DefaultPageSettings = MyPageSettings;
Example The following code shows an example of how to use the PageSetupDialog
control.
private void PageSetup()
{
try {
PageSetupDialog pageDialog = new PageSetupDialog();
if (storedPageSettings == null) {
storedPageSettings = new PageSettings();
}
pageDialog.PageSettings = storedPageSettings ;
pageDialog.ShowDialog();
catch(Exception ex) {
MessageBox.Show("An error occurred - " + ex.Message);
}
Customize sections of The user can enable sections of the PageSetup dialog box to manipulate
the PageSetup dialog printing, margin, and paper orientation, and size.
box
Use the Margins and MinMargins properties to specify margins.
pageSetupDialog1.PageSettings.Margins.Top = 200;
pageSetupDialog1.PageSettings.Margins.Left = 200;
pageSetupDialog1.PageSettings.Margins.Bottom = 100;
pageSetupDialog1.PageSettings.Margins.Right = 100;
pageSetupDialog1.MinMargins.Top = 85;
pageSetupDialog1.MinMargins.Left = 75;
pageSetupDialog1.MinMargins.Bottom = 100;
pageSetupDialog1.MinMargins.Right = 100;
6. Close the application, and then add the following code lines to the top of the
PageSetup procedure.
myPageSettings = new PageSettings();
pageSetupDialog1.PageSettings = myPageSettings;
7. Run the PageSetupDialog application, and display the Page Setup dialog
box.
8. Change the Top and Left margins to 0.5 inches, and then click OK.
9. Display a preview of the print document. Why didn’t the new settings take
effect?
Although the PageSetupDialog automatically places the new settings
into the MyPageSettings object, you still have to assign the page settings
to the PrintDocument object.
____________________________________________________________
____________________________________________________________
5. Click Cancel, close the application, and then, in the PageSetup procedure,
replace the "myPageSettings = new PageSettings();" code line with the
following code lines.
if (myPageSettings == null)
{
myPageSettings = new PageSettings();
}
6. Run the PageSetupDialog application, and use the PageSetup dialog box to
modify the document’s page settings. Notice that settings are not lost when
the dialog box is closed.
7. Close the application.
If time permits
Examine some additional members of the PageSetupDialog control
1. In the Code Editor, examine the code in the pageSetupButton_Click
procedure.
2. Remove the comment characters from the front of the code lines one section
at a time, and view the changes to the PageSetup dialog box and the Print
Preview dialog box by running the application and opening the two dialog
boxes.
3. How could you use these additional members of the PageSetupDialog
control?
These additional members could be used to customize the
PageSetupDialog and control the range of settings that a user is allowed
to select.
____________________________________________________________
____________________________________________________________
PrintDialog
CodeExample
Example The following code uses the PrintDialog control to provide the user with an
opportunity to modify printer and print job settings before printing the
document.
private void PrintDoc()
{
PrintDialog1.Document = PrintDocument1;
DialogResult userResponse;
userResponse = PrintDialog1.ShowDialog();
if (userResponse == DialogResult.OK)
{
PrintDocument1.Print();
}
}
Module 6: Printing and Reporting in Windows Forms Applications 29
6. Close the application, and then add the following code line to the top of the
PrintDoc procedure.
printDialog1.Document = printDocument1;
____________________________________________________________
Note For more information about the DialogResult object, see the Visual
Studio .NET Help documentation.
5. Run the PrintDialog application, and display the print dialog box.
6. Click OK, and then, inside in the Output File Name box, type C:\Text
7. Click OK.
Notice that a Printing dialog box opens automatically, providing the user
with an opportunity to cancel the print job.
8. Close the application, and close Visual Studio .NET.
32 Module 6: Printing and Reporting in Windows Forms Applications
What Is GDI+?
'' draw
draw lines
lines or
or outlined
outlined shapes
shapes using
using aa Pen
Pen
myGraphic.Graphics.DrawLine(myPen,X1,Y1,X2,Y2)
myGraphic.Graphics.DrawLine(myPen,X1,Y1,X2,Y2) ;;
'' draw
draw filled
filled shapes
shapes using
using aa Brush
Brush
myGraphic.FillRectangle(myBrush,X1,Y1,X2,Y2);
myGraphic.FillRectangle(myBrush,X1,Y1,X2,Y2);
'' draw
draw text
text using
using aa Font
Font and
and aa Brush
Brush
myGraphic.DrawString(myText,myFont,myBrush,X1,Y1);
myGraphic.DrawString(myText,myFont,myBrush,X1,Y1);
Graphics object The Graphics object provides an extensive assortment of methods that can be
methods used to draw text, lines, and shapes. There are also methods for scaling,
transforming, and measuring the contents that have or will be drawn on its
surface. Some of the most common methods are listed in the following table.
Method Description
Clear Clears the entire drawing surface and fills it with the
specified background color.
DrawLine Draws a line connecting the two points specified by
coordinate pairs.
Example The following code examples show how to draw objects by using the Graphics
object provided by the PrintPageEventArgs parameter of the
PrintDocument.PrintPage event.
//Create a graphics object
Graphics myGraphics = this.CreateGraphics();
Pens A pen
pen is
is required
required to
to draw
draw lines and
and outlined
outlined shapes
shapes
Pen
Pen myPen
myPen == new
new Pen(Color.Blue);
Pen(Color.Blue);
Brushes A brush
brush is
is required
required to draw
draw filled
filled shapes
shapes or
or draw
draw text
text
SolidBrush
SolidBrush myBrush
myBrush == new
new SolidBrush(Color.Blue);
SolidBrush(Color.Blue);
Fonts A font
font is
is required
required to
to draw
draw text of aa single
single size
size or
or style
Font
Font myFont
myFont == new
new Font("Arial",
Font("Arial", 12);
12);
Procedure: Creating Brush objects are required for drawing text and filled shapes. You can create
brushes brushes that produce Solid, Hatched, Textured, and Gradient fills.
• Create a new Brush.
The following code examples demonstrate creating a solid blue brush and a
linear gradient brush by using white and light blue blended horizontally.
Brush brushBlue = new SolidBrush(Color.Blue);
LinearGradientBrush myGrBrush = new LinearGradientBrush(
lgRectangle,
Color.White,
Color.LightBlue,
LinearGradientMode.Horizontal);
For more information about Hatched, Textured, and Gradient Brushes see
“Brushes and Filled Shapes” in the .NET Framework software development kit
(SDK) and see Appendix A, “Using Filled Shapes and Images,” in the student
workbook.
Procedure: Creating Before you can draw text with GDI+, you must construct a Font object. The
fonts declaration statement for a Font object can include parameters for the
FontFamily (such as Arial), Size, Style, and the GraphicsUnits used by the
Size parameter. The FontFamily and Size properties are required when creating
a new font.
• Create a new Font object.
The following code example creates an Arial font of size 10 and a Lucida
font with a style setting of bold and a size of 12 millimeters.
Font smallFont = new Font("Arial", 10);
Font largeFont;
largeFont = new Font("Lucida",
12,
FontStyle.Bold,
GraphicsUnit.Millimeter);
38 Module 6: Printing and Reporting in Windows Forms Applications
To draw text
1. Calculate the location for the text
2. Select the Font and Brush that you want to use for this text
3. Call the Graphics.DrawString method
e.Graphics.DrawString(myText,
e.Graphics.DrawString(myText, myFont,
myFont, myBrush,
myBrush, X1,
X1, Y1);
Y1);
To measure text
textWidth
textWidth == e.Graphics.MeasureString(myText,myFont).Width;
e.Graphics.MeasureString(myText,myFont).Width;
textHeight
textHeight ==
e.Graphics.MeasureString(myText,myFont).Height;
e.Graphics.MeasureString(myText,myFont).Height;
Procedure: Measuring To measure text, add the code as shown to the PrintPage event handler.
text
The following code measures the width and height of the specified string.
textWidth = e.Graphics.MeasureString(myText, myFont).Width;
textHeight = e.Graphics.MeasureString(myText,
myFont).Height;
Another option for getting the height of your text is to use the GetHeight
method for Font and pass it the Graphics object as follows.
textHeight = myFont.GetHeight(e.Graphics);
40 Module 6: Printing and Reporting in Windows Forms Applications
The following code shows that if no text is being read from StreamReader, the
printing exits, or else it checks if there are more pages to print.
// inside PrintPage event handler
while (currentLine < linesPerPage)
{
textLine = StreamToPrint.ReadLine();
if(textLine == null)
{
break;
}
//If more lines of text exist in the file, print another page.
if (TextLine != null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
42 Module 6: Printing and Reporting in Windows Forms Applications
____________________________________________________________
3. Run your application, and click Print Preview to view the GDI+ output.
4. Close the preview form, click Draw gradient text, and then click Print
Preview.
5. How would you draw right-aligned text?
You can draw right-aligned text by measuring the text string and
establishing a horizontal position that is equal to the right-side position
that you define minus the width of the text string.
____________________________________________________________
____________________________________________________________
If time permits, examine the code used to create the gradient filled text.
6. Save your application, and then close Visual Studio .NET.
Module 6: Printing and Reporting in Windows Forms Applications 47
Crystal Reports
Crystal Reports
Is the standard reporting tool in .NET
Allows you to create a report from the beginning or use
one of the Report Expert Wizards
Benefits
You can use any programming language
Report viewers for Windows-based and Web applications
Run time customization of reports
Easy interaction with reports
Data visualization and analysis capabilities
http://msdn.microsoft.com/vstudio/partners/tools
/crystaldecisions.asp
Open
Open the
the Choose
Report Choose a
a Choose a
Report template
template data source
Expert
Expert
2. Choose a template.
Report Expert provides various templates for creating a report. Some of the
templates are:
• Standard
• Form Letter
• Form
• Cross-Tab
• Subreport
• Mail Label
• Drill Down
• For more information about each of the templates, in the
Visual Studio .NET Help documentation, search by using the phrase
Crystal Reports Experts.
3. Choose a data source.
Select the data source that your report will reference. You can use more than
one data source in a report. You also choose the database tables that you
want to use in the report. Crystal Reports can automatically link the tables,
or you can specify how you want the tables linked. Database tables are
linked so that records from one database match related records from
another.
4. Select the required fields.
After selecting the data source, select the fields that you want to display on
the report.
5. Group items and create formulas.
When you first insert a database field into your report, the data in the fields
appears in the order in which it was originally entered into the database.
Grouping, sorting, and totaling help turn disorganized data into useful
information on a report.
In most cases, the data needed for a report already exists in database table
fields. Sometimes, you need to put additional data on the report that does
not exist in any of the data fields. In cases such as this, you must create a
formula. There are four different groups of formulas in Crystal Reports:
report, conditional formatting, selection, and search. The majority of
formulas in a report use the report and conditional formatting formulas.
For more information about how to create and use these formulas, in the
Visual Studio .NET Help documentation, search by using the phrase
Formula Overview.
Module 6: Printing and Reporting in Windows Forms Applications 51
private
private CrystalReport.StoreSalesReport
CrystalReport.StoreSalesReport report;
report;
storeSalesSqlDataAdapter.Fill(storeSalesDataSet1);
storeSalesSqlDataAdapter.Fill(storeSalesDataSet1);
report
report == new
new CrystalReport.StoreSalesReport();
CrystalReport.StoreSalesReport();
report.SetDataSource(storeSalesDataSet1);
report.SetDataSource(storeSalesDataSet1);
crystalReportViewer1.ReportSource
crystalReportViewer1.ReportSource == report;
report;
Note Use the existing connection information for the Pubs database if it
already exists and skip to the next procedure.
Review
Printing from a Windows Forms Application
Using the Print Preview, Page Setup, and Print Dialogs
Constructing Print Document Content by Using GDI+
Creating Reports by Using Crystal Reports
Note This lab focuses on the concepts in Module 6, “Printing and Reporting in
Windows Forms Applications,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET). As a result, this lab may not
comply with Microsoft security recommendations.
Scenario Members of the Northwind Traders sales force need to print purchase order
documents while they are at a customer site. The purchase order documents—
form number NT-2555P (portrait) and NT-2555L (landscape)—have specific
requirements associated with document layout, text formatting, and the
appearance of 2-D vector graphics objects. You are an application developer at
Northwind Traders. The department that you work in is developing a purchase
order application that will be used by the Northwind Traders sales force. You
have been assigned the task of completing the code sections of the purchase
order application that support printing. The Northwind Traders Legal and
Media departments have given you the three requirements tables that describe
these forms. The tables are included at the end of this lab.
To complete this task, you must add basic print support to a project, enable
users to control the print process by using dialog boxes, and develop the code
statements necessary to complete the construction of the print document by
using GDI+.
Estimated time to
complete this lab:
45 minutes
60 Module 6: Printing and Reporting in Windows Forms Applications
Exercise 1
Adding Print Support to an Application
In this exercise, you will open two existing Visual Studio .NET projects, create a reference to the
Drawing and Drawing2D namespaces, create a procedure that handles the PrintPage event,
develop code that ensures that all pages of a print document are included in a print job, and add
support for the PrintPreviewDialog, PageSetupDialog, and PrintDialog dialog boxes to your
application. This exercise assesses your knowledge of the print process and your ability to use the
PrintDocument class and the three dialog boxes to provide the application user with control of the
print process.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab06_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab06_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
Scenario
The user interface of the purchase order application has been developed and the underlying code is
functioning as intended. You have reviewed the application code and the code contained in a
custom document printing class that inherits from the PrintDocument class. The custom printing
class that your department created will be used to print the purchase order forms that are used by
Northwind Traders. Most of the code that is used to construct (draw) purchase order documents has
already been written. You will now begin adding code to your application and the printing class so
that users can print purchase order documents.
The Northwind Traders sales force has requested that the application be capable of printing in either
portrait or landscape mode and that page margins be fixed in accordance with the Legal department
and Media department requirements for the purchase order document. The sales force would also
like to have the option to review the purchase order document with a customer before it is printed.
As the application developer, you will start by opening the purchase order application and the
printing class in separate projects and checking to see what code still needs to be added to the two
projects to support document printing. Then, you will add support for the PrintPreviewDialog. In
addition to providing the sales force with an easy way to preview a purchase order before printing,
the PrintPreview dialog box enables you to view the print document as you develop the code that
constructs the document. You will then add support for the PageSetupDialog class to your
application and create the code that is required to show this dialog box. By checking various page
layout settings, you can ensure that the print document is constructed in accordance with the page
layout parameters needed by your Legal and Media departments. Because your customer also wants
the option to print without previewing the document, you will also add support for the PrintDialog
class.
Module 6: Printing and Reporting in Windows Forms Applications 61
1. Open two instances of a. For more information about opening a project file and starting an
Visual Studio .NET. In the application, see the following resource:
first instance, open the • The Visual Studio .NET Help documentation. For additional
Lab06Application.sln file. information about opening a project file, in Search, select the
In the second instance, open Search in titles only check box, then search by using the phrase
the Lab06Class.sln file. To Open Project Dialog Box. For additional information about
open the solution files, in starting an application from in Designer, in Index, search by using
the Lab06Application and the phrase Debugging Windows Applications.
Lab06Class folders,
respectively, browse to
install_folder\Labfiles\
Lab06_1\Ex01\Starter.
3. Use the Task List in the a. For more information about the PrintPage event and the
Lab06Class.cs file to locate PrintPageEventArgs class, see the following resources:
the code section 'TODO: • Lesson: Printing From a Windows Forms Application in Module 6,
Create the declaration “Printing and Reporting in Windows Forms Applications,” in
statement for the PrintPage Course 2555A, Developing Microsoft .NET Applications for
Procedure' and then create Windows (Visual C# .NET).
the declaration statement for
a procedure named • Practice: Adding Print Support to a Windows Forms Application in
Lab06Class_PrintPage that Module 6, “Printing and Reporting in Windows Forms
handles the PrintPage Applications,” in Course 2555A, Developing Microsoft .NET
event. Add code statements Applications for Windows (Visual C# .NET).
to the procedure that call the • The Visual Studio .NET Help documentation. For additional
PrintingEmptyForm2555 information about the PrintPage event, search by using the phrases
and PrintingContentsForm Creating Standard Windows Forms Print Jobs and
2555 procedures. PrintDocument.PrintPage Event. For additional information
about the PrintPageEventArgs class, search by using the phrases
The PrintPage procedure PrintPageEventArgs Class and PrintPageEventArgs Members.
handles all requests for a
page of the print document.
The PrintPageEventArgs
class that is passed to the
PrintPage procedure
contains the Graphics
object on which you
construct the print
document.
4. Use the Task List in the a. For more information about how to specify that there are additional
Lab06Class.cs file to locate pages to be printed, see the following resources:
the code section 'TODO: • Lesson: Printing From a Windows Forms Application in Module 6,
Determine if more pages “Printing and Reporting in Windows Forms Applications,” in
must be printed' and then Course 2555A, Developing Microsoft .NET Applications for
create a code section that Windows (Visual C# .NET).
tells the event handler for
the PrintPage event that • Practice: Adding Print Support to a Windows Forms Application in
there are more pages to print Module 6, “Printing and Reporting in Windows Forms
when currentPurchaseItem Applications,” in Course 2555A, Developing Microsoft .NET
Number is less than Applications for Windows (Visual C# .NET).
totalPurchaseItems, • The Visual Studio .NET Help documentation. Search by using the
otherwise specify that there phrase PrintPageEventArgs.HasMorePages Property.
are no more pages to print.
5. Rebuild the Lab06Class a. For more information about referencing an external class, see the
project. In the following resource:
Lab06Application project, in • The Visual Studio .NET Help documentation. Search by using the
Solution Explorer, update phrases Project References, Adding and Removing References,
the reference to Lab06Class. and Preparing and Managing Builds.
8. Use the Task List to locate a. For more information about adding the PageSetupDialog class to an
the code section 'TODO: application, see the following resources:
Create an instance of the • Lesson: Using the Print Preview, Page Setup, and Print Dialogs in
PageSetupDialog class'. Module 6, “Printing and Reporting in Windows Forms
Add code below the Applications,” in Course 2555A, Developing Microsoft .NET
comment line that creates an Applications for Windows (Visual C# .NET).
instance of the
PageSetupDialog class • Practice: Using the PageSetupDialog Control in Module 6,
named “Printing and Reporting in Windows Forms Applications,” in
form2555SetupDialog. Course 2555A, Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
The PageSetupDialog class • The Visual Studio .NET Help documentation. Search by using the
enables users to modify the phrases Introduction to the Windows Forms PageSetupDialog
page settings of a print Component, PageSetupDialog Class, and PageSetupDialog
document. You can use it to Members.
test the code that constructs
the print document by
displaying the print
document with various page
setting values. You will get
a chance to modify page
settings later in this lab
exercise.
9. Use the Task List to locate a. For more information about adding support for the PrintDialog class to
the code section 'TODO: your application, see the following resources:
Create an instance of the • Lesson: Using the Print Preview, Page Setup, and Print Dialogs in
PrintDialog class'. Add code Module 6, “Printing and Reporting in Windows Forms
below the comment line that Applications,” in Course 2555A, Developing Microsoft .NET
creates an instance of the Applications for Windows (Visual C# .NET).
PrintDialog class named
form2555PrintDialog. • Practice: Using the PageSetupDialog Control in Module 6,
“Printing and Reporting in Windows Forms Applications,” in
Course 2555A, Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrases Introduction to the Windows Forms PrintDialog
Component and PrintDialog Component.
Module 6: Printing and Reporting in Windows Forms Applications 65
10. Use the Task List to locate a. The purchaseItemNumber and purchaseItemCount variables are passed
the code section 'TODO: Set to the Lab06Class class (inherits from PrintDocument) and used to
purchaseItemNumber and determine when HasMorePages should be set to True or False. The
purchaseItemCount'. Add purchaseItemNumber variable is the current purchase item being
code below the TODO printed, and the purchaseItemCount variable is the total number of
comment that assigns a purchase items in the current purchase order.
value of 0 to the
MainModule.purchaseItem
Number variable and assigns
the value of the Count
property of
MainModule.mainPOForm.
ProductOrderPanel.Controls
to the
MainModule.purchaseItem
Count variable.
12. Rebuild and then start the a. For more information about building and debugging your applications,
Lab06Application project. and for information about running the Purchase Order application, see
Use the File menu or the the following resources:
Print button on the ToolBar • Demonstration, Purchase Order Application, in Module 0,
control to demonstrate that “Introduction,” in Course 2555A, Developing Microsoft .NET
you can now display the Applications for Windows (Visual C# .NET).
print preview dialog box.
Close the Lab06Application • The Visual Studio .NET Help documentation. Search by using the
executable file. phrases Default and Custom Builds and Using the Debugger.
14. Use Task List to locate the a. For more information about members of the PageSetupDialog class,
code section 'TODO: see the following resources:
Disable user access to the • Lesson: Using the Print Preview, Page Setup, and Print Dialogs in
Margins section of the Module 6, “Printing and Reporting in Windows Forms
dialog'. Add code below the Applications,” in Course 2555A, Developing Microsoft .NET
comment line that disables Applications for Windows (Visual C# .NET).
user access to the margin
settings. • Practice: Using the PageSetupDialog Control in Module 6,
“Printing and Reporting in Windows Forms Applications,” in
Restricting user access to Course 2555A, Developing Microsoft .NET Applications for
only those page settings that Windows (Visual C# .NET).
are required will help to • The Visual Studio .NET Help documentation. Search by using the
eliminate support issues that phrase PageSetupDialog Members.
would be generated when
users modify settings in an
unpredictable manner.
15. Rebuild and then start the a. For more information about building and debugging your application,
Lab06Application project. use the following resource:
Use the File menu to open • The Visual Studio .NET Help documentation. Search by using the
the page setup dialog box phrases Default and Custom Builds and Using the Debugger.
and change the page
orientation from portrait to
landscape. Use the print
preview dialog box to view
the print document. Close
the Lab06Application
executable file.
16. Use the Task List to locate a. For more information about using DialogResult, see the following
the code section 'TODO: resources:
Determine if the document • Lesson: Using the Print Preview, Page Setup, and Print Dialogs in
should be printed'. Add code Module 6, “Printing and Reporting in Windows Forms
statements below the Applications,” in Course 2555A, Developing Microsoft .NET
comment line that will send Applications for Windows (Visual C# .NET).
form2555Document to the
printer when the application • Practice: Using the PageSetupDialog Control in Module 6,
user clicks OK to close the “Printing and Reporting in Windows Forms Applications,” in
print dialog. Course 2555A, Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
You must use DialogResult • The Visual Studio .NET Help documentation. Search by using the
to determine whether the phrase Retrieving the Result for Dialog Boxes.
user closed PrintDialog by
clicking Cancel or by
clicking OK.
68 Module 6: Printing and Reporting in Windows Forms Applications
17. Rebuild and then start the a. For more information about building and debugging your application,
Lab06Application project. see the following resource:
Use the File menu to • The Visual Studio .NET Help documentation. Search by using the
demonstrate that the print phrases Default and Custom Builds and Using the Debugger.
dialog box is working as
intended. Close the
Lab06Application
executable file.
18. Save the changes that you Additional information is not necessary for this task.
made to your code, and then
close both solution files.
Module 6: Printing and Reporting in Windows Forms Applications 69
Exercise 2
Creating Printed Output by Using GDI+
In this exercise, you will create pens, brushes, and fonts and then use them to draw 2-D vector
objects and text at specific locations on a print document. This exercise provides you with an
opportunity to assess your ability to complete the construction of a print document by using GDI+.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab06_1\Ex02\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab06_1\Ex02\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
Scenario
Initial testing has revealed that the custom printing class does not accurately reproduce the legal and
official representation of the organization’s purchase order documents—Northwind Traders forms
NT-2555P and NT-2555L. To correct this problem, you will review the data contained in the
NT-2555P and NT-2555L requirements tables (the tables of data from the Media and Legal
Departments that are included after this exercise) and develop GDI+ code statements that produce
the required 2-D vector objects and text. You will begin by creating some of the pens, brushes, and
fonts required to construct portions of the forms. After that, you will develop the code that draws
some of the 2D vector shapes that are used to create the base forms. The last step will be to develop
the code used to draw some of the text that appears on the NT-2555P and NT-2555L forms.
1. In the first instance of a. For more information about opening a project file and starting an
Visual Studio .NET, browse application, see the following resources:
to install_folder\Labfiles\ • The Visual Studio .NET Help documentation. For additional
Lab06_1\Ex02\Starter and information about opening a project file, in Search, select the
open the Search in titles only check box, then search by using the phrase
Lab06Application.sln file. Open Project Dialog Box. For additional information about
In the second instance, starting an application from in Designer, in Index, search by using
browse to the phrase Debugging Windows Applications.
install_folder\Labfiles\
Lab06_1\Ex02\Starter and
open the Lab06Class.sln
file.
2. Open the code editor view a. For more information about creating pens, see the following resources:
of the Lab06Class.cs file • Lesson: Constructing Print Document Content Using GDI+ in
and use Task List to locate Module 6, “Printing and Reporting in Windows Forms
the code section 'TODO: Applications,” in Course 2555A, Developing Microsoft .NET
Create the pageBorderPen'. Applications for Windows (Visual C# .NET).
Add code below the
comment line that creates a • Practice: How to Construct Print Document Content Using GDI+ in
pen named pageBorderPen Module 6, “Printing and Reporting in Windows Forms
and that has the following Applications,” in Course 2555A, Developing Microsoft .NET
characteristics: Applications for Windows (Visual C# .NET).
Color = Gray, • The Visual Studio .NET Help documentation. Search by using the
width = 3, phrases Pens, Brushes, and Colors; Setting Pen Width and
DashStyle = Dash. Alignment (in the .NET Framework Developer’s Guide) and
Using a Brush to Fill Shapes.
70 Module 6: Printing and Reporting in Windows Forms Applications
3. Use the Task List to locate a. For more information about creating brushes, see the following
the code section 'TODO: resources:
Create the footerBrush'. Add • Lesson: Constructing Print Document Content Using GDI+ in
code below the comment Module 6, “Printing and Reporting in Windows Forms
line that creates a solid black Applications,” in Course 2555A, Developing Microsoft .NET
brush named footerBrush. Applications for Windows (Visual C# .NET).
• Practice: How to Construct Print Document Content Using GDI+ in
Module 6, “Printing and Reporting in Windows Forms
Applications,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrases Pens, Brushes, and Colors; Setting Pen Width and
Alignment and Using a Brush to Fill Shapes.
4. Use the Task List to locate a. For more information about creating fonts, see the following resources:
the code section 'TODO: • Lesson: Constructing Print Document Content Using GDI+ in
Create the footerFont'. Add Module 6, “Printing and Reporting in Windows Forms
code below the comment Applications,” in Course 2555A, Developing Microsoft .NET
line that creates a Private Applications for Windows (Visual C# .NET).
font named footerFont and
that has the following • Practice: How to Construct Print Document Content Using GDI+ in
characteristics: family = Module 6, “Printing and Reporting in Windows Forms
Microsoft Sans Serif, Applications,” in Course 2555A, Developing Microsoft .NET
emSize = 7. Applications for Windows (Visual C# .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrases Constructing Font Families and Fonts (in the .NET
Framework Developer’s Guide), Fonts and Text (in the .NET
Framework Developer’s Guide), and Using GDI+ Managed
Classes (in the .NET Framework Developer’s Guide).
Module 6: Printing and Reporting in Windows Forms Applications 71
5. Use the Task List to locate a. For more information about drawing 2-D vector shapes, see the
the code section 'TODO: following resources:
Draw the border of the • Lesson: Constructing Print Document Content Using GDI+ in
Customer Address table'. Module 6, “Printing and Reporting in Windows Forms
Create the code statements Applications,” in Course 2555A, Developing Microsoft .NET
required to draw the border Applications for Windows (Visual C# .NET).
of the customer address
table by using the following • Practice: How to Construct Print Document Content Using GDI+ in
variables: Module 6, “Printing and Reporting in Windows Forms
sectionOutlinePen, Applications,” in Course 2555A, Developing Microsoft .NET
customerSectionLeft, Applications for Windows (Visual C# .NET).
customerSectionTop, • The Visual Studio .NET Help documentation. Search by using the
customerSectionWidth, phrases Pens, Lines, and Rectangles; Using a Pen to Draw Lines
customerSectionHeight. and Rectangles; and Graphics Methods.
7. Use the Task List to locate a. For more information about filled shapes, see the following resources:
the code section 'TODO: • Lesson: Constructing Print Document Content Using GDI+ in
Draw the shaded area of the Module 6, “Printing and Reporting in Windows Forms
Purchase Items table'. Applications,” in Course 2555A, Developing Microsoft .NET
Create the code statements Applications for Windows (Visual C# .NET).
required to draw the shaded
portion of the Purchase • Practice: How to Construct Print Document Content Using GDI+ in
Items table by using the Module 6, “Printing and Reporting in Windows Forms
following variables: Applications,” in Course 2555A, Developing Microsoft .NET
purchaseSectionHeaderRow Applications for Windows (Visual C# .NET).
BackgroundBrush, • The Visual Studio .NET Help documentation. For additional
purchaseSectionLeft, information about drawing 2-D filled shapes, search by using the
purchaseSectionTop, phrases Drawing Lines and Shapes with GDI+ and GDI+
purchaseSectionWidth, Graphics.
purchaseSectionRowHeight.
9. Use the Task List to locate a. For more information about drawing and measuring text, see the
the code section 'TODO: following resources:
Draw the footer text'. Create • Lesson: Constructing Print Document Content Using GDI+ in
the code statements required Module 6, “Printing and Reporting in Windows Forms
to draw the contents of the Applications,” in Course 2555A, Developing Microsoft .NET
printText variable by using Applications for Windows (Visual C# .NET).
the variables footerFont,
footerBrush, • Practice: How to Construct Print Document Content Using GDI+ in
horizontalPosition, and Module 6, “Printing and Reporting in Windows Forms
verticalPosition, where Applications,” in Course 2555A, Developing Microsoft .NET
horizontalPosition has a Applications for Windows (Visual C# .NET).
value equal to the left • The Visual Studio .NET Help documentation. Search by using the
margin value of the page phrases Drawing Text with GDI+ and Fonts and Text.
and verticalPosition has a
value equal to the bottom
margin value of the page
minus the height of the font.
Top Margin 1.0 inch (25.4 mm) 0.85 inch (21.6 mm)
Left Margin 1.2 inch (30.5 mm) 1.6 inch (40.6 mm)
Right Margin 0.8 inch (20.3 mm) 1.0 inch (25.4 mm)
Bottom Margin 1.0 inch (25.4 mm) 0.7 inch (17.8 mm)
Document Title Area 10% of available Same as NT-2555P
height*, full width
Address Table 25% of available Same as NT-2555P
height*, full width
Purchase Table 62.5% of available Same as NT-2555P
height*, full width
This table is incomplete. The complete Page Layout Table for Forms NT-2555P
and NT-2555L table would contain additional information required to recreate the
NT-2555P and NT-2555L forms. Information has been left out of this table because
the additional information is not required to complete the exercises in this lab.
* The available height is the distance between the top and bottom margins.
Overview 1
Lesson: The .NET Asynchronous
Programming Model 2
Lesson: The Asynchronous Programming
Model Design Pattern 7
Lesson: How to Make Asynchronous Calls
to Any Method 19
Lesson: Protecting State and Data in a
Multithreaded Environment 27
Review 34
Lab 7.1: Making Asynchronous Calls to an
XML Web Service 36
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 7: Asynchronous Programming iii
Instructor Notes
Presentation: In this module, students learn how to use the techniques of asynchronous
90 minutes programming and multithreading to avoid blocking the user interface of an
application.
Lab:
15 minutes After completing this module, students will be able to:
Describe the Microsoft® .NET Framework asynchronous programming
model.
Modify a client application to use built-in .NET Framework support for
asynchronous calls to methods.
Describe how to add explicit support for asynchronous calls to any method.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_07.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Review the animation for this module.
Complete the demonstrations, practice, and lab.
iv Module 7: Asynchronous Programming
Overview
Submit
Submit reports
reports
to
to server
server
2. In the main application window, click the View Submitted Reports button.
3. Notice that the application is not responsive while the XML Web service is
being called. You can test this by trying to move the main application
window, or by trying to minimize the main application window before the
expense report list window opens.
4. After the expense report list window opens, close the application.
Module 7: Asynchronous Programming 5
Completion
Completion Technique
Technique Comments
Comments
Supply
Supply aa callback
callback delegate,
delegate, method
method will
will be
be
Use
Use aa callback
callback called
called when
when operation
operation completes
completes
Poll
Poll the
the IAsyncResult
IAsyncResult interface’s
interface’s
Poll
Poll IsCompleted
IsCompleted property
property
Call
Call the
the EndOperation
EndOperation Call
Call the
the EndOperation
EndOperation method
method and
and block
block till
till
method
method operation
operation completes
completes
Wait
Wait onon IAsyncResult
IAsyncResult interface’s
interface’s WaitHandle
WaitHandle
Wait
Wait on
on aa handle
handle property,
property, then
then call
call EndOperation
EndOperation method
method
EndOperation The EndOperation technique can be used when you have a finite amount of
work to be done on the main thread that is not dependent on the asynchronous
call. After that work is done and your application must receive the results of the
asynchronous operation before it can do any further meaningful work, you can
call the EndOperation method to block until the asynchronous operation
completes.
Be aware that an EndOperation might block forever if the asynchronous call
never completes due to a network or server failure. Therefore, the wait on a
handle technique might be more appropriate to use in certain situations.
Wait on a handle With the wait on a handle technique, you can specify a maximum time-out to
wait for an asynchronous operation to complete. You can also use the
System.Threading.WaitHandle.WaitAll method to wait on multiple
asynchronous operations and be notified when they have all completed.
For more information about using the polling and wait on a handle techniques,
see Module 14, “Threading and Asynchronous Programming” in Course
2349B, Programming with the Microsoft .NET Framework (Microsoft Visual
C# .NET).
10 Module 7: Asynchronous Programming
Invoke
Invoke the
the BeginOperation
BeginOperation method,
method, passing
passing itit the
the callback delegate
delegate
Inside
Inside the
the callback,
callback, invoke the
the EndOperation
EndOperation method
method to
to notify
notify that
that
asynchronous
asynchronous work
work is
is complete
complete and
and to return
return results
Return
Return control to the main thread and update UI
Get
Get reports
reports Callback Delegate{
BeginOperation
{…}
EndOperation
Update UI }
The remaining topics in this lesson provide the programming details related to
these steps.
Module 7: Asynchronous Programming 11
Create
Create the
the asynchronous
asynchronous callback
callback delegate
delegate
Asynchronous callback delegate
AsyncCallback
AsyncCallback delCB
delCB == new
new AsyncCallback(
AsyncCallback(
this.AsyncCB);
this.AsyncCB);
Invoke
Invoke the
the BeginOperation
BeginOperation method,
method, passing
passing itit the
the callback delegate
delegate
WS.BeginGetReportsForEmployee(
WS.BeginGetReportsForEmployee(
username,
username, pwdToken,
pwdToken,
RecordCursor,
RecordCursor, 10,
10, TotalNumRecords,
TotalNumRecords,
delCB,
delCB, null);
null);
Inside
Inside the
the callback,
callback, invoke the
the EndOperation
EndOperation method
method to
to retrieve the
the
results
results of
of the
the asynchronous
asynchronous call
call
//
// Inside
Inside the
the callback
callback method,
method, AsyncCB,
AsyncCB, call
call
//
// EndOperation
EndOperation to
to get
get results
results of
of the
the async
async call
call
void
void AsyncCB
AsyncCB (IAsyncResult
(IAsyncResult ar)
ar)
{{ Invoke EndOperation method
...
...
DataSet
DataSet ds
ds == WS.EndGetReportsForEmployee(
WS.EndGetReportsForEmployee(
ar,
ar, out
out TotalNumRecords);
TotalNumRecords);
...
...
}}
Receive results
Exceptions If the asynchronous operation throws an exception, it will be returned from the
call to the EndOperation method.
14 Module 7: Asynchronous Programming
Return
Return control
control to
to the main
main thread
thread
//Switch
//Switch back
back to
to main
main thread
thread to
to update
update the
the UI
UI
//First,
//First, create
create aa MethodInvoker
MethodInvoker delegate
delegate for
for
//the
//the method
method to
to be
be called
called
MethodInvoker
MethodInvoker mi
mi == new
new MethodInvoker(
MethodInvoker(
this.UpdateUI);
this.UpdateUI);
//
// Use
Use the
the current
current form’s
form’s BeginInvoke
BeginInvoke to
to
//
// invoke
invoke the
the delegate
delegate
this.BeginInvoke(mi);
this.BeginInvoke(mi);
this.BeginInvoke(mi);
This call to the form’s BeginInvoke method will cause the method referred
to by mi to be called on the main thread and therefore update the user
interface (UI) safely. By calling the BeginInvoke method instead of the
Invoke method, the worker thread used to make the asynchronous call
returns to the thread pool faster, thus avoiding exhaustion of threads in the
thread pool.
Module 7: Asynchronous Programming 15
The application displays the results of the XML Web service call by using the
UpdateUI method. The UpdateUI method manipulates controls to show the
results. Controls can only be called safely from the application’s main thread.
The callback method is not executing on the application’s main thread, and
therefore cannot call the UpdateUI method directly.
Instead, it calls the form’s thread-safe BeginInvoke method, passing it a
delegate to the UpdateUI method. BeginInvoke then executes this method on
the main thread.
Module 7: Asynchronous Programming 17
3. Find the next TODO comment. Add the code to begin the call to the XML
Web service.
WS.BeginGetReportsForEmployee(null, null, 0, 10,
TotalReports, asyncCB, null);
4. Find the next TODO comment and uncomment the line of code below the
TODO comment.
5. Find the next two TODO comments. Comment out the rest of the code (the
synchronous code) in the method.
6. Find the next TODO comment. Add the code to finish the call to the XML
Web service.
ExpenseReports = WS.EndGetReportsForEmployee(result,
out TotalReports);
7. Find the next TODO comment. Add the code to instantiate a
MethodInvoker delegate that points to the UpdateUI method of this class.
MethodInvoker mi = new MethodInvoker(this.UpdateUI);
8. Find the next TODO comment. Add the code to call BeginInvoke on this
form, passing the MethodInvoker delegate created in step 6.
this.BeginInvoke(mi);
9. Save your files and build the project.
Follow
Follow the
the design
design pattern
pattern for
for asynchronous
asynchronous programming
programming
Techniques for protecting state and data is covered in the topic How to Protect
State and Data in a Multithreaded Environment in this module.
Module 7: Asynchronous Programming 21
Declare
Declare the
the delegate
delegate
Delegate keyword
The delegate's
public
public delegate
delegate int
int CalcDelegate(
CalcDelegate( signature matches
int startingValue,
int startingValue, that of the method it
int
int interestRate);
interestRate); will point to
Instantiate
Instantiate the
the delegate, passing
passing in
in the
the method
method that
that the
the delegate
delegate
points
points to
//Instantiate
//Instantiate class
class that
that contains
contains method
method delegate
delegate points
points to
to
TotalReturnCalc
TotalReturnCalc trtr == new
new TotalReturnCalc();
TotalReturnCalc();
//Instantiate
//Instantiate the
the delegate,
delegate, passing
passing it
it the
the method
method to
to call
call
CalcDelegate
CalcDelegate cd
cd == new
new CalcDelegate(tr.CalculateReturn);
CalcDelegate(tr.CalculateReturn);
The previous code declares a delegate to a method that returns an integer and
takes two integers as parameters.
Because Microsoft Visual C#™ and Microsoft Visual Basic® .NET compilers
support asynchronous delegates, they generate the Invoke method and the
BeginInvoke and EndInvoke methods when you declare the delegate.
Use the Invoke method if you want to call the target method synchronously.
Use the BeginInvoke method to call the target method asynchronously. The
runtime queues the request and returns immediately to the caller. The target
method will be called on a thread from the thread pool. The original thread that
submitted the request is free to continue executing in parallel to the target
method, which is running on a thread pool thread.
If a callback has been specified on BeginInvoke, it is called when the target
method returns. In the callback, the EndInvoke method is used to obtain the
return value and the in/out parameters. If the callback is not specified on
BeginInvoke, you can use the other asynchronous design pattern techniques,
for example, polling, on the original thread that submitted a request.
22 Module 7: Asynchronous Programming
Procedure: Instantiating Instantiate the class that contains the method that the delegate will point to.
the delegate
TotalReturnCalc tr = new TotalReturnCalc();
Create
Create the
the delegate
delegate to
to the
the callback
callback method
method
Call
Call the
the BeginInvoke
BeginInvoke method
When using a callback method, pass in the delegate for the callback
method
Returns an object implementing IAsyncResult
//
// call
call BeginInvoke
BeginInvoke to
to asynchronously
asynchronously call
call the
the method
method
IAsyncResult
IAsyncResult ar
ar == cd.BeginInvoke(startVal,
cd.BeginInvoke(startVal, intRate,
intRate, cb,
cb, null);
null);
In the code example above, this refers to the object from which you are making
the asynchronous call. Alternatively, the method that handles the callback could
be in a different object, if necessary for your scenario.
Procedure: Calling the To call the BeginInvoke method, pass the callback delegate, named cb in the
BeginInvokemethod code example, to the BeginInvoke method as the second to last parameter.
IAsyncResult ar = cd.BeginInvoke(startVal, intRate, cb,
null);
Call
Call the
the EndInvoke
EndInvoke method
method
Returns a return value or a data structure that includes a return value
//inside
//inside the
the callback
callback method
method called
called ResultsCB
ResultsCB
void
void ResultsCB(IAsyncResult
ResultsCB(IAsyncResult ar)
ar)
{{
...
...
int
int result
result == cd.EndInvoke(ar);
cd.EndInvoke(ar);
...
...
}}
Update
Update the UI
UI to reflect
reflect the
the results
results of
of the
the operation
operation
When using Windows Forms, this involves returning control back
to the main UI thread because Windows Forms can only be safely
called from the main thread
Exceptions If the asynchronous operation throws an exception, it will be returned from the
call to the EndInvoke method.
Updating the UI In Windows Forms applications, you must return control to the main thread
before updating the user interface.
Module 7: Asynchronous Programming 25
//Switch
//Switch back
back to
to main
main thread
thread before
before updating
updating UI
UI
MethodInvoker
MethodInvoker mi
mi == new
new MethodInvoker(this.UpdateUI);
MethodInvoker(this.UpdateUI);
//
// Use
Use BeginInvoke
BeginInvoke to
to call
call the
the MethodInvoker,
MethodInvoker, because
because
//
// it
it returns
returns worker
worker thread
thread to
to thread
thread pool
pool faster
faster
this.BeginInvoke(mi);
this.BeginInvoke(mi);
Automatic synchronization
Potential overhead incurred
Synchronized code region
Monitor class
Manual synchronization
Mutex class
ReaderWriterLock class
Interlocked.Increment and Interlocked.Decrement
methods
Design applications to try to minimize synchronization
needs
Note Using automatic synchronization can incur more overhead than using
manual synchronization techniques.
Synchronized code Another technique that you can use is a compiler keyword to synchronize
regions blocks of code, instance methods, and static methods. In Visual C#, the
keyword is lock. This keyword uses the Monitor class to lock the object.
When you use the lock keyword, the compiler generates code. The Visual C#
compiler emits a try/finally block with Monitor.Enter at the beginning of the
try, and Monitor.Exit in the finally block. If an exception is thrown inside of
the lock block, the finally handler runs to allow you to perform any clean-up
work.
Module 7: Asynchronous Programming 29
class Cache
{
public static void Add(object x)
{
// method code that doesn't require exclusive access
lock (typeof(Cache))
{
// code requiring exclusive access to static data
}
// method code that doesn't require exclusive access
}
}
Manual synchronization You can use the Monitor, Interlocked, Mutex, ManualResetEvent,
AutoResetEvent, and ReaderWriterLock classes to acquire and release a lock
to protect global, static, and instance fields and global, static, and instance
methods.
Designing applications For many UI-based applications, little or no special synchronization code is
to minimize required. All of the changes of the UI must happen on the main application
synchronization needs thread, so this usually forces synchronous access to state information. Also,
careful enabling and disabling of UI elements can prevent the application from
getting into an undefined state. For example, the Expense Reporting sample
application enables and disables buttons as asynchronous XML Web service
calls are made to prevent threading-related problems. Therefore, no special
synchronization code is required in the Expense Reporting application, other
than the use of MethodInvoker delegates to switch control to the main thread
upon completion of asynchronous calls.
For more information about synchronization techniques, see Module 14,
“Threading and Asynchronous Programming” in Course 2349B, Programming
with the Microsoft .NET Framework (Microsoft Visual C# .NET).
Module 7: Asynchronous Programming 31
Notice that although Increment was called five times for the unsafe test, the
value of the counter never reaches five. Also, the start and stop notifications
are interspersed among different threads. In the lock version, the start and
stop notifications are paired for each thread, and the counter is correctly
incremented to five.
34 Module 7: Asynchronous Programming
Review
2. In a Windows Forms application, what are the main steps to follow to use
the asynchronous programming design pattern with an asynchronous
callback for completion?
The main steps are:
1. Create the asynchronous callback delegate.
2. Invoke the BeginOperation method, passing it the callback.
3. Inside the callback, invoke the EndOperation method for
completion.
4. Return control to the main thread and update the user interface.
Module 7: Asynchronous Programming 35
4. Why do you need to return control to the main thread before updating the UI
in Windows Forms applications?
You need to return control to the main thread before updating the UI
because Windows Forms controls can be safely accessed only from the
main thread.
Scenario The Expense Report application makes numerous calls to an XML Web service.
To improve the responsiveness and usability of the application, all of the XML
Web service calls should be made asynchronously.
To make the calls asynchronous, you must perform the following tasks:
Convert the synchronous XML Web service calls to asynchronous calls.
Write the method that handles the asynchronous callback.
Write the method that updates the user interface.
In the starter code for this lab, the asynchronous callback method and user
interface update method are already written, and some of the XML Web service
calls are already converted.
In this lab, you will convert the rest of the synchronous XML Web service calls
to asynchronous calls and then use the Visual Studio debugger to follow the
flow of the asynchronous calls in the resulting code.
Lab Setup There are starter and solution files associated with this lab. Browse to
install_folder\Labfiles\Lab07_1\Ex01\Starter to find the starter files, and
browse to install_folder\Labfiles\Lab07_1\Ex01\Solution to find the solution
files. If you performed a default installation of the course files, install_folder
corresponds to C:\Program Files\Msdntrain\2555.
Estimated time to
complete this lab:
15 minutes
38 Module 7: Asynchronous Programming
Exercise 1
Converting Synchronous Calls to Asynchronous Calls
In this exercise, you will convert some synchronous XML Web service calls to asynchronous calls.
You will also use the Visual Studio debugger to view the flow of asynchronous calls and test your
application to ensure that it has the expected results.
1. Open the ExpenseReport project in a. For more information about opening a project file
Visual Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab07_1\Ex01\Starter to resource:
find the project files. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application in the Designer, in Index, search
by using the phrase Debugging Windows
Applications.
2. Open the ExpenseReportList source file, and view a. See the TODO comments in the code for more
the code. Refer to the synchronous versions of the detailed information about the tasks that you must
calls to see which parameters to pass: perform to convert the synchronous XML Web
• The first four parameters should be the same. service calls in the constructor to asynchronous
calls.
• The fifth parameter should not use the ref
keyword in the asynchronous version. b. For more information about how to make
asynchronous calls, see the following resources:
• The sixth parameter should be the callback
delegate. • Practice: Making an Asynchronous Call to an
XML Web Service in Module 7
• The seventh parameter should be null. “Asynchronous Programming,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: The Asynchronous Programming
Model Design Pattern in Module 7
“Asynchronous Programming,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation.
For more information about the asynchronous
design pattern, search by using the phrase
Including Asynchronous Calls.
Module 7: Asynchronous Programming 39
3. View the flow of asynchronous code by setting a. For more information about debugging and
breakpoints in the ExpenseReportList controlling the flow of asynchronous calls, see the
constructor and the GetReportsCB and following resources:
UpdateReportsUI methods. • Practice: Making an Asynchronous Call to an
a. Run the application in the Visual Studio XML Web Service in Module 7
debugger. Click View Submitted Reports. “Asynchronous Programming,” in Course
Step through the code, and make sure it 2555A, Developing Microsoft .NET
executes as expected. Applications for Windows (Visual C# .NET).
b. Confirm the correct behavior in the user This practice contains information about how
interface by making sure that the expense to debug an asynchronous call.
reports are downloaded asynchronously when • Lesson: The Asynchronous Programming
a new list window is opened. Model Design Pattern in Module 7
“Asynchronous Programming,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
This lesson contains information about the
flow of control of an asynchronous call.
THIS PAGE INTENTIONALLY LEFT BLANK
Module 8: Enhancing
the Usability of
Applications
Contents
Overview 1
Lesson: Adding Accessibility Features 2
Lesson: Adding Help to an Application 9
Lesson: Localizing an Application 21
Review 34
Lab 8.1: Enhancing the Usability of an
Application 37
Course Evaluation 53
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 8: Enhancing the Usability of Applications iii
Instructor Notes
Presentation: In this module, students learn to use the accessibility, Help, and localization
60 minutes features available in the Microsoft® .NET Framework.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_08.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Complete the practices and lab.
iv Module 8: Enhancing the Usability of Applications
Overview
Accessibility options
Magnifier
On-Screen Keyboard
In this lesson, you will use Narrator—the screen reader included with
Windows XP—to demonstrate and test the accessibility properties that you can
set on the user interface elements of your applications.
4 Module 8: Enhancing the Usability of Applications
Developer support For more information about the guidelines for designing accessible
applications, see the MSDN Library and the Microsoft Accessibility Web site
http://www.microsoft.com/enable/.
Some examples of the guidelines include:
The application must be compatible with specific system color, size, font,
sound, and input settings.
This provides a consistent user interface (UI) across all applications on the
user’s system. Users can configure their preferred settings for these
elements by using Control Panel.
Applications must be compatible with the High Contrast display option.
Users who desire a high degree of screen legibility select the Use High
Contrast check box on the Display tab of the Accessibility Options dialog
box. When this option is selected, several restrictions are imposed on the
application. For example, only system colors that can be selected through
Control Panel, or colors set by the user, may be used by the application.
The application must provide keyboard access to all features.
This allows the user to interact with the application without requiring a
pointing device, such as a mouse.
Applications must not convey information by sound alone.
Applications that convey information by sound must provide additional
options to express this information. This includes on-screen messages.
Many of the standard user interface elements also have properties that you can
set either at design time or programmatically in your applications to provide
information for use by accessibility aids.
Module 8: Enhancing the Usability of Applications 5
this.AppExitButton
this.AppExitButton == new
new System.Windows.Forms.PushButton();
System.Windows.Forms.PushButton();
this.AppExitButton.Text
this.AppExitButton.Text == "E&xit";
"E&xit";
AppExitButton.AccessibleRole
AppExitButton.AccessibleRole ==
System.Windows.Forms.AccessibleRole.PushButton;
System.Windows.Forms.AccessibleRole.PushButton;
AppExitButton.AccessibleName
AppExitButton.AccessibleName == "Exit";
"Exit";
AppExitButton.AccessibleDescription
AppExitButton.AccessibleDescription == "Use
"Use this
this button
button to
to
exit
exit the
the application";
application";
this.Controls.Add(this.AppExitButton);
this.Controls.Add(this.AppExitButton);
*****************************ILLEGAL FOR NON-TRAINER USE******************************
Introduction The settings of various properties of a control or form can affect how accessible
your application will be. Some properties are specifically designed for use by
accessibility aids while others are more general properties like FontSize.
Properties related to This table provides accessibility considerations related to certain properties.
accessibility
Property Considerations for accessibility
(continued)
Property Considerations for accessibility
Setting accessibility At design time, use the Properties window to set the appropriate values for
properties at design properties for a form or control.
time
Programmatically You can also set the property values programmatically. In the following code, a
setting accessibility button that has the appropriate property values is created and added to a form.
properties The this keyword in the code refers to the form to which the button is added.
this.AppExitButton = new System.Windows.Forms.PushButton();
this.AppExitButton.Text = "E&xit";
AppExitButton.AccessibleRole =
System.Windows.Forms.AccessibleRole.PushButton;
AppExitButton.AccessibleName = "Exit";
AppExitButton.AccessibleDescription = "Use this button to exit
the application";
this.Controls.Add(this.AppExitButton);
Module 8: Enhancing the Usability of Applications 7
Note Notice that Narrator reads the information for one of the controls twice.
This is because Narrator automatically reads the information from the control
that has focus, then reads the information about the form, and finally reads the
information about all the controls that appear on the form.
8 Module 8: Enhancing the Usability of Applications
Context-sensitive Help
HelpProvider control
HelpButton property
Adding support for Help Visual Studio .NET provides several new controls that you can use when
at design time developing applications. To provide context-sensitive Help, you can use the
HelpProvider control and the HelpButton property. To create a short Help text
string that will appear when a user rests the mouse on a control, you can use the
ToolTip control. The HelpProvider and ToolTip controls do not appear on the
form. They provide an interface between the controls and the properties that
you can set to provide Help and ToolTips.
You can use the MainMenu control to add a Help menu to the application to
provide easy access to Help topics.
Module 8: Enhancing the Usability of Applications 11
For each control that you want to add Help information set the
following properties
HelpKeyword
HelpNavigator
HelpString
Procedure: Adding a When the user clicks the Help button on the form at run time and then clicks a
Help button to the form control, the text in the HelpString property for that control displays.
1. In Visual Studio .NET Design view, set the following properties for the
form to which you want to add a Help button.
2. Set the HelpButton property to True.
3. Set the MaximizeBox property to False.
4. Set the MinimizeBox property to False.
12 Module 8: Enhancing the Usability of Applications
Set the Help information In Visual Studio .NET Design view, set the HelpKeyword, HelpNavigator,
for each control and HelpString properties for each control for which you want to add Help
information.
If you set the HelpNamespace property in the HelpProvider control to an
HTML page and you set the HelpKeyword property of a control, the Help
system will try to locate an anchor tag in the Help file that has the keyword in it
when the F1 key is pressed. For example, if the keyword is FormHelp, the
Help system will look for <A NAME=“FormHelp”> in the target HTML file.
Because F1 is now overridden by setting the HelpNamespace property to bring
up a separate Help file, the Help button can be used to mimic the F1
functionality.
The HelpNavigator property determines how the keyword is used by the Help
system to locate the information the user has requested. This property can take
one of the following values.
HelpNavigator property value Description
The HelpString property is used for pop-up Help (the Help that is displayed
when a user presses F1 when a specific control has focus). If the
HelpNamespace property on the HelpProvider is set, pressing F1 on a Help-
enabled control will always bring up the target Help file rather than the pop-up
window.
Note If you set the HelpButton property on a form to True and do not set the
MaximizeBox and MinimizeBox properties to False, then the form will
display the maximize box and minimize box, but it will not display the Help
button.
Module 8: Enhancing the Usability of Applications 13
Parent
Parent of
of the
the Path
Path and
and name
name of
of
Help
Help dialog
dialog box
box Help
Help file
file
Help.ShowHelp
Help.ShowHelp (this,
(this, HelpProvider.HelpNamespace);
HelpProvider.HelpNamespace);
2. Edit the menu to add the Help menu and Help menu items.
3. When the Help menu option is clicked at run time, it fires a click event. In
the click event code for the menu item, add code to open the Help file:
Help.ShowHelp (this, HelpProvider.HelpNamespace);
In the previous code:
• The first parameter (this) is the control that identifies the parent of the
Help dialog box. In this case, the form is the parent control of the Help
dialog box.
• The second parameter (HelpProvider.HelpNamespace) is the path and
name of the Help file. The URL can be of the form C:\..., file:///…, or
http://....
Module 8: Enhancing the Usability of Applications 15
5. Locate the TODO comment in the Click event handler for the menu item,
and add the following code.
// TODO: Call the ShowHelp method to display the help file
to the user.
Help.ShowHelp(this,
UsabilityDemoHelpProvider.HelpNamespace);
6. Build and run the application.
7. On the Help menu, click the Help menu item.
Internet Explorer displays the Help file.
18 Module 8: Enhancing the Usability of Applications
When the user moves the mouse pointer over the control at run time, after a
short pause the ToolTip window appears, displaying the text that you set as the
value for the ToolTip on toolTip1 property.
20 Module 8: Enhancing the Usability of Applications
Globalization
Localization
Culture
Region
Localization support in The CultureInfo class contains culture-specific information, such as the
the .NET Framework language, country/region, calendar, and cultural conventions associated with a
specific culture. This class also provides the information required for
performing culture-specific operations, such as casing, formatting dates and
numbers, and comparing strings.
The CultureInfo class specifies a unique name for each culture. The name is a
combination of a two-letter lowercase culture code associated with a language
and, if required, a two-letter uppercase subculture code associated with a
country or region. For a list of all the valid culture and region codes, see the
topic “CultureInfo Class” in the .NET Framework software development kit
(SDK) documentation.
22 Module 8: Enhancing the Usability of Applications
Lesson objectives After completing this lesson, you will be able to:
Differentiate between the concepts of globalization and localization of an
application.
Use localization properties and resource files to create a localized version of
an application.
Module 8: Enhancing the Usability of Applications 23
Visual Studio .NET creates and uses resource files to store the information
created for each form and control for the different cultures and regions.
24 Module 8: Enhancing the Usability of Applications
When you create multiple language versions of a form, Visual Studio .NET
automatically creates resource files to store the localization information. There
are two resource files for each language: one for the specific culture and region
and one for the overall culture. You can view these files by using
Windows Explorer to the view folder for your project.
Localizing other When you localize other resources, such as text strings, bitmaps, and so on, you
resources must create resource files manually. To do this, add a new resource file to the
project, name it appropriately, and then use the ResourceManager object in the
.NET Framework to retrieve the appropriate resources at run time.
Module 8: Enhancing the Usability of Applications 25
Modify the Text property values for the form and controls into
the appropriate language
Each time that you choose another culture to localize to, Visual Studio .NET
creates a new resource file for that culture. The data stored in the resource file is
XML and includes not only the localized data but also changes made to control
positioning and size.
26 Module 8: Enhancing the Usability of Applications
3. Add entries into the resource file, with values in the appropriate language
for the culture.
Using satellite assembly A satellite assembly is an assembly that contains only resources. After you
files build an application that contains multiple resource files for multiple cultures,
the resulting satellite assembly names are all the same; however, they are stored
in different folders that are named after the culture that they represent. For
example, if you build an application called AppHelp with the resource file
mentioned in the previous procedure, the resulting satellite assembly would be
named UsabilityDemo.resources.dll, and it would be stored in
ApplicationFolder\bin\Debug\culture (for example,
UsabilityDemo\bin\Debug\de-DE).
The best reason to use satellite assemblies is the separation of resources from
the application. You can build a version of your application with the default
culture and release it to the public. At a later time, you can deploy a satellite
assembly for each culture that you support. When a culture for your application
becomes available, you put it in a separate assembly and make it available to
your clients (by using the network, a Web site, or some other media).
Third-party organizations can create resource files by using the Resource File
Generator (ResGen.exe) tool that is included with the .NET Framework. You
can use this tool to create resource files without having Visual Studio .NET
installed. Source files for ResGen must be text files with a file extension of .txt
or XML files with the file extension of .resx. ResGen compiles these files into
resource files that have the file extension .resource.
For more information about how the .NET Framework searches for resource
files, see Module 4, “Assembly Versioning and Satellite Assemblies,” in
Course 2350A, Securing and Deploying Microsoft .NET Assemblies or see the
.NET SDK documentation.
Module 8: Enhancing the Usability of Applications 29
using System.Threading;
2. Set the thread’s User Interface culture based on what is set in Control Panel.
Thread.CurrentThread.CurrentUICulture =
Thread.CurrentThread.CurrentCulture;
In this case, the Thread.CurrentThread.CurrentCulture property value is
taken from the settings in Control Panel. To make the UI use the correct
culture, you set the CurrentUICulture property value of the current thread.
30 Module 8: Enhancing the Usability of Applications
Note If you want to ensure that your Windows Forms application starts with
the culture that is set in the Regional and Language Options dialog box in
Control Panel, set the Thread.CurrentThread.CurrentUICulture property
value prior to the call to the InitializeComponents method in the startup class
constructor.
The resource manager uses the resource fallback process to control how an
application retrieves resources. The resource manager uses the
CultureInfo.CurrentUICulture property to determine which resources to
search for and load. If you want to use a different culture than that of the local
computer, then you must set this property programmatically in your application.
For example, if you set the Culture.CurrentUICulture property to en-GB, the
runtime searches for a satellite assembly that supports the en-GB culture. If the
Culture.CurrentUICulture is not set, the common language runtime sets the
culture to that of the local computer.
Because the runtime always searches for the default culture when all other
possibilities are exhausted, you should always include a default culture with
your applications. The default culture is the only one that is built into the main
application assembly. For more information about how the .NET Framework
searches for resource files, see Module 4, “Assembly Versioning and Satellite
Assemblies,” in Course 2350A, Securing and Deploying Microsoft .NET
Assemblies or see the .NET SDK documentation.
Procedure: Accessing To access localized strings by using a resource manager:
localized strings by
using a resource 1. Add the code to instantiate a resource manager and access resources.
manager ResourceManager rm = new
ResourceManager("MyNamespace.Resource1",
Assembly.GetExecutingAssembly());
The first parameter is the root name of the resource file. For example, if the
resource file is Resource1.en-EN.resources, the root name is Resource1. The
root name of the resource file is qualified with the namespace that contains
the resource file. The second parameter is the main assembly for the
resources. Because you are in the assembly that is the main assembly, the
call to GetExecutingAssembly() returns the current assembly’s name.
2. Add the code to access the resource and display the localized string.
MessageBox.Show (rm.GetString("test_1"));
When you create an instance of the resource manager, it automatically gets
the value for the current culture and locates the appropriate resource file.
Call GetString, passing the name of a specific resource file element, and it
will return the value from the correct resource file that matches the current
culture setting. If the resource manager cannot locate the appropriate
resource file, an exception is thrown. Therefore, any code that uses the
resource manager should be wrapped in exception-handling code.
Module 8: Enhancing the Usability of Applications 31
4. Examine the Localizable property of the form. Notice that it is set to True,
which means that the form can be localized.
5. Set the Language property of the form to French (France).
The English version of the form is still displayed, but it can be localized into
French. Notice that a set of new resource files for the form can be found
under the UsabilityDemo source file in Solution Explorer. These are
UsabilityDemo.fr.resx and UsabilityDemo.fr-FR.resx. Both of these files are
required for the resource fallback process.
6. Notice that this form has also been localized into German and Japanese.
7. Set the Text property of the form to Démonstration de l'utilisation.
Note To get the strings for the French version of the form, go to the
UsabilityDemoLocalizedStrings.rtf file in install_folder\Practices\
Mod08\Mod08_04.
32 Module 8: Enhancing the Usability of Applications
8. Set the Text property of the menu and menu item to Aide.
9. Set the Text property of the Choose a Culture button to Choisir une
langue.
10. Set the Text property of the Show Date/Time button to Afficher la
date/l'heure.
11. Set the Text property of the Show Currency button to Afficher la devise.
12. Set the Text property of the Show a String button to Afficher une chaîne.
13. Set the Text property of the Exit button to Quitter.
7. Find the next TODO comment. Add code to use the resource manager to
retrieve the text string from the resource file and display it in the text box.
OutputTextBox.Text = RM.GetString("SimpleTextString");
8. Find the next TODO comment. Add code to set the current thread’s Culture
and UICulture property values to the same culture that the user requested.
Thread.CurrentThread.CurrentUICulture = new
CultureInfo(ChosenCulture, false);
Thread.CurrentThread.CurrentCulture = new
CultureInfo(ChosenCulture, false);
9. Save your work.
Review
4. Describe the purpose of the ampersand (&) character with regard to the text
for controls.
The ampersand character, when included in the Text property of a
control, provides an access key to the user so that he or she can use the
keyboard—in addition to the mouse—to access the control.
7. When enabling the HelpButton property, what must be done to ensure that
the Help button appears on the form at run time?
The MaximizeBox and MinimizeBox properties must be set to False.
8. Where do the HelpProvider and ToolTip controls appear when they are
added to a form?
They appear below the form, not on the form.
36 Module 8: Enhancing the Usability of Applications
11. What is required to change the locale of an application at run time so that it
matches the current settings of the computer?
A resource manager reads the localized information from the resource
files, and the user interface culture must be changed to the current
culture of the thread.
Note This lab focuses on the concepts in Module 8, “Enhancing the Usability
of Applications,” in Course 2555A, Developing Microsoft .NET Applications
for Windows (Visual C# .NET). As a result, this lab may not comply with
Microsoft security recommendations.
Scenario The Internal Business Application shell provides a common access point to
various internal business applications. The shell must provide accessibility
support and Help to users in the organization. In addition, the application must
be localized into several languages to support the languages spoken by people
of different cultures across the organization.
Supporting accessibility requires that you set control properties and use an
accessibility aid such as the Narrator utility included in Windows XP. Including
Help as part of the application requires that you use the HelpProvider control,
set several properties on controls, and add code to the application to provide
access to a Help file. To localize the application for specific region and culture
combinations requires that each user interface element (form, controls, and so
on) and resources found in the source code be localized for the appropriate
cultures. In addition, the use of a resource manager is required to retrieve
localized resources from resource files.
In this lab, you will add some accessibility support and Help features to the
Internal Business Application shell and localize the application for several
region and culture combinations.
Estimated time to
complete this lab:
30 minutes
Module 8: Enhancing the Usability of Applications 39
Exercise 1
Adding Support for Accessibility
In this exercise, you will update the Internal Business Application shell by adding support for
accessibility and testing the application by using the Narrator accessibility aid in Windows XP.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab08_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab08_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in Visual a. For more information about opening a project file
Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab08_1\Ex01\Starter to resource:
find the project. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application in the Designer, in Index, search
by using the phrase Debugging Windows
Applications.
2. Open the AppControlForm form and set the a. For more information about how to add
form’s AccessibleName property to Internal accessibility support to an application, see the
Business Application Control Panel. following resources:
• Practice: Adding Accessibility Support to an
Application, in Module 8, “Enhancing the
Usability of Applications,” in Course 2555A,
Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
• Lesson: Adding Accessibility Features in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
b. For more information about writing accessible
applications, see the following resource:
• The Visual Studio.NET Help documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Designing Accessible Applications.
40 Module 8: Enhancing the Usability of Applications
3. Set the AccessibleName property for the buttons. a. For more information about how to add
See the following table for the values to give to accessibility support to an application, see the
the AccessibleName property for each button. following resources:
Button Value • Practice: Adding Accessibility Support to an
Make Travel Plans Make Travel Plans Application, in Module 8, “Enhancing the
Expense Reporting Expense Reporting Usability of Applications,” in Course 2555A,
Procurement Procurement Developing Microsoft .NET Applications for
Exit Exit the Application Windows (Visual C# .NET).
• Lesson: Adding Accessibility Features in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
4. Enable Narrator. a. For more information about how to enable
Microsoft Narrator in Windows XP Professional,
see the following:
• Practice: Adding Accessibility Support to an
Application, in Module 8, “Enhancing the
Usability of Applications,” in Course 2555A,
Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
• Lesson: Adding Accessibility Features in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
5. Run the application to test the accessibility a. For more information about starting an
support. You can log on with the user name application in the Designer, see the following
mario and the password P@ssw0rd. resource:
• The Visual Studio.NET Help documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Debugging Windows Applications.
Module 8: Enhancing the Usability of Applications 41
Exercise 2
Adding Help to an Application
In this exercise, you will update the Internal Business Application shell by adding on-screen Help.
When the user presses the F1 key, a Help message that is associated with the control that has focus
appears.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab08_1\Ex02\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab08_1\Ex02\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab08_1\Ex02\Starter to resource:
find the project. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application in the Designer, in Index, search
by using the phrase Debugging Windows
Applications.
2. View the Toolbox, and add the HelpProvider a. For more information about adding Help to an
control to the AppControlForm form. application, see the following resources:
a. Set the (Name) property of the HelpProvider • Practice: Adding Help to an Application in
control to Module 8, “Enhancing the Usability of
InternalBusinessAppHelpProvider. Applications,” in Course 2555A, Developing
b. Set the HelpNamespace property to Microsoft .NET Applications for Windows
http://localhost/ (Visual C # .NET).
InternalBusinessAppHelp.htm. • Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Introduction to the Windows Forms
HelpProvider.
42 Module 8: Enhancing the Usability of Applications
3. Select the AppControlForm form. To enable Help a. For more information about adding Help to an
on the form, set some of the Help properties. See application, see the following resources:
the following table for the properties and the • Practice: Adding Help to an Application in
corresponding values to set. Module 8, “Enhancing the Usability of
Property Value Applications,” in Course 2555A, Developing
HelpKeyword IBA_ControlPanel Microsoft .NET Applications for Windows
HelpNavigator Topic (Visual C# .NET).
HelpString Provides access to the • Lesson: Adding Help to an Application in
company’s internal Module 8, “Enhancing the Usability of
applications Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Introduction to the Windows Forms
HelpProvider.
Module 8: Enhancing the Usability of Applications 43
4. For each of the controls on the AppControlForm a. For more information about adding Help to an
form, set the Help properties to enable Help. application, see the following resources:
Use the following tables to set the appropriate • Practice: Adding Help to an Application in
properties for the following controls. Module 8, “Enhancing the Usability of
a. Make Travel Plans control Applications,” in Course 2555A, Developing
Property Value Microsoft .NET Applications for Windows
(Visual C# .NET).
HelpKeyword IBA_Travel
HelpNavigator Topic • Lesson: Adding Help to an Application in
HelpString Plan a business trip. Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
b. Expense Reporting control Microsoft .NET Applications for Windows
Property Value (Visual C# .NET).
HelpKeyword IBA_Expense • The .NET Framework SDK documentation.
HelpNavigator Topic In Search, select the Search in titles only
HelpString Log expenses for check box, then search by using the phrase
reimbursement. Introduction to the Windows Forms
c. Procurement control HelpProvider.
Property Value
HelpKeyword IBA_Procurement
HelpNavigator Topic
HelpString Internal Purchasing.
d. Exit control
Property Value
HelpKeyword IBA_Exit
HelpNavigator Topic
HelpString Exit the Internal Business
Application.
e. Status Bar control
Property Value
HelpKeyword IBA_Status
HelpNavigator Topic
HelpString Network Connection Status
44 Module 8: Enhancing the Usability of Applications
5. Add a Help button to the AppControlForm form. a. For more information about adding Help to an
a. Set the value for the MaximizeBox and application, see the following resources:
MinimizeBox properties to False. • Practice: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Introduction to the Windows Forms
HelpProvider.
6. Link the Help menu to the Help file. a. For more detailed information about the tasks that
you must perform, see the TODO comments in
the code.
b. For more information about adding Help to an
application, see the following resources:
• Practice: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Introduction to the Windows Forms
HelpProvider.
7. Run the application to test Help. a. For more information about starting an
application from within Designer, see the
following resource:
• The Visual Studio.NET Help documentation.
In Index, search by using the phrase
Debugging Windows Applications.
Module 8: Enhancing the Usability of Applications 45
Exercise 3
Adding ToolTips to an Application
In this exercise, you will update the Internal Business Application shell by adding ToolTips to the
AppControlForm form and providing ToolTip text for the controls on the form.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab08_1\Ex03\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab08_1\Ex03\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab08_1\Ex03\Starter to resource:
find the project. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application in the Designer, in Index, search
by using the phrase Debugging Windows
Applications.
2. View the AppControlForm form in the form a. For more information about adding ToolTips to
designer. an application, see the following resource:
a. View the Toolbox, and add the ToolTip • Practice: Adding ToolTips to an Application
control to the AppControlForm form. in Module 8, “Enhancing the Usability of
b. Set the (Name) property of the ToolTip Applications,” in Course 2555A, Developing
control to ApplicationToolTip. Microsoft .NET Applications for Windows
(Visual C# .NET).
• Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase ToolTip
Component.
46 Module 8: Enhancing the Usability of Applications
3. Set the text for the ToolTip for each of the a. For more information about adding ToolTips to
controls on the AppControlForm form. an application, see the following resources:
a. Use the following table to set the value for the • Practice: Adding ToolTips to an Application
ToolTip on ApplicationToolTip property for in Module 8, “Enhancing the Usability of
each control. Applications,” in Course 2555A, Developing
Property Value Microsoft .NET Applications for Windows
(Visual C# .NET).
Form Accesses internal
applications. • Lesson: Adding Help to an Application in
Make Travel Plans Allows you to plan a Module 8, “Enhancing the Usability of
business trip. Applications,” in Course 2555A, Developing
Expense Reporting Allows you to submit and Microsoft .NET Applications for Windows
check expense reports. (Visual C# .NET).
Procurement Allows you to purchase • The .NET Framework SDK documentation.
items at company rates. Search by using the phrase ToolTip
Exit Exit the application. Component.
Status bar Displays the network
connection status.
4. Run the application to test the ToolTips. a. For more information about starting an
application in the Designer, see the following
resource:
• The Visual Studio.NET Help documentation.
In Index, search by using the phrase
Debugging Windows Applications.
Module 8: Enhancing the Usability of Applications 47
Exercise 4
Localizing the User Interface of an Application
In this exercise, you will update the Internal Business Application shell by localizing the
AppControlForm form into French.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab08_1\Ex04\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab08_1\Ex04\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab08_1\Ex04\Starter to resource:
find the project. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application in the Designer, in Index, search
by using the phrase Debugging Windows
Applications.
2. View the AppControlForm form in the form a. For more information about localizing an
designer. Set the Language property of the form application, see the following resources:
to French (France). • Practice: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase Developing
World-Ready Applications.
48 Module 8: Enhancing the Usability of Applications
3. Change the Text property of each control from a. For more information about localizing an
English to its equivalent French translation. application, see the following resources:
a. Use the following table to set the value for • Practice: Localizing an Application in Module
Text property for each control. 8, “Enhancing the Usability of Applications,”
Control Value in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
Form Tableau de bord des
applications • Lesson: Localizing an Application in Module
HelpMenu Aide 8, “Enhancing the Usability of Applications,”
HelpMenuItem Aide in Course 2555A, Developing Microsoft .NET
AboutMenuItem À propos de l'application Applications for Windows (Visual C# .NET).
interne d'entreprise • The .NET Framework SDK documentation.
Make Travel Plans Préparer un voyage Search by using the phrase Developing
Expense Reporting Notes de frais World-Ready Applications.
Procurement Réservation
Exit Quitter
Note: You can copy and paste the French strings from
the file install_folder\Labfiles\Lab08_1\Ex04\Starter\
InternalBusinessApplicationLocalizedStrings.rtf.
4. Add code to the AppControlForm form to set the a. For more detailed information about the tasks that
culture to match the regional and language you must perform, see the TODO comments in
information that the user has set in Control Panel. the code.
b. For more information about localizing an
application, see the following resources:
• Practice: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase Developing
World-Ready Applications.
Module 8: Enhancing the Usability of Applications 49
5. Change the default language for the computer, No additional information is required for this task.
and test the application.
a. Open Control Panel in Windows XP
Professional:
• If you are using Category View in
Control Panel, click Date, Time,
Language, and Regional Options, and
then click Regional and Language
Options.
• If you are using Classic View in Control
Panel, double-click Regional and
Language Options.
b. In the Regional and Language Options
dialog box, on the Regional Options tab, in
the Standards and formats area, in the list of
languages, click French (France).
c. Run the application.
50 Module 8: Enhancing the Usability of Applications
Exercise 5
Localizing Resources in an Application
In this exercise, you will update the Internal Business Application shell by localizing strings used in
the AppControlForm form.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab08_1\Ex05\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab08_1\Ex05\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the InternalBusinessApp project in a. For more information about opening a project
Visual Studio .NET. Browse to file, see the following resource:
install_folder\Labfiles\Lab08_1\Ex05\Starter to • The Visual Studio.NET Help documentation.
find the project. Search by using the phrase Open Project
Dialog Box.
2. Create a new resource file, and name it a. For more information about localizing an
AppControlRes.fr-FR.resx. application, see the following resources:
• Practice: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• Lesson: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase Developing
World-Ready Applications.
Module 8: Enhancing the Usability of Applications 51
3. Add text in French to the resource file. a. For more information about localizing an
a. Use the following table to set the Name and application, see the following resources:
Value elements for each resource string. • Practice: Localizing an Application in Module
Name Value 8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
AppUnavailable Application non disponible Applications for Windows (Visual C# .NET).
Message
PermissionDenied Autorisation refusée • Lesson: Localizing an Application in Module
Message 8, “Enhancing the Usability of Applications,”
Unauthorized in Course 2555A, Developing Microsoft .NET
Message Vous ne disposez pas des Applications for Windows (Visual C# .NET).
autorisations nécessaires • The .NET Framework SDK documentation.
pour utiliser cette Search by using the phrase Developing
application World-Ready Applications.
OfflineMode Mode hors connexion
OnlineMode Mode connexion
Note: You can copy and paste the French strings from
the file install_folder\Labfiles\Lab08_1\Ex05\Starter\
InternalBusinessApplicationLocalizedStrings.rtf.
4. Add code to the AppControlForm form to set the a. For more detailed information about the tasks that
culture to match the regional and language you must perform, see the TODO comments in
information that the user has set in Control Panel. the code.
b. For more information about localizing an
application, see the following resources:
• Lesson: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase Developing
World-Ready Applications.
52 Module 8: Enhancing the Usability of Applications
5. Make sure that the default language for the No additional information is required for this task.
computer is set still to French (France) and test
the application.
a. To change the default language for the
computer, open Control Panel in
Windows XP Professional.
• If you are using Category View in
Control Panel, click Date, Time,
Language, and Regional Options, and
then click Regional and Language
Options.
• If you are using Classic View in Control
Panel, double-click Regional and
Language Options.
b. In the Regional and Language Options
dialog box, on the Regional Options tab, in
the Standards and formats area, in the list of
languages, click French (France).
c. Run the application.
Module 8: Enhancing the Usability of Applications 53
Course Evaluation
Overview 1
Lesson: .NET Assemblies 2
Lesson: Deploying Windows Forms
Applications 24
Review 46
Lab 9.1: Deploying an Application 48
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 9: Deploying Windows Forms Applications iii
Instructor Notes
Presentation: In this module, students learn about assemblies and the use of strong-named
120 minutes assemblies and the global assembly cache in the Microsoft® .NET Framework.
Students also learn how to configure and deploy Windows Forms applications.
Lab:
30 minutes After completing this module, students will be able to:
Use strong-named assemblies in .NET applications.
Use application configuration files to configure and use Microsoft
Windows® Installer 2.0 to package and deploy .NET applications.
Required materials To teach this module, you need Microsoft PowerPoint® file 2555A_09.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Complete the demonstrations, practices and lab.
iv Module 9: Deploying Windows Forms Applications
Overview
.NET Assemblies
Deploying Windows Forms Applications
What is an Assembly?
In the simplest case, an application can consist of one assembly that contains
one managed module with all the code and resources for the application. In
most scenarios, however, an application has multiple assemblies, and each
assembly may have multiple files. References between assemblies are not
resolved until the code making the call is executed. So, all assemblies of an
application need not be present at run time. Assemblies, such as localization
resources, can be retrieved on demand.
All assemblies are self-describing. Each assembly contains metadata that
includes the identity and version of the assembly and the types implemented by
that assembly. You can use the Microsoft intermediate language (MSIL)
Disassembler (Ildasm.exe) to view the contents of the assembly file. At the
command prompt, type the following command:
ildasm <assembly name>
4 Module 9: Deploying Windows Forms Applications
Private assemblies
Private assemblies are deployed with and used
exclusively by a single application
Where private assemblies can reside
Default probing process
Application folder tree
Use Assembly.LoadFrom for these locations
Any folder on the local computer
Any folder on a remote computer
A URL
Assembly
Assembly PrivateAssembly;
PrivateAssembly;
PrivateAssembly
PrivateAssembly == Assembly.LoadFrom("C:\\PrivateAssembly.dll");
Assembly.LoadFrom("C:\\PrivateAssembly.dll");
//
// Obtain
Obtain aa reference
reference to
to aa method
method known
known to
to exist
exist in
in assembly.
assembly.
MethodInfo
MethodInfo Method
Method ==
PrivateAssembly.GetTypes()[0].GetMethod("CalculateSum");
PrivateAssembly.GetTypes()[0].GetMethod("CalculateSum");
The probing process for private assemblies can be summarized with the
following steps:
1. The runtime obtains the private assembly’s simple name from the metadata
of the application that is referencing the private assembly.
2. The runtime starts probing first in the application’s root directory, next in
the assembly’s named subdirectory, and then in the assembly’s culture
subdirectory. For example, if the application MyApp is installed in
C:\Program Files\MyApp, the following directories may be searched:
C:\Program Files\MyApp\MyAssembly.dll.
C:\Program Files\MyApp\MyAssembly\MyAssembly.dll.
C:\Program Files\MyApp\MyAssembly.exe.
C:\Program Files\MyApp\MyAssembly\MyAssembly.exe.
C:\Program Files\MyApp\de\MyAssembly.dll.
C:\Program Files\MyApp\de\MyAssembly\MyAssembly.dll.
C:\Program Files\MyApp\de\MyAssembly.exe.
C:\Program Files\MyApp\de\MyAssembly\MyAssembly.exe.
To access an assembly that is not in the directory tree of the application, you
can use the Assembly.LoadFrom() method, providing the location where the
assembly can be found. To use Assembly.LoadFrom(), you must include the
using directive, using System.Reflection. The following code demonstrates
how to call LoadFrom():
Assembly PrivateAssembly;
PrivateAssembly =
Assembly.LoadFrom ("C:\\PrivateAssembly.dll");
// Obtain a reference to a method known to
// exist in the assembly.
MethodInfo Method =
PrivateAssembly.GetTypes()[0].GetMethod("CalculateSum");
6 Module 9: Deploying Windows Forms Applications
Strong-named assemblies
Strong names identify assemblies uniquely and allow for
features that guarantee the assembly is authentic and has not
been tampered with
Benefits of strong names
Where strong-named assemblies can reside
Where strong-named assemblies should reside
Private assemblies vs. strong-named assemblies
The tool used to create the assembly generates a hash of the file that contains
the assembly’s manifest. The private key is used to sign the hash (digital
signature). The digital signature is stored in the PE file that contains the
manifest for the assembly. The public key is used by the client of the strong-
named assembly to decrypt its digital signature.
Benefits of strong Strong names guarantee name uniqueness by relying on unique key pairs. No
names one can generate the same assembly name that you can, because an assembly
generated with one private key has a different name than an assembly generated
with another private key.
Strong names protect the version lineage of an assembly. A strong name can
ensure that no one can produce a subsequent version of your assembly. Users
can be sure that a version of the assembly they are loading comes from the same
publisher that created the version the application was built with.
Module 9: Deploying Windows Forms Applications 7
Strong names provide a strong integrity check. Passing the .NET Framework
security checks guarantee that the contents of the assembly have not been
changed since it was built. Note, however, that strong names in and of
themselves do not imply a level of trust, such as that provided by a digital
signature and the supporting certificate.
Where strong-named Assemblies shared by multiple applications should be installed in the global
assemblies should assembly cache, a centralized repository. .NET clients can access the same copy
reside of the assembly, which is signed and installed in the global assembly cache.
The global assembly cache can handle multiple versions of an assembly, and
it’s a secure place where assemblies can be stored. If the assembly is not going
to be shared, then the assembly should be installed in the application directory
tree. Once a strong-named assembly has been installed in the global assembly
cache, it is referred to as a shared assembly.
The only differences between a strong-named assembly and a shared assembly
are (a) where they are located and (b) during the integrity/security validation. If
the assembly is installed in the global assembly cache, the runtime checks the
assembly during the install. If the assembly is not installed in the global
assembly cache, the integrity is checked at run time.
Differences between Some key differences between private and strong-named assemblies are listed
private and strong- below.
named assemblies
Private assemblies:
Can only be installed in an application’s directory structure.
Are referenced only by their simple name.
Can have version information, but the runtime does not use it.
Are not installed in the global assembly cache and therefore the runtime will
not look in the global assembly cache when probing for the private
assembly.
8 Module 9: Deploying Windows Forms Applications
Strong-named assemblies:
Can be installed in a number of different locations.
Are referenced by their simple name, culture, version, and public key.
Contain version information that the runtime checks when loading the
assembly.
Can be installed in the global assembly cache and therefore the runtime will
look in the global assembly cache as part of the probing process.
Can have multiple versions deployed in a side-by-side manner in the global
assembly cache.
For more information about both private and strong-named assemblies, see
Course 2350A, Securing and Deploying Microsoft .NET Applications.
Module 9: Deploying Windows Forms Applications 9
sn
sn –k
–k CalcKey.snk
CalcKey.snk
[assembly:
[assembly: AssemblyKeyFile("CalcKey.snk")]
AssemblyKeyFile("CalcKey.snk")]
[assembly:
[assembly: AssemblyVersion("2.1.45.0")]
AssemblyVersion("2.1.45.0")]
Examples of assembly The AssemblyKeyFile attribute tells the compiler to create a strong-named
attributes assembly and indicates where the key pair can be found. The following example
demonstrates the use of the AssemblyKeyFile and AssemblyVersion attributes
(note that the AssemblyVersion attribute is not used to force the compile to
build a strong-named assembly, but is needed to give the assembly a version
number):
using System.Reflection;
…
[assembly: AssemblyKeyFile("CalcKey.snk")]
[assembly: AssemblyVersion("2.1.45.0")]
There are other assembly attributes that can be added to the AssemblyInfo file.
For more information about assembly attributes, search on the phrase
assembly-level attributes in Visual Studio .NET online Help.
Module 9: Deploying Windows Forms Applications 11
Troubleshooting Default binding policy refers to the process by which the runtime locates an
assembly based on the binding information contained in the application. An
application will be bound to an assembly it was built and tested with, even if a
newer version of the assembly is available. Default binding policy is always
used unless it is explicitly overridden.
8. Locate the next TODO comment. Add a new attribute at the bottom of the
file to reference the strong name key pair file.
[assembly: AssemblyKeyFile("CalcKey.snk")]
9. Open the Calculator.cs source file.
10. Locate the TODO comment. Change the versionInfo string from v2.0.1.1 to
v3.0.1.1.
private static string versionInfo = "Calculator v3.0.1.1";
11. Rebuild the assembly and then close Visual Studio.NET.
12. In a Visual Studio .NET Command Prompt window, change directories to
install_folder\Practices\Mod09\Mod09_01\Starter\CalculatorEngine\
bin\Debug.
13. At the command prompt, run ILDASM on CalculatorEngine.dll.
ildasm CalculatorEngine.dll
14. Open the MANIFEST sub-node.
15. Notice that under the .assembly CalculatorEngine entry, there is a
.publickey entry. This indicates that CalculatorEngine is a strong-named
assembly.
16. Close the MANIFEST window and ILDASM.
Using MSCORCFG.msc The .NET Framework Configuration tool is a Microsoft Management Console
(MMC) snap-in that allows you to manage and configure assemblies in the
global assembly cache, adjust code access security policy, and adjust remoting
services.
Using a Windows When you create a Microsoft Windows Installer 2.0 setup project for your
Installer 2.0 setup application, you can add strong-named assemblies to the Global Assembly
project Cache node of your setup project.
Module 9: Deploying Windows Forms Applications 19
When your application is installed by using the Windows Installer, these strong-
named assemblies will be installed into the global assembly cache of the
computer where the installed project is run. For more information about setup
projects see the lesson, Deploying Windows Forms Applications, Module 9,
“Deploying Windows Forms Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows (Visual C# .NET).
20 Module 9: Deploying Windows Forms Applications
Important During development, you can use the global assembly cache tool
(GACUtil) to install your assembly in the global assembly cache for testing
purposes. This tool is available for convenience only and should not be used for
production deployment. For production environments, assemblies should be
installed in the global assembly cache by using Windows Installer or by using
the .NET Framework configuration tool, Mscorcfg.msc.
Example of an Application configuration files contain hierarchical elements and some of these
application elements can have attributes. Here is an example of a simple application
configuration file configuration file.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="CalculatorEngine"
publicKeyToken="3a1061701aba2b5b"
culture="en-US"/>
<bindingRedirect oldVersion="3.0.1.1"
newVersion="4.0.1.1"/>
<codeBase version="4.0.1.1"
href="file:///C:/Program
Files/MyApplications/WindowsCalculator/CalculatorEngine.dll"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Note The path for the <codeBase> element may differ from the one shown in
the example configuration file, depending on where the referenced assembly is
located.
<configuration>
<configuration>
<runtime>
<runtime>
<assemblyBinding>
<assemblyBinding>
<dependentAssembly>
<dependentAssembly>
<assemblyIdentity>
<assemblyIdentity>
<bindingRedirect>
<bindingRedirect>
<codeBase>
<codeBase>
<publisherPolicy>
<publisherPolicy>
<probing>
<probing>
<publisherPolicy>
<publisherPolicy>
.. .. ..
<configuration>
<configuration>
(continued)
Element Description
Element Attributes
<assemblyIdentity>
name (required)
publicKeyToken (optional)
culture (optional)
<codeBase>
version (required)
href (required)
<bindingRedirect>
oldVersion (required)
newVersion (required)
<probing>
privatePath (required)
<publisherPolicy>
apply (required)
(continued)
Element Attribute Description
6. Display the contents of the global assembly cache by typing the following
command:
gacutil –l
7. Scroll through the list to find CalculatorEngine. There should be two
versions of CalculatorEngine in the global assembly cache. One version is
4.0.1.1 and the other is 5.0.1.1.
Publisher policy
Machine policy
Enterprise policy
Safe-mode
Safe-mode versioning
versioning
Important Prior to performing this demonstration, run the Fusion Log Viewer
and enable the Log Failures checkbox. If you do not do so, the run time will
not log probing errors and the following practice will not work as expected. It is
also beneficial to leave tracking of log failures turned on at all times to help you
in troubleshooting application problems.
Instructions
Run the WindowsCalculator application
1. In Windows Explorer, browse to
install_folder\Democode\Mod09\Mod09_03.
2. Double-click WindowsCalculator.exe to run the application. Notice that
the version number of the CalculatorEngine is 3.0.1.1.
Packaging applications
As a set of executables and DLLs
Microsoft Windows Installer 2.0 package
Cabinet files
Deploying applications
XCOPY
Windows Installer 2.0
Code download
Executables and DLLs A set of executables and DLLs in No packaging is required with .NET
the original folder hierarchy in applications and assemblies. You can use the
which the application was built. EXE and DLL files as they were built.
Windows Installer 2.0 Use Visual Studio .NET to create This is the standard way of distributing and
.msi files for use with the installing applications that run on the desktop.
Windows Installer. Other applications can also be deployed by
using .msi files. For example, Microsoft
ASP.NET applications can be packaged in an
.msi file.
38 Module 9: Deploying Windows Forms Applications
(continued)
Packaging Option Description Comments
Cabinet Files Use Visual Studio .NET to create The following restrictions apply when creating
cabinet (.cab) files for deployment the .cab file for .NET compatible applications:
of a .NET Framework application.
Only one assembly can be stored in a .cab file.
The .cab file must have the same name as the
file in the assembly that contains the manifest.
For example, if the file containing the manifest
in the assembly is called MyClasses.dll, then
the .cab file must be named MyClasses.cab.
Deployment Options This table compares the deployment options available for .NET applications.
Deployment Option Description Comments
XCOPY Because common language runtime applications Easiest way to install an application.
are self-describing and require no registry entries, To remove the application from the
you can use XCOPY to copy the application to an computer, just delete for directory
appropriate directory. The application can then be structure for the application.
run from that directory. You can also use FTP to
deploy your application. Installs private and strong-named
assemblies only. No shared
assemblies can be installed this way.
Windows Installer 2.0 Windows Installer 2.0 can install, repair, or Use a Visual Studio .NET setup
remove Microsoft .NET Framework assemblies in project to build an .msi file.
the GACand in private directories. This is the Installation, repair, and removal of
recommended way to deploy Windows Forms assemblies in the global assembly
Applications. cache.
Install, repair, or remove assemblies
in private locations designated for
particular applications.
Rollback unsuccessful installations,
repairs, or removals of assemblies.
Install-on-demand strong-named
assemblies in the GACand in private
locations designated for particular
applications.
Code Download If you are distributing your application over the
Internet or through a corporate intranet, you can
download the code to a computer and run the
application.
Module 9: Deploying Windows Forms Applications 39
Note Remember to add files from a Release build, not a Debug build, to setup
projects.
Components of a This table describes the uses for the various components of a Windows Installer
Windows Installer setup setup project.
project
Setup Component Description
Add
Add any
any shared
shared assemblies
assemblies to the
the Global
Global Assembly
Assembly Cache
Cache folder
folder of the
the
project
Build
Build the
the project
In
In Explorer double-click the Setup.exe file created by the setup
setup project
project to
to
install
install the
the application
application
6. To add any shared assemblies to the global assembly cache at setup time
(these are strong-named assemblies that will be shared among multiple
applications), in the File System tree, right-click the File System on Target
Machine root node, click Add Special Folder, and then click Global
Assembly Cache Folder. Right-click the Global Assembly Cache Folder,
point to Add, and then click Assembly. Use the Component Selector to
browse and a select any strong-named assemblies you wish to add to the
global assembly cache.
14. Right-click the Application Folder, and then click Properties Window. In
the Properties window, change the DefaultLocation property to
[ProgramFilesFolder]\[ ProductName] by removing the Manufacturer
entry. Also, change the AlwaysCreate property to True.
15. In Solution Explorer, expand Detected Dependencies. In the Detected
Dependencies folder, right-click CalculatorEngine.dll, and then click
Exclude.
16. To create a shortcut for the User’s Desktop, select the Application Folder
again, and then click WindowsCalculator.exe.
When you reach step 24, you will be directed to repeat steps 16 through 22
to create a second shortcut for the Program menu.
17. On the Action menu, click Create Shortcut to WindowsCalculator.exe.
Rename the shortcut to Windows Calculator.
18. In the Properties window, make sure the Target property is set to
WindowsCalculator.
19. Click on the Icon property and select Browse.
20. In the Icon dialog box, click Browse.
21. Select Application Folder from the Look In dropdown list and click on
KEYS03.ICO.
22. Click OK and then click OK in the Icon dialog box.
23. Drag the shortcut from the Application Folder to the User’s Desktop node.
24. To create a shortcut for the Program menu, repeat steps 16 through 22
again to create another shortcut with the same name.
25. Drag the shortcut to the User’s Program Menu node.
26. In Solution Explorer, click the WinCalc project. In the Properties window,
set the following properties to their associated values.
Property Value
Review
.NET Assemblies
Deploying Windows Forms Applications
Scenario Many applications that you create for the .NET Framework will require the use
of assemblies that are not included with the application assembly. The
referenced assembly may be installed into the global assembly cache, or it may
reside in a location other than the application’s folder.
In this lab, you will create a strong-named assembly and then reference this
assembly from an application. You will then deploy the application by using a
Setup and Deployment project to build a Windows Installer file. In addition,
you will upgrade the strong-named assembly to a new version and modify the
application to use the new assembly through the use of application
configuration files.
Estimated time to
complete this lab:
30 minutes
50 Module 9: Deploying Windows Forms Applications
Exercise 1
Building and Referencing a Strong-Named Assembly
In this exercise, you will use the Expense Reporting application to build a strong-named assembly.
You will then use the Internal Business Application shell application to reference the strong-named
assembly. You will also use ILDASM to verify that ExpenseReport.DLL is a strong-named
assembly.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab09_1\Ex01\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab09_1\Ex01\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the ExpenseReport project in Visual Studio a. For more information about opening a project
.NET. Browse to file, see the following resource:
install_folder\Labfiles\Lab09_1\Ex01\Starter\ • The Visual Studio .NET Help documentation.
ExpenseReportApp to find the project files. In Search, select the Search in titles only
check box, then search by using the phrase
Open Project Dialog Box.
2. Build the expense report project. Keep this a. For more information about building an
instance of Visual Studio .NET open. application, see the following resource:
• The Visual Studio .NET Help documentation.
Search by using the phrase Preparing and
Managing Builds.
3. Open the InternalBusinessApp project in another a. For more information about opening a project
instance of Visual Studio.NET. Browse to file, see the following resource:
install_folder\Labfiles\Lab09_1\Ex01\Starter\ • The Visual Studio .NET Help documentation.
Business Application Shell to find the project In Search, select the Search in titles only
files. check box, then search by using the phrase
Open Project Dialog Box.
4. Add a reference to the ExpenseReport DLL file. a. For more information about how to add a
reference to an assembly by using Visual Studio
.NET, see the following resource:
• Practice: Working with the Global Assembly
Cache in Module 9, “Deploying Windows
Forms Applications,” in Course 2555A,
Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
5. Build and test the internal business application. No additional information is necessary for this task.
Keep this instance of Visual Studio .NET open.
6. Open a Visual Studio .NET Command Prompt a. For more information about how to open a Visual
window and change directories to the location of Studio .NET Command Prompt window, see the
InternalBusinessApp.exe. Browse to following resource:
install_folder\Labfiles\Lab09_1\Ex01\ • Practice: Calling a Strong-Named Assembly
Starter\Business Application Shell\bin\Debug to in Module 9, “Deploying Windows Forms
find the executable. Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
Module 9: Deploying Windows Forms Applications 51
7. Run ILDASM, and view the information for a. For more information about how to use ILDASM,
InternalBusinessApp.exe. View the MANIFEST, see the following resources:
and note that the reference to the ExpenseReport • Practice: Calling a Strong-Named Assembly
assembly does not include a public key token. in Module 9, “Deploying Windows Forms
Close ILDASM. Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase MSIL
Disassembler (Ildasm.exe).
8. In a Visual Studio .NET Command Prompt a. For more information about how to open a
window, change directories to where the command prompt window in Visual Studio .NET,
ExpenseReport project is located. Browse to see the following resource:
install_ folder\Labfiles\Lab09_1\Ex01\Starter\ • Practice: Calling a Strong-Named Assembly
ExpenseReportApp to find the project. in Module 9, “Deploying Windows Forms
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
9. Run the strong-name tool to generate a strong- a. For more information about SN.EXE, see the
name key pair file. following resource:
• Name the strong-name key pair file • The .NET Framework SDK documentation.
ExpenseReport.snk. Search by using the phrases Strong Name
Tool (Sn.exe) and Creating a Key Pair.
10. Switch to the Visual Studio .NET instance in a. For more information about how to use ILDASM,
which the ExpenseReport project is open. see the following resource:
a. Complete the AssemblyKeyFile attribute to • Practice: Calling a Strong-Named Assembly
reference the ExpenseReport.snk key pair file. in Module 9, “Deploying Windows Forms
b. Rebuild the ExpenseReport project. Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
b. For more information about global attributes and
the AssemblyInfo file, see the following resource:
• The .NET Framework SDK documentation.
Search by using the phrase Global
Attributes.
11. Switch to the Visual Studio .NET instance in a. For more information about how to use ILDASM,
which the InternalBusinessApp project is open. see the following resources:
a. Rebuild and run the application. • Practice: Calling a Strong-Named Assembly
b. In a Visual Studio .NET Command Prompt in Module 9, “Deploying Windows Forms
window, run ILDASM to view the Applications,” in Course 2555A, Developing
information for InternalBusinessApp.exe. Microsoft .NET Applications for Windows
(Visual C# .NET).
c. View the MANIFEST. Notice that the
reference to the ExpenseReport assembly now • The .NET Framework SDK documentation.
includes a public key token. Search by using the phrase MSIL
Disassembler (Ildasm.exe).
52 Module 9: Deploying Windows Forms Applications
Exercise 2
Installing a Strong-Named Assembly into the Global Assembly
Cache
In this exercise, you will update the ExpenseReport assembly to version 2.0.1.1 and install it into
the global assembly cache. You will then build and run the Internal Business Application to
reference the ExpenseReport assembly and use ILDASM to verify that the Internal Business
Application is referencing the correct version of the ExpenseReport assembly.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab09_1\Ex02\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab09_1\Ex02\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the ExpenseReport project in Visual Studio a. For more information about opening a project
.NET. Update the AssemblyVersion attribute to file, see the following resource:
"2.0.1.1" and build the expense report project. • The Visual Studio .NET Help documentation.
Browse to install_folder\Labfiles\Lab09_1\ In Search, select the Search in titles only
Ex02\Starter\ExpenseReportApp to find the check box, then search by using the phrase
project. Open Project Dialog Box.
2. Open the InternalBusinessApp project in another a. For more information about opening a project
instance of Visual Studio.NET. Browse to file, see the following resource:
install_folder\Labfiles\Lab09_1\Ex02\Starter\ • The Visual Studio .NET Help documentation.
Business Application Shell to find the project. In Search, select the Search in titles only
check box, then search by using the phrase
Open Project Dialog Box.
3. Add a reference to the ExpenseReport DLL file. a. For more information about how to add a
Browse to install_folder\Labfiles\Lab09_1\Ex02\ reference to an assembly using Visual Studio
Starter\ExpenseReportApp\bin\Debug to find the .NET, see the following resource:
DLL. • Practice: Working with the Global Assembly
Cache in Module 9, “Deploying Windows
Forms Applications,” in Course 2555A,
Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
4. In Solution Explorer, beneath References, click No additional information is necessary for this task.
the ExpenseReport entry.
a. Change the Copy Local property to False.
This prevents Visual Studio .NET from
copying the ExpenseReport.dll file into the
debug folder of the Internal Business
Application.
b. Build the Internal Business Application.
Module 9: Deploying Windows Forms Applications 53
5. Open a command prompt window in a. For more information about how to open a
Visual Studio .NET, and change directories to the command prompt window in Visual Studio .NET,
location where ExpenseReport.dll is located. see the following resource:
Browse to install_folder\Labfiles\Lab09_1\ • Practice: Calling a Strong-Named Assembly
Ex02\Starter\ExpenseReportApp\bin\Debug to in Module 9, “Deploying Windows Forms
find the file. Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
6. Run GACUTIL to install ExpenseReport.dll into a. For more information about how to use
the global assembly cache. GACUTIL, see the following resource:
• View the global assembly cache after • Practice: Working with the Global Assembly
installing the ExpenseReport.dll assembly. Cache in Module 9, “Deploying Windows
There should be an entry for ExpenseReport Forms Applications,” in Course 2555A,
in the global assembly cache. Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
7. Run the Internal Business Application. No additional information is necessary for this task.
8. Open a Visual Studio .NET Command Prompt a. For more information about how to open a Visual
window and change directories to the location Studio .NET Command Prompt window, see the
where InternalBusinessApp.exe is located. following resource:
Browse to install_folder\Labfiles\Lab09_1\ • Practice: Calling a Strong-Named Assembly
Ex02\Starter\Business Application in Module 9, “Deploying Windows Forms
Shell\bin\Debug to find the executable file. Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
9. Run ILDASM, and view a. For more information about how to use ILDASM,
InternalBusinessApp.exe. see the following resources:
• View the MANIFEST. Notice that the • Practice: Calling a Strong-name Assembly in
reference to the ExpenseReport assembly is Module 9, “Deploying Windows Forms
now to version 2.0.1.1. Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase MSIL
Disassembler (Ildasm.exe).
54 Module 9: Deploying Windows Forms Applications
Exercise 3
Deploying a .NET Application
In this exercise, you will package the Expense Reporting application into a Windows Installer file
by using a Setup and Deployment project. You will then install the application on the local
computer.
Note The Internal Business Application component of the Expense Reporting application requires
that the Expense Report XML Web service be installed on the target computer. This exercise
assumes that the Expense Report XML Web service has already been installed on the target
computer.
1. Open the InternalBusinessApp project in Visual a. For more information about opening a project
Studio .NET. Browse to file, see the following resource:
install_folder\Labfiles\Lab09_1\Ex03\Starter\ • The Visual Studio .NET Help documentation.
Business Application Shell to find the project In Search, select the Search in titles only
files. check box, then search by using the phrase
Open Project Dialog Box.
2. Build the InternalBusinessApp project. Close the a. For more information about building an
InternalBusinessApp solution, but keep Visual application, see the following resource:
Studio .NET open. • The Visual Studio .NET Help documentation.
Search by using the phrase Preparing and
Managing Builds.
3. Create a new Setup and Deployment project. Use a. For more information about how to create a new
the template that will create a Windows Installer Setup and Deployment project, see the following
setup project. resource:
• Set the project name to • Topic: How to Create and Use a Windows
InternalBusinessApplication. Installer Setup Project in Module 9,
• Set the project location to “Deploying Windows Forms Applications,”
install_folder\Labfiles\Lab09_1\ in Course 2555A, Developing Microsoft .NET
Ex03\Starter. Applications for Windows (Visual C# .NET).
Module 9: Deploying Windows Forms Applications 55
4. Add the global assembly cache folder to the a. For more information about how to add the global
project. assembly cache folder, see the following
resource:
• Practice: Creating and Using a Windows
Installer Deployment Project in Module 9,
“Deploying Windows Forms Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
b. For more information about deploying
applications, see the following resources:
• Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
5. Add the localized folders to the Application a. For more information about how to add the
folder. Application folder, see the following resource:
a. Right-click Application folder, point to Add, • Practice: Creating and Using a Windows
and select Folder. Installer Deployment Project in Module 9,
b. Create folders with the following names: “Deploying Windows Forms Applications,”
de, de-DE, en, en-US, fr, fr-FR, ja, and ja-JP. in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
b. For more information about deploying
applications, see the following resources:
• Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
6. Add the InternalBusinessApp.exe file to the a. For more information about deploying
Application folder. Browse to applications, see the following resources:
install_folder\Labfiles\Lab09_1\Ex03\Starter\ • Lesson: Deploying Windows Forms
Business Application Shell\bin\Debug to find the Applications in Module 9, “Deploying
InternalBusinessApp.exe file. Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
56 Module 9: Deploying Windows Forms Applications
7. Add the ExpenseReport.dll file to the global a. For more information about how to add the global
assembly cache folder. Browse to assembly cache folder, see the following
install_folder\Labfiles\Lab09_1\Ex03\ resource:
Starter\Business Application Shell to find the • Practice: Creating and Using a Windows
ExpenseReport.dll. Installer Deployment Project in Module 9,
“Deploying Windows Forms Applications,”
in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
b. For more information about deploying
applications, see the following resources:
• Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
8. Add the localized resource assemblies to their a. For more information about packaging and
associated folders in the setup project. These deploying resources, see the following resource:
folders are the localized folders that you created • The .NET Framework SDK. Search by using
in step 5. Browse to install_folder\Labfiles\ the phrase Deploying Applications.
Lab09\Ex03\Starter\Business Application
Shell\bin\Debug to find the folders that contain
the localized resource files.
9. Create the directory for the Help file, and add it to a. For more information about deploying
the project. applications, see the following resources:
a. Name the custom folder IISRoot. • Lesson: Deploying Windows Forms
b. Set the DefaultLocation property of IISRoot Applications in Module 9, “Deploying
to C:\inetpub\wwwroot. Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
c. Browse to install_folder\ Labfiles\Lab09_1\ Applications for Windows (Visual C# .NET).
Ex03\Starter\Business Application Shell, find
the InternetBusinessAppHelp.htm file, and • The .NET Framework SDK. Search by using
add it to IISRoot. the phrase Deploying Applications.
Module 9: Deploying Windows Forms Applications 57
10. Set the following project properties. No additional information is necessary for this task.
Property Value
Author Contoso, Ltd.
Manufacturer Contoso Ltd
ProductName Internal Business Application
Title Internal Business Application
Version 3.0.1
a. When prompted to change the ProductCode
and PackageCode properties, click Yes.
b. Set the AlwaysCreate property for the
Application folder to True.
11. Create the application shortcuts. a. For more information about deploying
applications, see the following resources:
• Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
Warning: A new dependency to ExpenseReport.dll may appear under Detected Dependencies in
Solution Explorer. If this occurs, right-click the ExpenseReport.dll dependency, and select Exclude
from the context menu. If you do not do this, a copy of the ExpenseReport.dll file will be installed in
the target application folder in addition to the global assembly cache, and your application will use the
.dll file from the application folder instead of the .dll from the global assembly cache.
12. Build the project, and install the Internal Business a. For more information about deploying
Application. Browse to install_folder\ applications, see the following resources:
\Labfiles\Lab09_1\Ex03\Starter\ • Lesson: Deploying Windows Forms
InternalBusinessApplication\Debug to find the Applications in Module 9, “Deploying
Setup.exe file. Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
13. Test the Internal Business Application. a. For more information about deploying
• Test the different region/culture settings that applications, see the following resources:
the application supports. • Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
58 Module 9: Deploying Windows Forms Applications
Exercise 4
Using an Application Configuration File
In this exercise, you will create an application configuration file that will redirect the Internal
Business Application to load a new version of the ExpenseReport.dll file.
There are starter and solution files associated with this exercise. Browse to
install_folder\Labfiles\Lab09_1\Ex04\Starter to find the starter files, and browse to
install_folder\Labfiles\Lab09_1\Ex04\Solution to find the solution files. If you performed a default
installation of the course files, install_folder corresponds to C:\Program Files\Msdntrain\2555.
1. Open the Visual Studio .NET Command Prompt a. For more information about how to create
window and install the ExpenseReport.dll file into application configuration files, see the following
the global assembly cache. After the file is resource:
installed in the global assembly cache, delete it • Practice: Creating and Using Application
from the folder. Browse to install_folder\ Configuration Files in Module 9, “Deploying
Labfiles\Lab09_1\Ex04\Starter to find the Windows Forms Applications,” in Course
ExpenseReport.dll file. 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
b. For more information about configuration files,
see the following resources:
• Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Configuration Files.
2. Run the .NET Configuration Tool, and create a a. For more information about how to create
new application configuration file for the application configuration files, see the following
InternalBusinessApp.exe application. Change the resource:
BindingRedirect entry from 3.0.1.1 to 4.0.1.1. • Practice: Creating and Using Application
Browse to install_folder\Labfiles\Lab09_1\Ex04\ Configuration Files in Module 9, “Deploying
Starter to find the InternalBusinessApp.exe file. Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
b. For more information about configuration files,
see the following resources:
• Lesson: Deploying Windows Forms
Applications in Module 9, “Deploying
Windows Forms Applications,” in Course
2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Configuration Files.
Module 9: Deploying Windows Forms Applications 59
Overview 1
Lesson: Security in the .NET Framework 2
Lesson: Using Code Access Security 14
Lesson: Using Role-Based Security 29
Review 40
Lab 10.1: Adding and Testing Permission
Requests 42
Course Evaluation 46
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Module 10: Securing Windows Forms Applications iii
Instructor Notes
Presentation: This module starts with an overview of the Microsoft® .NET Framework
75 minutes security model. In this module, students learn how to use code access security
and role-based security in their applications.
Lab:
30 minutes After completing this module, students will be able to:
Describe the .NET Framework security model.
Use code access security to secure an application.
Use role-based security to control access to an application.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2555A_10.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this module.
Review the animation for this module.
Complete the demonstrations, practice, and lab.
iv Module 10: Securing Windows Forms Applications
Overview
Security Basics
What is Evidence?
What are Permissions?
How Does Code Access Security Work?
Animation: Code Access Security
What is Role-Based Security?
What is Authentication?
What is Authorization?
Security Basics
Security policy
Role-based security
Permissions granted to users based on:
User name
Roles
Windows group(s)
Generic and custom principals and identities
Microsoft .NET Passport
What is Evidence?
The creator of an assembly can also include custom evidence with the
assembly. This custom evidence is evaluated only if security policy is
configured to use the custom evidence.
Strength of evidence Some forms of evidence are stronger than others and can therefore be used to
make more far-reaching security policy decisions.
Strong names, for instance, provide an extremely reliable form of evidence,
because they are very difficult to falsify unless the publisher’s private key has
been compromised. Authenticode signatures are also strong forms of evidence.
Conversely, evidence such as an assembly’s zone or URL is weaker. Web sites
can be hacked, and packets can be tampered with over the Internet. It is a risk to
grant permissions based heavily on weaker forms of evidence. However, both
strong and weak forms of evidence can be combined in an effective security
policy.
Module 10: Securing Windows Forms Applications 5
(continued)
Code access permission class Resource protected
Code Groups
Gather
Gather evidence
evidence Repeat
Repeat this
this same security
security check
check
for
for assembly
assembly for
for all
all security
security policy
policy levels
levels
Policy levels
Assign
Assign assembly
assembly to
to Enterprise
code
code group(s)
group(s) Machine
User
Application domain (optional)
Assembly
Assembly getsgets Per assembly grant
UNION Assembly
Assembly gets
gets INTERSECTION
INTERSECTION of of
of permission
permission sets
sets permission sets
sets for
for all
all policy
policy levels
levels
for
for its
its code
code groups
groups
Security policy levels Security policy is organized into different policy levels: enterprise policy level,
machine policy level, user policy level, and an optional application domain
policy level.
Security Policy Levels Description
LocalIntranet
Allows code to execute, to create user interface elements without
restrictions; to use isolated storage with no quota; to use DNS services; to
read the USERNAME, TEMP, and TMP environment variables; to make
Web connections to the same site the assembly originates from; and to read
files in the same folder as the assembly. Under default security policy, all
code from the LocalIntranet zone receives this permission set.
Module 10: Securing Windows Forms Applications 9
Everything
Provides all standard permissions except permission to skip verification.
FullTrust
Provides full access to all resources protected by permissions. Under default
security policy, all code from the local computer zone receives this
permission set.
10 Module 10: Securing Windows Forms Applications
Identity
Typically consists of user’s log on name
Principal
Typically consists of role(s) associated with a user
Roles can be
Microsoft Windows user and group
- Or -
Custom (using generic principals and identities)
Authenticated identity generally == identity + principal
What is Authentication?
What is Authorization?
Final
Final permission
permission grant
grant
is
is the
the intersection
intersection of what
what assembly
assembly
requested
requested and and security
security policy
policy allows
allows
Final permission grant The permissions the assembly actually receives are the result of the following
operation:
FG = SP ∩ ((M ∪ O) – R)
Where FG is the final grant, SP is the permission set an assembly receives from
security policy, ∩ is intersection of sets, M is the minimum permission request,
∪ is the union of sets, O is the optional permission request, and R is the refused
permission request.
18 Module 10: Securing Windows Forms Applications
//
// Add
Add attributes
attributes toto the
the AssemblyInfo
AssemblyInfo source
source file
file
//
// Request
Request for
for aa specific
specific permission
permission
[assembly:UIPermission(
[assembly:UIPermission( Assembly
Assembly scope
scope
SecurityAction.RequestMinimum,
SecurityAction.RequestMinimum,
Window
Window == UIPermissionWindow.SafeTopLevelWindows)]
UIPermissionWindow.SafeTopLevelWindows)]
//
// Request
Request for
for aa permission
permission set
set
[assembly:PermissionSet
[assembly:PermissionSet ((
SecurityAction.RequestMinimum,
SecurityAction.RequestMinimum,
Name
Name == "LocalIntranet")]
"LocalIntranet")]
2. If you make any optional permission requests, your code may be granted the
permission. However, if it is not, you’ll have to add code to handle security
exceptions.
Example: Handling using System.Security;
security exceptions using System.IO;
FileStream fs = null;
try
{
// open a file for reading
fs = new FileStream("C:\\log.txt",
FileMode.Open,
FileAccess.Read);
// read from file
…
}
catch (SecurityException se)
{
// display error message
MessageBox.Show(“ExceptionMessage: “ + se.Message);
}
20 Module 10: Securing Windows Forms Applications
6. Click the Membership Condition tab, and point out that the membership
condition for this code group is Internet zone.
a. Click the Condition type box to show the different conditions available
for use in a membership condition.
b. Select the Strong Name condition type, and point out that the
parameters for the condition type change.
c. Click the Condition type box and change it back to Zone.
7. Click the Permission Set tab, and point out that the permission set granted
for this code group is the Internet permission set.
a. Click the Permission set box to show the different permission sets
available for use, but do not change the permission set. This tab also
shows the permissions that make up the Internet permission set.
b. In the Permission list, click User Interface, and then click the View
Permission button. Point out that the Permission Viewer dialog box
displays the user interface-related permissions that are granted as part of
the Internet permission set.
c. Click Close to close the Permission Viewer dialog box.
d. Click Security, and then click View Permission. Point out the security-
related permissions that are either granted or denied as part of the
Internet permission set.
e. Click Close to close the permission viewer dialog box.
f. Click Cancel to close the Internet_Zone Properties dialog box.
8. The default security policy for the user and enterprise policy levels is that all
code gets the FullTrust permission set.
a. To show this in the console tree, in the Runtime Security Policy node,
expand the Enterprise and Code Groups nodes, and then, in the
Enterprise hierarchy, click All_Code. Point out that it grants FullTrust.
b. Do the same thing for the All_Code node in the User hierarchy, pointing
out that it looks the same and also grants FullTrust. Explain that code
will not get FullTrust based on these policy levels, because the policy
grants for the user and enterprise policy levels will be intersected with
the policy grant for the machine policy level to determine the final
permission grant. Assuming that the machine policy level grants
something less than FullTrust when the enterprise and user policy levels
are intersected with the machine policy level, an assembly would get the
permission set associated with the machine policy level.
c. Collapse the Enterprise and User hierarchies before moving to the next
step.
9. The snap-in also allows viewing of permission sets.
a. In the Machine node, expand Permission Sets. This shows a list of the
permission sets for the machine policy level.
b. Under the Permission Sets list, click Internet, and point out that the
permissions that make up the Internet permission set are shown in the
details pane.
22 Module 10: Securing Windows Forms Applications
The following table lists the command-line options used in the examples in this
topic.
Command-line
option Action or qualifier Comments
Procedure: Using The Code Access Security tool is quick way to view security policy.
Caspol.exe to view
security policy 1. To list all available information about code groups and permission sets,
information open the Microsoft Visual Studio® .NET Command Prompt window and
type the following command:
Caspol –l
To open the Visual Studio .NET Command Prompt window, click Start,
point to All Programs, point to Microsoft Visual Studio .NET, point to
Visual Studio .NET Tools, and then click Visual Studio .NET Command
Prompt.
2. To list code groups, open the Visual Studio .NET Command Prompt
window and type the following command:
Caspol –lg
Module 10: Securing Windows Forms Applications 25
By default, all code running on the local computer receives the FullTrust
permission set. Often, when testing the security characteristics of your code, it
is convenient to have your code run with different permission sets. An easy way
to do this is to create a test folder and configure security policy to treat this
folder as a different zone.
Procedure: Testing your You can also use the Code Access Security tool to set up security context test
application by using environments for your applications.
Caspol.exe
1. Create a folder named C:\testfolder.
2. To create a new code group to test an application that you want to run with
the Internet permission set, open the Visual Studio .NET Command Prompt
window and type the following command:
Caspol –ag 1 –url file:///C:/testfolder/* Internet
-n Test_Group –exclusive on
This adds a new exclusive code group at the machine policy level with a
URL membership condition of file:///C:/test/* that grants the Internet
permission set and is named Test_Group. The code group must be
exclusive. This ensures that other code groups that would normally match
your assembly are ignored, as in the case of code whose zone is
MyComputer, which would usually be granted FullTrust. You can then copy
your application to the test directory, and when you run it, it will get the
Internet permission set.
To open the Visual Studio .NET Command Prompt window, click Start,
point to All Programs, point to Microsoft Visual Studio .NET, point to
Visual Studio .NET Tools, and then click Visual Studio .NET Command
Prompt.
3. To change this code group to test your application against the LocalIntranet
permission set, type the following command:
Caspol –cg Test_Group LocalIntranet
4. To remove your test code group by typing the following command:
Caspol –rg Test_Group
Important Do not turn off security. The Code Access Security tool has an
option that allows you to turn off security. Avoid using this option if at all
possible.
26 Module 10: Securing Windows Forms Applications
4. Click each of the three buttons at the top of the form and notice that all of
the operations succeed.
This happens because the code is running with the FullTrust permission
set, with no permission request restrictions.
5. Click Exit to quit the application.
Username = Fred
Role = Manager
Manager
Administrator
Custom identity
Represents an identity that encapsulates custom user information. Any
custom identity class must implement the IIdentity interface.
All identity classes must implement the IIdentity interface. The IIdentity
interface has three public properties, listed in the following table.
Property Description
Principals A principal object represents the security context under which code is running.
This includes the identity of the user, as represented by an associated identity
object, and the roles associated with the user.
A role defines a group of related users of an application. For example, a
banking application might impose limits on the withdrawal amounts that can be
transacted, based on role. In this scenario, tellers might be authorized to process
withdrawals that are less than a specified amount, while managers might be
allowed to process withdrawals above the specified amount.
Role-based security in the .NET Framework supports three kinds of principals:
Windows principal
Represents Windows users and their roles. The roles are the Windows
groups that the user is a member of. The WindowsPrincipal class
implements this kind of principal.
Generic principal
Represents users and roles that are independent of Windows users and their
roles. Essentially, the generic principal is a simple solution for application
authentication and authorization. The GenericPrincipal class implements
this kind of principal.
Custom principal
Represents application-specific role information. Any custom principal class
must implement the IPrincipal interface.
32 Module 10: Securing Windows Forms Applications
WindowsIdentity
WindowsIdentity MyIdentity
MyIdentity ==
WindowsIdentity.GetCurrent();
WindowsIdentity.GetCurrent();
WindowsPrincipal
WindowsPrincipal MyPrincipal
MyPrincipal ==
new
new WindowsPrincipal(MyIdentity);
WindowsPrincipal(MyIdentity);
CodeExample
Procedure: Creating a When you must perform role-based validation repeatedly, you can call the
WindowsPrincipal object SetPrincipalPolicy method on the System.AppDomain object.
for repeated validation
1. Call the static SetPrincipalPolicy method on the System.AppDomain
object, passing it a PrincipalPolicy enumeration value that indicates what
the policy should be. Supported values are NoPrincipal,
UnauthenticatedPrincipal, and WindowsPrincipal.
2. With the policy set, use the Thread.CurrentPrincipal property to retrieve
the principal that encapsulates the current Windows user.
34 Module 10: Securing Windows Forms Applications
//Principal values.
string Name = MyPrincipal.Identity.Name;
string Type = MyPrincipal.Identity.AuthenticationType;
string Auth =
MyPrincipal.Identity.IsAuthenticated.ToString();
//Identity values.
string IdentName = MyIdentity.Name;
string IdentType = MyIdentity.AuthenticationType;
string IdentIsAuth =
MyIdentity.IsAuthenticated.ToString();
string ISAnon = MyIdentity.IsAnonymous.ToString();
string IsG = MyIdentity.IsGuest.ToString();
string IsSys = MyIdentity.IsSystem.ToString();
string Token = MyIdentity.Token.ToString();
…
return 0;
}
}
Module 10: Securing Windows Forms Applications 35
String[]
String[] MyStringArray
MyStringArray == {"Manager",
{"Manager", "Employee"};
"Employee"};
GenericPrincipal
GenericPrincipal MyPrincipal
MyPrincipal ==
new
new GenericPrincipal(MyIdentity,
GenericPrincipal(MyIdentity, MyStringArray);
MyStringArray);
System.Threading.Thread.CurrentPrincipal
System.Threading.Thread.CurrentPrincipal == MyPrincipal;
MyPrincipal;
Important The code attaching the principal to the current thread must have
been granted the ControlPrincipal member of the SecurityPermission
class to successfully attach the principal to the thread.
36 Module 10: Securing Windows Forms Applications
For WindowsIdentity objects, the name represents the user’s login name,
including the domain.
Example You can check role membership by calling the IsInRole method on the
principal object, as shown in the second example on the slide. The example on
the slide checks if the user belongs to the DOMAIN\Administrators role.
For WindowsPrincipal objects, a role maps to a Windows group, including the
domain. When checking for membership in built-in Windows groups, you can
use the WindowsBuiltInRole enumeration. The following example uses a
hard-coded string in the call to determine if the user is a member of the built-in
Administrators role:
MyPrincipal.IsInRole("BUILTIN\\Administrators");
38 Module 10: Securing Windows Forms Applications
The code works, but it is not easily localized. The following example uses the
WindowsBuiltInRole enumeration instead, and is more easily localized:
MyPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
Note .NET Framework role-based security does not provide access to COM+
roles with these mechanisms. Classes in the System.EnterpriseServices
namespace must be used to gain access to COM+ role-based security
information.
Module 10: Securing Windows Forms Applications 39
Review
3. What are the three types of permission requests that you can make?
You can make minimum, optional, and refused permission requests.
5. What are the two ways to configure the security policy to test an
application?
You can use the .NET Framework Configuration tool (Mscorcfg.msc)
or the Code Access Security tool (Caspol.exe) to configure the security
policy.
7. Describe when you would use a WindowsPrincipal object and when you
would use a CustomPrincipal object to implement role-based security.
Use a WindowsPrincipal when your role-based security decisions are
based on Windows users and groups. Use a CustomPrincipal when your
role-based security decisions are based on another authentication
mechanism, such as a SQL Server database.
8. What method of the Principal class do you use to perform role check?
You use the IsInRole method of the Principal class.
9. What are the three main steps to implement role-based security with
GenericIdentity and GenericPrincipal objects in your application?
The three main steps to implement role-based security with
GenericIdentity and GenericPrincipal objects are:
• Create a new instance of the GenericIdentity class and initialize it
with the name you want it to hold.
• Create a new instance of the GenericPrincipal class and initialize it
with the previously created GenericIdentity object and an array of
strings that represent the roles that you want associated with this
principal.
• Attach the principal to the current thread. Attaching the principal
to the current thread is valuable in situations where the principal
must be validated several times, it must be validated by other code
running in your application, or it must be validated by a
PrincipalPermission object.
42 Module 10: Securing Windows Forms Applications
Note This lab focuses on the concepts in Module 10, “Securing Windows
Forms Applications,” in Course 2555A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET). As a result, this lab may not
comply with Microsoft security recommendations.
Lab setup There are starter and solution files associated with this lab. Browse to
install_folder\Labfiles\Lab10_1\Ex01\Starter to find the starter files, and
browse to install_folder\Labfiles\Lab10_1\Ex01\Solution to find the solution
files. If you performed a default installation of the course files, install_folder
corresponds to C:\Program Files\Msdntrain\2555.
Estimated time to
complete this lab:
30 minutes
44 Module 10: Securing Windows Forms Applications
Exercise 1
Adding and Testing Permission Requests
In this exercise, you will add some minimum permission requests to the Expense Report
application. You will also test the Expense Report application in different security contexts.
1. Open the ExpenseReport.sln solution file in a. For more information about opening a project file
Visual Studio .NET. Browse to and starting an application, see the following
install_folder\Labfiles\Lab10_1\Ex01\Starter to resource:
find the project files. • The Visual Studio .NET Help documentation.
For additional information about opening a
project file, in Search, select the Search in
titles only check box, then search by using
the phrase Open Project Dialog Box. For
additional information about starting an
application in the Designer, in Index, search
by using the phrase Debugging Windows
Applications.
2. Open the AssemblyInfo.cs file. Add minimum a. For more information about permission requests,
permission requests for the following see the following resources:
permissions: • Practice: Adding Permission Requests in
• Use of all windows. Module 10, “Securing Windows Forms
• Use of Isolated Storage, isolated by domain Applications,” in Course 2555A, Developing
and user. Use the following syntax: Microsoft .NET Applications for Windows
(Visual C# .NET). This practice contains
[assembly: information about how to add the minimum
IsolatedStorageFilePermission( permission request for the use of all windows
SecurityAction.RequestMinimum, and the optional permission request for no
UsageAllowed = permissions.
IsolatedStorageContainment.Domain
IsolationByUser)] • Lesson: Using Code Access Security in
Module 10, “Securing Windows Forms
• Use of Web access for the Expense Report Applications,” in Course 2555A, Developing
Web service. Use the following syntax: Microsoft .NET Applications for Windows
[assembly:WebPermission( (Visual C# .NET). This lesson contains
SecurityAction.RequestMinimum, information about how to make permission
Connect = requests.
"http://localhost/ExpenseReportWeb • The .NET Framework SDK documentation.
Service/ In Search, select the Search in titles only
ExpenseReportWebService.asmx")] check box, then search by using the phrase
• Add an optional permission request for no Requesting Permissions.
permissions.
Module 10: Securing Windows Forms Applications 45
3. Test the permission requests. a. In step 3.c., the application will not run because
a. Build and run the application in Visual Studio the LocalIntranet permission set limits Web
to make sure it still works. access to the same site that the assembly was
downloaded from. If the application were
b. Copy the ExpenseReport.exe file from the installed on localhost, it would run in the
bin(\debug) folder of the project to the LocalIntranet permission set.
C:\Test\LocalIntranet folder.
b. For more information about the default security
c. Double-click the application and attempt to policy, see the following resources:
run it. Notice that you get a policy exception.
• Lesson: Using Code Access Security in
Module 10, “Securing Windows Forms
Applications,” in Course 2555A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET). This lesson contains
information about configuring the security
policy.
• The .NET Framework SDK documentation.
In Search, select the Search in titles only
check box, then search by using the phrase
Default Security Policy.
46 Module 10: Securing Windows Forms Applications
Course Evaluation
Overview 1
Lesson: Creating Brushes and Filled Shapes 2
Lesson: Working with Bitmap Images 14
Information in this document, including URL and other Internet Web site references, is subject to
change without notice. Unless otherwise noted, the example companies, organizations, products,
domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious,
and no association with any real company, organization, product, domain name, e-mail address,
logo, person, place or event is intended or should be inferred. Complying with all applicable
copyright laws is the responsibility of the user. Without limiting the rights under copyright, no
part of this document may be reproduced, stored in or introduced into a retrieval system, or
transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual
property rights covering subject matter in this document. Except as expressly provided in any
written license agreement from Microsoft, the furnishing of this document does not give you any
license to these patents, trademarks, copyrights, or other intellectual property.
The names of actual companies and products mentioned herein may be the trademarks of their
respective owners.
Appendix A: Using Filled Shapes and Images iii
Instructor Notes
Presentation: This appendix provides students with an overview of how to create filled shapes
60 minutes and images by using GDI+. Students learn how to use solid, hatch, texture,
linear gradient, path gradient, and transparent brushes to fill shapes. They will
Lab: also learn how to load, skew, rotate, reflect, crop, and scale images.
00 minutes
After completing this module, students will be able to:
Create and use textured, hatched, and gradient brushes to fill shapes.
Manipulate bitmap images and use them in a Windows Forms application.
Required materials To teach this appendix, you need the Microsoft® PowerPoint® file
2555A_XA.ppt.
Preparation tasks To prepare for this module:
Read all of the materials for this appendix.
Complete the practices.
iv Appendix A: Using Filled Shapes and Images
Overview
Solid
Solid Brush
Brush Texture
Texture Brush
Brush
Hatch
Hatch Brush
Brush
Gradient
Gradient Brush
Brush Path
Path Gradient
Gradient
Brush
Brush
CodeExample
CodeExample
Procedure: How to The following example fills an ellipse with an image. The code constructs an
create a texture filled Image object, and then passes the address of that Image object as an argument
shape to a TextureBrush constructor. The final statement fills the ellipse with
repeated copies of the image.
imageFileName = "C:\Images\Image01.jpg";
Image brushImage = new Bitmap(imageFileName);
TextureBrush myImageBrush = new TextureBrush(brushImage);
e.Graphics.FillEllipse(myImageBrush, 0, 0, 135, 55);
Note You can also use a brush to draw lines by constructing a pen based on the
brush rather than a solid color. For more information about using a brush as the
source of a line color, see “Drawing a Line Filled with a Texture” in the .NET
Framework SDK documentation.
Appendix A: Using Filled Shapes and Images 5
CodeExample
The hatch style argument can be any of the more than 50 values from the
HatchStyle enumeration, such as Cross, Horizontal, OutlinedDiamond,
Sphere, Vertical, and ZigZag.
The following example demonstrates how to fill an ellipse with a horizontal line
hatch pattern of red on a cyan background:
Imports System.Drawing.Drawing2D
…
HatchBrush myHatchBrush = new
HatchBrush(HatchStyle.Horizontal, Color.Red, Color.Cyan);
e.Graphics.DrawString(myText,
e.Graphics.DrawString(myText, myFont,
myFont, myBrush,
myBrush, hPos,
hPos,
vPos);
vPos);
Procedure: How to The following example draws a string (myText) by using a linear gradient
create a horizontal linear brush. The size of the brush is determined by a rectangle, which is constructed
gradient to be the same size as the string when it is drawn on the graphics object.
Rectangle rect = new Rectangle(hPos, vPos, txtWidth,
txtHeight);
LinearGradientBrush lgBrush = new LinearGradientBrush(rect,
Color.SeaGreen, Color.BlueViolet,
LinearGradientMode.Horizontal);
e.Graphics.DrawString(myText, myFont, myBrush, hPos, vPos);
Note If the object being drawn with a linear gradient brush extends beyond the
size of the brush, the color gradient repeats itself until the entire object is filled.
8 Appendix A: Using Filled Shapes and Images
CodeExample
e.Graphics.FillPath(pgBrush, pathShape1);
By default, a path gradient brush does not extend outside the boundary of the
path. If you use the path gradient brush to fill a figure that extends beyond the
boundary of the path, the area of the object that is outside the path is not filled.
For more information about customizing a PathGradientBrush, see “Creating a
Path Gradient” in the .NET Framework SDK documentation.
Procedure: How to set By default, the center point of a path gradient brush is at the centroid of the path
the center point used to construct the brush. You can change the location of the center point by
setting the CenterPoint property of the PathGradientBrush class.
Appendix A: Using Filled Shapes and Images 9
The following example creates a path gradient brush based on an ellipse. The
center of the ellipse is at (70, 35), but the center point of the path gradient brush
is set to (120, 40).
// Create a path that consists of a single ellipse.
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, 0, 140, 70);
CodeExample
The following example draws two ellipses on a textured background. The first
ellipse uses an alpha component of 255, so it is opaque. The second ellipse uses
an alpha component of 128, so it is semitransparent. Background images can be
seen through a semitransparent shape.
Customize brushes
1. In the Task List, double-click TODO: customize the linear gradient
brush.
2. Modify the code statement that uses the SetBlendTriangularShape method
by changing the value passed to the method from 0.0 to 0.5.
3. In the Task List, double-click TODO: enable customizations to the path
gradient brush.
4. Enable the code statement that follows the TODO line.
5. On the Debug menu, click Start.
6. Click Show Splash Screen.
Examine the change to the splash screen form. If necessary, change the code
statements back to their original state, run the application again to see the
appearance of the “Purchase Order Application” text and “star-shaped path”
before the changes were made, and then reintroduce the changes made in
steps 2 and 4 above.
7. Close the splash screen form, and then close the splash screen application.
8. If time permits, experiment with the code used to set the alpha value
(transparency) for the path gradient brushes. You can find the appropriate
code section by double-clicking TODO: modify transparency settings for
path gradient brushes in the Task list.
14 Appendix A: Using Filled Shapes and Images
Bitmap
A bitmap is an array of bits that specify the color of
each pixel in a rectangular array of pixels
Graphic File Formats
Used for saving bitmaps in disk files
Types of Graphic File Formats
BMP, GIF, JPEG, EXIF, PNG, TIFF
CodeExample
CodeExample
Procedure One of the DrawImage methods receives a Bitmap object and uses a
Rectangle object to specify the size of the drawn image. The rectangle specifies
the destination for the drawing operation; that is, it specifies the rectangle in
which to draw the image. If the size of the destination rectangle is different
from the size of the original image, the image is scaled to fit the destination
rectangle. The following example draws an image full scale and then draws the
image with scaled coordinates.
// draw the original image
e.Graphics.DrawImage(fileImage, 0, 0);
CodeExample
Procedure The following code demonstrates how to create the point arrays that can be used
to rotate, skew, and reflect an image.
// create a set of points that can be used to
// draw a version of the original image
// that is rotated 90 degrees counter-clockwise
//
// upper-left becomes lower-left
// upper-right becomes upper-left
// lower-left becomes lower-right
Point[] rotatedCoordinates = {
new Point(leftImage, topImage + heightImage + widthImage),
new Point(leftImage, topImage + heightImage),
new Point(leftImage + heightImage,
topImage + heightImage + widthImage)
};
e.Graphics.DrawImage(fileImage, rotatedCoordinates);
e.Graphics.DrawImage(fileImage, skewedCoordinates);
e.Graphics.DrawImage(fileImage, reflectedCoordinates);
22 Appendix A: Using Filled Shapes and Images
Dim
Dim image
image == New
New Bitmap("Compass.bmp")
Bitmap("Compass.bmp")
Dim
Dim pThumbnail
pThumbnail AsAs Image
Image ==
image.GetThumbnailImage(100,
image.GetThumbnailImage(100, 100,
100, Nothing,
Nothing, __
New
New IntPtr())
IntPtr())
e.Graphics.DrawImage(
e.Graphics.DrawImage( __
pThumbnail,
pThumbnail, __
10,
10, __
10,
10, __
pThumbnail.Width,
pThumbnail.Width, __
pThumbnail.Height)
pThumbnail.Height)