Developing Microsoft .NET Applications for Windows (Visual Basic .NET)
Developing Microsoft .NET Applications for Windows (Visual Basic .NET)
NET ®
Delivery Guide
Course Number: 2565A
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
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
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 ..................................................................42
Lesson: Creating Menus ........................................................................................48
Lesson: Validating User Input ...............................................................................58
Review ...................................................................................................................66
Lab 2.1: Working with Controls ............................................................................68
Module 3: Building Controls
Overview..................................................................................................................1
Lesson: Extending and Creating Controls................................................................2
Lesson: Adding Design-Time Support for Controls ..............................................18
Lesson: Licensing a Control ..................................................................................26
Review ...................................................................................................................37
Lab 3.1: Building Controls ....................................................................................39
iv Developing Microsoft® .NET Applications for Windows® (Visual Basic® .NET)
Student prerequisites This course requires that students meet the following prerequisites:
! Experience with a .NET Framework language such as Visual Basic .NET
Microsoft MSDN® Training Course 2559A: Introduction to Visual Basic
.NET Programming with Microsoft .NET will help students gain basic skills
in Visual Basic .NET programming techniques and meet the prerequisites
for this course.
! Experience developing applications with Visual Basic 6
viii Developing Microsoft® .NET Applications for Windows® (Visual Basic® .NET)
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 dialogs 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.
! Consume XML Web services from Windows Forms applications.
! Use .NET and COM components in a Windows Forms application.
! Call Microsoft Win32® APIs from a Windows Forms application.
! Upgrade Visual Basic 6.0 applications to Visual Basic .NET.
! Print documents in a Windows Forms application.
! Make asynchronous calls to methods from a Windows Forms application.
! Debug a Windows Forms application.
! Incorporate accessibility features in a Windows Forms application.
! Localize a Windows Forms application.
! Add support for help to localize a Windows Forms application.
! Create help files in a Windows Forms application.
! Deploy a Windows Forms application.
! Implement code access and role-based security in a Windows Forms
application.
! Add deployment flexibility to applications by using shared assemblies.
Developing Microsoft® .NET Applications for Windows® (Visual Basic® .NET) ix
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 Basic® .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 Basic® .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, places or events 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 2565A, Developing Microsoft .NET
Applications for Windows® (Visual Basic® .NET).
Required materials To teach this course, you need the following materials:
! Delivery Guide
! Trainer Materials compact disc
Demonstration: It is very important that you go through this demonstration before teaching the
Purchase Order rest of the course. The Purchase Order application is one of two primary
Application scenarios for practices and labs throughout the course. Demonstrating the
Purchase Order application is also a good way to introduce students to the skills
that they will acquire in the course. If a student arrives after you have done the
demonstration, have the student review the steps for this demonstration before
doing any of the labs.
Microsoft Certified Inform students about the Microsoft Certified Professional (MCP) program and
Professional program the various certification options.
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 Basic 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\2565. However, if you install to a
different location, you must reset the assembly references in the starter and
solution projects.
Prerequisites
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 Microsoft PowerPoint® file 2565A_01.ppt.
Preparation tasks To prepare for this module:
! Read all of the materials for this module.
! Complete the demonstration, practices, and lab.
iv Module 1: Introducing Windows Forms
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
Form
Form Name
Name
Categorized
Categorized Button
Button
Alphabetic
Alphabetic Button
Button
Description
Description Pane
Pane
Common form The following table describes some common form properties that you typically
properties set at design time.
Property Description Default setting
(Name) Sets the name of the form in your project. (This is not the name Form1 (Form2, Form3,
that is displayed to the user in the caption bar but rather the and so on)
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 up correctly. For more 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 the user presses the ENTER None
key.
Note: You must have at least one button on your form to use
this property.
CancelButton Sets which button is clicked when the user presses the ESC key. None
Note: you must have at least one button on your form to use this
property.
ControlBox Determines whether a form displays a control box in the caption True
bar. The control box can contain the Minimize button,
Maximize button, Help button, and the Close button.
FormBorderStyle Controls the appearance of the border for the form. This will Sizable
also affect how the caption bar appears and what buttons appear
on it.
8 Module 1: Introducing Windows Forms
(continued)
Property Description Default setting
MaximizeBox Determines whether a form has a Maximize button in the upper True
right corner of its caption bar.
MinimizeBox Determines whether a form has a Minimize button in the upper True
right corner of its caption bar.
StartPosition Determines the position of a form on the screen when it first WindowsDefaultLocation
appears.
Text Sets the text displayed in the caption bar of the control. Form1 (Form2, Form3,
and so on)
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.
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 earlier versions of Visual Basic, the Initialize event was used to execute
code before a form was loaded. In .NET, initialization code must be added to
the form constructor (Sub New()) after the call to InitializeComponent() as
shown in the following example:
Public Sub New()
MyBase.New()
' This call is required by the Windows Forms Designer.
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()
Deactivate fires when the form loses focus to another form. This event fires
after the LostFocus event.
Module 1: Introducing Windows Forms 11
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 MyBase.Dispose().
Public Overrides Sub Dispose(ByVal Disposing As Boolean)
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
3. Click the drop-down arrow for the Method Name list box to view events
available for the form. The following illustration shows the Method Name
list box with form events listed and the Click event selected. Notice that the
Event icon to the left of the event name indicates that it is an event.
You will learn more about using events and event handlers in the .NET
Framework in Module 2, “Working with Controls” in Course 2565A,
Developing Microsoft .NET Applications for Windows (Visual Basic .NET).
14 Module 1: Introducing Windows Forms
Designer-generate code If you look at the default code for the form, you will find the following code
generated by the Designer.
#Region " Windows Form Designer generated code "
End Sub
End Sub
#End Region
16 Module 1: Introducing Windows Forms
Right-click the
Toolbox
Click Customize
Toolbox
Note The Customize Toolbox dialog box replaces the Components dialog
box in previous versions of Visual Basic.
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
7. Double-click the Say Hello button to create the Click event handler.
Module 1: Introducing Windows Forms 25
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:
Me.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
child form,
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.
Visual Basic .NET supports two other values, Friend and Protected Friend.
Module 1: Introducing Windows Forms 29
Public
Public Class
Class Form2
Form2
Inherits
Inherits Namespace1.Form1
Namespace1.Form1
*****************************ILLEGAL FOR NON-TRAINER USE******************************
Introduction Visual Inheritance offers many advantages to developers. If you already have
designed a form for a different project that is similar to the one you need in the
current project, you can inherit from the earlier form. It also means that you can
create a base form as a template to use later. It is a useful way of duplicating the
main functionality of particular forms without having to recreate them from the
beginning. Changes to the base form will be reflected in those forms that are
inherited from it; so changes to the underlying template form will change all
forms based on it.
Procedure: Inheriting There are two ways of implementing Visual Inheritance in a
from an existing form Visual Studio .NET project.
To create an inherited form programmatically:
1. Create a new project in Visual Studio .NET.
2. Add another form, or view the code of Form1, which is created by default.
3. In the class definition, add a reference to the form to inherit from. The
reference should include the namespace that contains the form, followed by
a period, and then the name of the base form itself.
Public Class Form2
Inherits Namespace1.Form1
The form now takes on the characteristics of the inherited form. It contains
the controls that were on the inherited form, the code, and the properties.
30 Module 1: Introducing Windows Forms
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.
Module 1: Introducing Windows Forms 31
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.
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
Align Aligns all the controls with respect to the primary control
Make Same Size Resizes multiple controls on a form
Horizontal Spacing Increases horizontal spacing between controls
Vertical Spacing Increases vertical spacing between controls
Center in Form Centers the controls on a form
Order Layers controls on a form
Lock Controls Locks all controls on a form
Module 1: Introducing Windows Forms 37
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 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 Sub
Sub MenuItem2_OnClick(ByVal
MenuItem2_OnClick(ByVal sender
sender As
As System.Object,
System.Object, ByVal
ByVal
ee As
As System.EventArgs)
System.EventArgs) Handles
Handles MenuItem2.Click
MenuItem2.Click
Dim
Dim NewMdiChild
NewMdiChild As
As New
New Form2()
Form2()
'Set
'Set the
the Parent
Parent Form
Form of
of the
the Child
Child window.
window.
NewMdiChild.MdiParent
NewMdiChild.MdiParent == MeMe
'Display
'Display the
the new
new form.
form.
NewMdiChild.Show()
NewMdiChild.Show()
End
End Sub
Sub
*****************************ILLEGAL FOR NON-TRAINER USE******************************
Introduction There are three main steps involved in creating an MDI application: creating a
parent form, creating a child form, and calling the child form from a parent
form.
Procedure: Creating MDI To create the parent form at design time:
applications
The Parent form in an MDI application is the form that contains the MDI child
windows. Child windows are used for interacting with users in an MDI
application.
1. Create a new project.
2. In the Properties window, set the IsMdiContainer property to True.
This designates the form as an MDI container for child windows.
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.
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.
Dim activeChild As Form = Me.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
ArrangeIcons All MDI child icons are arranged in the client region of the MDI
parent form.
Cascade All MDI child windows are cascaded in the client region of the
MDI parent form.
TileHorizontal All MDI child windows are tiled horizontally in the client region
of the MDI parent form.
TileVertical All MDI child windows are tiled vertically in the client region of
the MDI parent form.
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 Then
ToggleMenuItem.Checked = False
ChildTextBox.ForeColor = System.Drawing.Color.Black
Else
ToggleMenuItem.Checked = True
ChildTextBox.ForeColor = System.Drawing.Color.Blue
End If
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\2565.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to the and starting an application, see the following
install_folder\Labfiles\Lab01_1\ resource:
Ex01\Starter to find this project. • The Visual Studio .NET Help documentation.
Note: The project will not build until you For additional information about opening a
complete 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.vb. • Practice: Creating a Form in Module 1,
“Introducing Windows Forms,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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
ControlBox False Course 2565A, Developing Microsoft .NET
FormBorderStyle Fixed3D Applications for Windows (Visual Basic
MaximizeBox False .NET). This practice contains information
MinimizeBox False about how to set form properties.
Size 322, 210 • Lesson: Creating a Form in Module 1,
Text Internal Business “Introducing Windows Forms,” in
Application Logon Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• The Windows Forms section of the
.NET Framework SDK.
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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: Creating a Form, in Module 1,
“Introducing Windows Forms,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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
Location 64, 31 Course 2565A, Developing Microsoft .NET
Size 63, 14 Applications for Windows (Visual Basic
Text Username .NET). This practice contains information
about how to set control properties.
Label2 Property Value
• Lesson: Creating a Form, in Module 1,
(Name) PasswordLabel “Introducing Windows Forms,” in
Location 64, 71 Course 2565A, Developing Microsoft .NET
Size 64, 14 Applications for Windows (Visual Basic
Text Password .NET).
Textbox1 Property Value • The Windows Forms section of the
(Name) UserNameTextBox .NET Framework SDK.
Location 128, 29
Size 120, 20
Text (Delete existing text
and leave it blank)
Textbox2 Property Value
(Name) PasswordTextBox
Location 128, 64
PasswordChart *
Size 120, 20
Text
Button1 Property Value
(Name) LogonButton
Location 67, 116
Size 75, 30
Text &Log On
Button2 Property Value
(Name) CancelAppButton
Location 171, 116
Size 75, 30
Text &Cancel
58 Module 1: Introducing Windows Forms
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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: Creating a Form, in Module 1,
“Introducing Windows Forms,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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\2565.
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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: Creating an Inherited Form, in
Module 1, “Introducing Windows Forms,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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
Modifier Module 1, “Introducing Windows Forms,” in
Control Property Value Course 2565A, Developing Microsoft .NET
ProductNameLabel protected Applications for Windows (Visual Basic
VersionNumber protected .NET).
CopyrightLabel protected • Lesson: Creating an Inherited Form, in
AllRightsReservedLabel protected Module 1, “Introducing Windows Forms,” in
AboutOkButton protected Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: Creating an Inherited Form, in
Module 1, “Introducing Windows Forms,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• The Windows Forms section of the
.NET Framework SDK.
62 Module 1: Introducing Windows Forms
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 2565A, Developing Microsoft .NET
Text About Internal Applications for Windows (Visual Basic
Business Application .NET). 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
Control Property Value Course 2565A, Developing Microsoft .NET
ProductNameLabel.Text Internal Business Applications for Windows (Visual Basic
Application .NET). This lesson contains information about
VersionNumber.Text Version 1.0.3153 how to work with inherited forms.
CopyrightLabel.Text Copyright © 2002 • The Windows Forms section of the
Contoso, Ltd. .NET Framework SDK.
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 resource:
• The Windows Forms section of the
.NET Framework SDK.
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 42
Lesson: Creating Menus 48
Lesson: Validating User Input 58
Review 66
Lab 2.1: Working with Controls 68
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 2565A_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
Button1
Private Sub
Button1_Click(ByVal Sender As
System.Object, ByVal e As
Invokes the System.EventArgs) Handles
delegate Button1.Click
Delegate
Delegate calls the
associated procedure
! Event Handlers
" Methods bound to an event
" When the event is raised, the code within the event
handler is executed
! Two Event Arguments with Event Handlers
" An object representing the object that raised the event
" An event object containing any event-specific
information
Private
Private Sub
Sub Button1_Click
Button1_Click (ByVal
(ByVal Sender
Sender As
As
System.Object,
System.Object, ByVal
ByVal ee As
As System.EventArgs)
System.EventArgs)
Example of event The following code example is an event handler for the Click event of a button.
handler
Private Sub Button1_Click(ByVal Sender As System.Object, ByVal
e As System.EventArgs) Handles Button1.Click
The following code example shows how you can use a single event handler to
handle events for multiple controls.
Private Sub MyHandler(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles RadioButton1.Click,
RadioButton2.Click, RadioButton3.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.
6 Module 2: Working with Controls
Handles Keyword
! Parts
" ProcedureDeclaration " Events
Routine
Routine can
can use
use Argument
Argument list list must
must match
match the
the
any
any name
name usual
usual list
list for
for the
the particular
particular event
event
Public
Public Sub
Sub Age
Age (ByVal
(ByVal Sender
Sender As
As System.Object,
System.Object,
ByVal
ByVal ee As
As System.EventArgs)
System.EventArgs)
Handles
Handles Under21.Click,
Under21.Click, Twenties.Click,
Twenties.Click,
Thirties.Click,
Thirties.Click,
Forties.Click,
Forties.Click, FiftiesPlus.click
FiftiesPlus.click
Handles
Handles keyword
keyword List
List of
of events
events that
that this
this routine
routine will
will handle
handle
! Proceduredeclaration
Proceduredeclaration is the Sub procedure declaration for the procedure
that will handle the event.
! Event
Event is the name of the event being handled. This event must be raised by
either the base class for the current class or by an object declared by using
the WithEvents keyword.
Module 2: Working with Controls 7
Friend
Friend WithEvents
WithEvents Button1
Button1 As
As System.Windows.Forms.Button
System.Windows.Forms.Button
Private
Private Sub
Sub Button1_Click(ByVal
Button1_Click(ByVal sender
sender As
As System.Object,
System.Object,
ByVal
ByVal ee As
As System.EventArgs)
System.EventArgs) Handles
Handles Button1.Click
Button1.Click
MessageBox.Show("MyHandler
MessageBox.Show("MyHandler captured
captured the
the event")
event")
End
End Sub
Sub
End Sub
8 Module 2: Working with Controls
AddHandler
AddHandler Button3.Click,
Button3.Click, AddressOf
AddressOf Process1
Process1
The
The event
event that
that you
you The
The routine
routine that
that you
you want
want
want
want to
to handle
handle to
to use
use to
to handle
handle the
the event
event
RemoveHandler
RemoveHandler Button3.Click,
Button3.Click, AddressOf
AddressOf
Process1
Process1
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 that 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
Procedure: Using the The .NET Framework offers the StatusBar control for the status bar. You can
StatusBar control create panels in the status bar by using the Add method of the Panels
collection. To display the panels, you must set the ShowPanels property to
True. You can indicate the size and alignment of each panel by setting
additional properties.
To create a status bar with panels:
1. Add a StatusBar control to the form.
2. In the Properties window, click the Panels property to select it. Then click
the ellipsis (…) button to open the StatusBarPanel Collection Editor.
3. Use the Add and Remove buttons to add and remove panels from the
StatusBar control at design time. You can use the Add and Remove
methods of the StatusBarPanels object to add and remove panels at run
time.
4. Configure the properties of the individual panels in the Properties window.
The following table lists the important properties and their descriptions.
Property Description
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
MultiColumn When set to True, the list box displays items in multiple
columns and a horizontal scroll bar appears. When set to
False, the list box displays items in a single column and a
vertical scroll bar appears.
ScrollAlwaysVisible When set to True, the scroll bar appears regardless of the
number of items.
SelectionMode Determines how many list items can be selected at a time.
SelectedIndex Returns an integer value that corresponds to the first
selected item in the list box. If no item is selected, the
SelectedIndex value is -1. If the first item in the list is
selected, then the SelectedIndex value is 0.
Items.Count Reflects the number of items in the list.
Items.Add/Items.Insert Adds items to the ListBox control.
Items.Remove/Items.Clear Removes items from the ListBox control.
DataSource Binds the ListBox to a data source.
DisplayMember Binds the ListBox to a name of the column in the Data
source.
Module 2: Working with Controls 19
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.
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. 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.
Module 2: Working with Controls 25
Procedure: Triggering If your Windows Forms application features a ToolBar control with buttons,
events for 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.
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.
Case "Copy"
Me.copyRadioButton.Checked = True
Me.StatusBar1.Panels(0).Text = _
Me.copyRadioButton.Text & _
" Radio Button is checked"
End Select
End Sub
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.
____________________________________________________________
____________________________________________________________
End Select
Me.StatusBar1.Panels(0).Text = panelText
MessageBox.Show("The " & e.Button.Tag & _
" button is index number " & _
ToolBar1.Buttons.IndexOf(e.Button))
5. On the View menu, point to Show Tasks, and then click Comment.
6. In the Task List, double-click TODO: paste inside Select Case.
7. Use a cut-and-paste operation to move the commented code inside the
Select Case structure that you just created, and then uncomment the code
statements.
Module 2: Working with Controls 29
8. What are some of the reasons for using the Tag property to determine which
ToolBar button was clicked?
You don’t have to update code when the button order changes and you
don’t have to consider button separators.
____________________________________________________________
____________________________________________________________
9. 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.
10. If time permits, examine the code used to construct the StatusBar control.
11. 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
page details
details for
for printing
printing
Displays
Displays a document as it would appear when it is
PrintPreviewDialog
PrintPreviewDialog
printed
printed
FontDialog The Windows Forms FontDialog control is the standard Windows Font dialog
box used to expose the fonts that are currently installed on the system. By
default, the dialog box includes options for Font, Font style, and Size. It also
includes check boxes for effects like Strikeout and Underline, and a drop-down
list for Script.
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.
Private Sub PerformSearch()
MessageBox.Show("The search is now complete", _ "My
Application", MessageBoxButtons.OKCancel, _
MessageBoxIcon.Asterisk)
End Sub
38 Module 2: Working with Controls
DialogResult Property
DialogResult Property
Example
Example
In the code window, navigate to the event handler or the method for
which you want to set the DialogResult property
Dim
Dim userResponse
userResponse As
As DialogResult
DialogResult ==
OpenFileDialog1.ShowDialog()
OpenFileDialog1.ShowDialog()
If
If userResponse
userResponse == DialogResult.OK
DialogResult.OK Then
Then
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,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1)
MessageBoxDefaultButton.Button1)
____________________________________________________________
Module 2: Working with Controls 41
Else
MessageBox.Show("You canceled the operation.", _
"Warning", _
MessageBoxButtons.OK, _
MessageBoxIcon.Warning, _
MessageBoxDefaultButton.Button1, _
MessageBoxOptions.RightAlign)
End If
9. Run the application, and then click Use the OpenFileDialog Control.
10. Click Cancel, and then close the application.
____________________________________________________________
____________________________________________________________
! 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)
Loop
5. Run the application, click Use International Policies, and then click Use
Domestic Policies.
6. Close the application.
46 Module 2: Working with Controls
____________________________________________________________
9. If time permits, open Form1.vb 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.
48 Module 2: Working with Controls
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.
Module 2: Working with Controls 49
Within the method, set the Text property for each menu item
MenuItemNew.Text
MenuItemNew.Text == "New"
"New"
Note You can also add images to menu items. To add images to menu items,
create an instance of the MenuItem class, override the OnPaint() method, and
draw the image next to the menu item text.
Module 2: Working with Controls 51
Procedure: Creating Shortcut keys provide a method for users to activate frequently used menu
shortcut keys items in the menu system and to provide keyboard access to the application.
For example, in Microsoft Word, you can open a file by using the Ctrl+O
shortcut or save a file by pressing Ctrl+S.
To create a shortcut for menu items:
1. Select the menu item for which you need to create a shortcut.
2. In the Properties dialog box, select the Shortcut property.
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.
To display checked menu items:
1. Select the menu item.
2. In the Properties dialog box, set the Checked property to True.
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.
Module 2: Working with Controls 55
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.
60 Module 2: Working with Controls
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.
62 Module 2: Working with Controls
CodeExample
End If
5. Run the application, press a letter key on the keyboard, and then click OK.
6. Close the application.
7. What happens if you don’t include the code statement that sets the value of
the Handled property to True?
The character representing the key that was pressed will be added to
the text box.
____________________________________________________________
____________________________________________________________
64 Module 2: Working with Controls
! 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. What methods do you use to add and remove event handlers at run time?
AddHandler and RemoveHandler are used to add and remove handlers
from an event handler.
3. 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).
5. 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 2565A, Developing Microsoft .NET Applications for Windows
(Visual Basic .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\2565.
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()
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.
72 Module 2: Working with Controls
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 in 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.vb. Configure the • Lesson, Using Windows Forms Controls, in Module 2, “Working
Toolbar as specified in the with Controls,” in Course 2565A, Developing Microsoft .NET
scenario. Applications for Windows (Visual Basic .NET).
• Practice, Creating and Using a ToolBar Control, in Module 2,
“Working with Controls,” in Course 2565A, Developing
Microsoft .NET Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
event handler for the Applications for Windows (Visual Basic .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 2565A, Developing
action when a ToolBar Microsoft .NET Applications for Windows (Visual Basic .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.
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 2565A, Developing Microsoft .NET
over the ToolBar buttons to Applications for Windows (Visual Basic .NET).
display ToolTips and click
the buttons to make sure that
your ButtonClick event
handler is working correctly.
Module 2: Working with Controls 73
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 2565A, Developing Microsoft .NET Applications for
the Windows (Visual Basic .NET).
PurchaseOrder.OrderItem
Control control named • Practice, Updating Menus at Run Time, in Module 2, “Working
tempProductOrder that with Controls,” in Course 2565A, Developing Microsoft .NET
uses ProductContextMenu Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
then add the new purchase Applications for Windows (Visual Basic .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 2565A, Developing
control. Microsoft .NET Applications for Windows (Visual Basic .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 creating event handlers, see the following
the code section 'TODO: resources:
handle the click event for • Lesson, Creating an Event Handler for a Control, in Module 2,
the “Working With Controls,” in Course 2565A, Developing
DeleteOrderItemMenuItem', Microsoft .NET Applications for Windows (Visual Basic .NET).
and then create an event
handler for the Click event • Practice, Creating and Event Handler for a Control, in Module 2,
of the “Working With Controls,” in Course 2565A, Developing
DeleteOrderItemMenuIte Microsoft .NET Applications for Windows (Visual Basic .NET).
m menu item that calls the • The Visual Studio .NET Help documentation. Search by using the
DeleteOrderItem() phrase Consuming Events.
procedure.
8. 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 2565A, Developing Microsoft .NET Applications for
deleted', and then assign the Windows (Visual Basic .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 2565A, Developing Microsoft .NET
currentControlIndex. Applications for Windows (Visual Basic .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase ContextMenu.SourceControl.
74 Module 2: Working with Controls
9. 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 2565A, Developing Microsoft .NET
ProductOrderPanel control Applications for Windows (Visual Basic .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 2565A, Developing
ProductOrderPanel control Microsoft .NET Applications for Windows (Visual Basic .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.
10. 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.
11. Save your changes, and then Additional information is not necessary for this task.
close Visual Studio .NET.
Module 3: Building
Controls
Contents
Overview 1
Lesson: Extending and Creating Controls 2
Lesson: Adding Design-Time Support for
Controls 18
Lesson: Licensing a Control 26
Review 37
Lab 3.1: Building Controls 39
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 2565A_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
! Composite controls
" Controls that are composed of other controls
" Designed to act as containers for other controls
! Custom controls
CodeExample
Example of extending a Some examples of extended controls include a text box that can accept only
control numeric values or a button that has some additional properties, such as a
property that can record how many times the button has been clicked.
The following code shows a numeric text box that is inherited from the
Windows TextBox control. It also shows how the OnKeyPress event of the
base TextBox class is overridden to provide custom functionality.
Public Class NumericTextBox
Inherits System.Windows.Forms.TextBox
End Sub
End Class
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.
Private MyNumericControl as New NumericTextBox()
MyNumericControl.Clear()
Composite controls 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.
Module 3: Building Controls 5
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 NewControl
Inherits Control
…
End Class
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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic® .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.
Example of a Custom Imports System
control Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Drawing
End Class
6 Module 3: Building Controls
Public
Public Property
Property QuantityTextBoxContextMenu()
QuantityTextBoxContextMenu() As
As
ContextMenu
ContextMenu
Get
Get
Return
Return txtQuantity.ContextMenu
txtQuantity.ContextMenu
End
End Get
Get
Set(ByVal
Set(ByVal Value
Value As
As ContextMenu)
ContextMenu)
txtQuantity.ContextMenu
txtQuantity.ContextMenu == Value
Value
End
End Set
Set
End
End Property
Property
! Overriding properties
CodeExample
The following code example shows how to expose the ContextMenu property
of a control contained in a composite control.
Public Property QuantityTextBoxContextMenu() As ContextMenu
Get
Return txtQuantity.ContextMenu
End Get
Set(ByVal Value As ContextMenu)
txtQuantity.ContextMenu = Value
End Set
End Property
The Get and Set methods are generally not different from other methods. They
can perform any program logic, throw exceptions, be overridden, and can be
declared with any modifiers allowed by the programming language. You can
make a property read-only or write-only by using the ReadOnly and
WriteOnly key words and only using a Get or Set accessor respectively. The
following code is an example of a ReadOnly property.
Public ReadOnly Property MyProperty() As String
Get
…
End Get
End Property
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
Inherits System.Windows.Forms.TextBox
! To override events
Public
Public Class
Class FirstControl
FirstControl
Inherits
Inherits Control
Control
……
Protected
Protected Overrides
Overrides Sub
Sub OnPaint(e
OnPaint(e As
As
PaintEventArgs)
PaintEventArgs)
You can then make the host application aware of the control event by
delegating a procedure to the event. You use the same Handles or AddHandler
keywords to handle a custom event that you use with the intrinsic controls.
Module 3: Building Controls 9
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
pointer.
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 (Me) along with the
KeyPressEventArgs passed to the event.
Protected Overrides Sub OnKeyPress(ByVal e As _
System.Windows.Forms.KeyPressEventArgs)
Dim asciiInteger As Integer = Asc(e.KeyChar)
Select Case asciiInteger
Case 47 To 57
e.Handled = False
'If the value represents BACKSPACE
Case 8
e.Handled = False
'If the value is anything else
Case Else
e.Handled = True
RaiseEvent InvalidUserEntry(Me, e)
End Select
End Sub
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.
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.
18 Module 3: Building Controls
! Property Attributes
! How to Add Attributes That Provide Information to the
Visual Designer
! Design-Time Support Options Built into the .NET
Framework
! Practice: Adding Design-Time Support for Controls
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
List of property The following table lists some of the property attributes and their descriptions.
attributes
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.
Module 3: Building Controls 21
Imports
Imports 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 require no 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.
24 Module 3: Building Controls
! Files in Licensing
! How to Enable Licensing for a Control
! Demonstration: Creating and Validating a License for
a Control
! How LicFileLicenseProvider Works in .NET
Components of the Licensing is built into the .NET Framework, and developers use classes built
licensing model into the System.ComponentModel namespace to provide custom licensing
solutions. There are two components of the licensing model the
LicenseManager and the LicenseProvider.
! The LicenseManager class is responsible for validating licensed controls at
both run time and design time. The LicenseManager class is part of the
runtime, and when a class is instantiated, LicenseManager uses the proper
validation mechanism for the control or component.
! The LicenseProvider class is the place to put custom validation code. You
can create unique licensing by extending the
System.ComponentModel.LicenseProvider class. By extending this class,
you can create unique licensing models. For example, you can create the
license for a control once and allow it to be reused as many times as
necessary, or you could create a licensing mechanism that expires after a
certain period of time.
Visual Studio .NET ships with the LicFileLicenseProvider, which is
derived from the System.ComponentModel.LicenseProvider object. The
LicFileLicenseProvider is built for demonstration purposes and is not
intended for production licensing behavior. You can build more advanced
licensing scenarios by building additional classes that derive from
System.ComponentModel.LicenseProvider.
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.
28 Module 3: Building Controls
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
Currently you have to manually add this text file to the assembly folder with
this correct format and the .LIC extension.
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.
Module 3: Building Controls 29
! .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"
InitializeComponent()
'Call the Validate method to validate
'the current instance of the LicensedClass
myLicense = LicenseManager.Validate_
(GetType(LicensedControl), Me)
'or call the IsValid method of the _
LicensedClass control
'to determine if a valid license exists
IsValid = LicenseManager.IsValid_
(GetType(LicensedControl))
End Sub
MyBase.Dispose(disposing)
End Sub
Module 3: Building Controls 33
<ToolBoxBitmap(GetType(NumericTextBox), _
"NumericTextBox.ico"), _
LicenseProvider(GetType(LicFileLicenseProvider))> _
Public Class NumericTextBox
34 Module 3: Building Controls
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
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
Module 3: Building Controls 41
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\2565.
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 install_folder\ Search in titles only check box, then search by using the phrase
Labfiles\Lab03_1\Ex01\ Open Project Dialog Box.
Starter\NumerictextBox.
2. Use the Task List in the a. For more information about creating extended controls and why you
NumericTextBox.vb 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 2565A, Developing Microsoft .NET
Inherits statement so that the Applications for Windows (Visual Basic .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 Basics.
3. Use the Task List in the a. For more information declaring an event, see the following resources:
NumericTextBox.vb file to • Lesson: Extending and Creating Controls in Module 3, “Building
locate the code section Controls,” in Course 2565A, Developing Microsoft .NET
‘TODO: 2. Declare the Applications for Windows (Visual Basic .NET).
InvalidUserEntry event
that passes an Object type • Practice: Creating a Composite Control in Module 3, “Building
and KeyPressEventArgs Controls,” in Course 2565A, Developing Microsoft .NET
event arguments. Applications for Windows (Visual Basic .NET).
• The .NET Framework SDK documentation. For additional
information about raising events from custom controls, search by
using the phrase Defining an Event.
42 Module 3: Building Controls
4. Use the Task List in the a. For more information about how to raise an event, see the following
NumericTextBox.vb file to resources:
locate the code section • Lesson: Extending and Creating Controls in Module 3, “Building
‘TODO: 3. Raise the Controls,” in Course 2565A, Developing Microsoft .NET
InvalidUserEntry event, Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
the KeyPressEventArgs Applications for Windows (Visual Basic .NET).
event. • The .NET Framework SDK documentation. For additional
The InvalidUserEntry information about raising events from custom controls, search by
event will fire every time a using the phrase Defining an Event.
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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .NET).
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
Then, add a Applications for Windows (Visual Basic .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.
Module 3: Building Controls 43
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 2565A, Developing Microsoft
the event handler, use the .NET Applications for Windows (Visual Basic .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 2565A, Developing Microsoft
is pressed in a message box. .NET Applications for Windows (Visual Basic .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.
44 Module 3: Building Controls
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.
There are solution files associated with this exercise. Browse to install_folder\Labfiles\Lab03_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\2565.
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 2565A, Developing Microsoft .NET
Save the project in Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
OrderItemControl.vb. Applications for Windows (Visual Basic .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.
Module 3: Building Controls 45
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 2565A, Developing Microsoft .NET
B, C—placing each value on Applications for Windows (Visual Basic .NET).
a separate line. Use the
image of the • Practice: Creating a Composite Control in Module 3, “Building
OrderItemControl shown in Controls,” in Course 2565A, Developing Microsoft .NET
the illustration to determine Applications for Windows (Visual Basic .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.
46 Module 3: Building Controls
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 2565A, Developing Microsoft .NET
and sets the Text property of Applications for Windows (Visual Basic .NET).
QuantityTextBox.
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
gets and sets the Text Applications for Windows (Visual Basic .NET).
property of
ProductNameComboBox. • Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
and sets the Text property of Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
Currency. Applications for Windows (Visual Basic .NET).
Using property procedures • The .NET Framework SDK documentation. Search by using the
gives you greater control phrases Properties Overview and Format Function.
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 2565A, Developing Microsoft .NET
and sets the Text property of Applications for Windows (Visual Basic .NET).
DiscountTextBox.
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .NET).
• The .NET Framework SDK documentation. Search by using the
phrase Properties Overview.
Module 3: Building Controls 47
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 2565A, Developing Microsoft .NET
that returns a String and Applications for Windows (Visual Basic .NET).
gets and sets the Text
property of • Practice: Creating a Composite Control in Module 3, “Building
QuantityPerUnitTextBox. Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .NET).
• Practice: Creating a Composite Control in Module 3, “Building
Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
Resize Form1 to make the Applications for Windows (Visual Basic .NET).
control fit.
• Practice: Creating a Composite Control in Module 3, “Building
When you use User Controls Controls,” in Course 2565A, Developing Microsoft .NET
to create composite controls, Applications for Windows (Visual Basic .NET).
they are automatically added
to the Toolbox in the design • The Visual Studio .NET Help documentation. Search by using the
time environment of the phrase Using the Toolbox.
solution. When you develop
extended controls and
custom controls, you must
manually add them to the
ToolBox.
48 Module 3: Building Controls
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 2565A, Developing
following steps: Microsoft .NET Applications for Windows (Visual Basic .NET).
• Assign the • Practice: Creating an Event Handler for a Control in Module 2,
OrderItemProduct “Working with Controls,” in Course 2565A, Developing
Name property of the Microsoft .NET Applications for Windows (Visual Basic .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.
This is only to test the Get
and Set statements of the
property procedures that you
created.
16. Set a breakpoint on the first a. For more information about building and debugging your applications,
line in the Button1 click see the following resource:
event procedure created in • The Visual Studio .NET Help documentation. Search by using the
the step 15. Set the Test phrases Default and Custom Builds and Using the Debugger.
project as Startup Project,
rebuild the solution, and
then run the
OrderItemControl solution.
Select B in the
ProductNameComboBox
control, and type 12 in the
DiscountTextBox control.
Click Button1, and view the
results.
Module 3: Building Controls 49
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\2565.
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 install_folder\ Search in titles only check box, then search by using the phrase
Labfiles\Lab03_1\Ex03\ Open Project Dialog Box.
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 2565A, Developing Microsoft .NET
OrderItemControl as the Applications for Windows (Visual Basic .NET).
Category.
• Practice: Adding Design-Time Support for Controls in Module 3,
“Building Controls,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase Attributes and Design-Time Support.
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
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 73
Lab 4.2: Calling an XML Web Service 84
Review 88
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 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 following materials: Microsoft PowerPoint®
file 2565A_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
! What Is a DataSet?
! What Is a Typed DataSet?
! How to Add ADO.NET Objects to and Configuring
ADO.NET Objects in a Windows Forms Application
! Practice: Adding ADO.NET Objects to and Configuring
ADO.NET Objects in a Windows Forms Application
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 of 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 phrase 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 the 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.
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
storesSQLDataAdapter.Fill(storesDataSet.Tables(""Stores
storesSQLDataAdapter.Fill(storesDataSet.Tables( Stores""))
storesSQLDataAdapter.Fill(storesDataSet.Tables("Stores")
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)
16 Module 4: Using Data in Windows Forms Applications
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.
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:
storesSQLDataAdapter.SelectCommand.Parameters _
("@stor_id").Value = 6380
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.
storesSQLDataAdapter.Fill(StoreSalesDataSet1.Tables("sales")
Module 4: Using Data in Windows Forms Applications 17
! Adding rows
Dim
Dim newDataRow
newDataRow As
As DataRow
DataRow == __
pubsDataSet.Tables("Titles").NewRow
pubsDataSet.Tables("Titles").NewRow
newDataRow
newDataRow ("title")
("title") == "New
"New Book"
Book"
newDataRow
newDataRow ("type")
("type") == "business"
"business"
pubsDataSet.Tables("Titles").Rows.Add(newDataRow)
pubsDataSet.Tables("Titles").Rows.Add(newDataRow)
! Editing rows
changeDataRow.BeginEdit()
changeDataRow.BeginEdit()
changeDataRow("Title")
changeDataRow("Title") == changeDataRow("Title").ToString
changeDataRow("Title").ToString && __
"" 1"
1"
changeDataRow.EndEdit()
changeDataRow.EndEdit()
! Deleting data
Dim
Dim deleteDataRow
deleteDataRow As
As DataRow
DataRow == __
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:
Dim deleteDataRow As DataRow = _
pubsDataSet.Tables("Titles").Rows(0)
pubsDataSet.Tables("Titles").Rows.Remove(deleteDataRow)
Module 4: Using Data in Windows Forms Applications 19
insertTitlesCommand.Parameters.Add("@title_id",
insertTitlesCommand.Parameters.Add("@title_id", __
SqlDbType.VarChar,
SqlDbType.VarChar, 6,
6, "title_id")
"title_id")
insertTitlesCommand.Parameters.Add("@title",
insertTitlesCommand.Parameters.Add("@title", __
SqlDbType.VarChar,
SqlDbType.VarChar, 80,
80, "title")
"title")
insertTitlesCommand.Parameters.Add("@type",
insertTitlesCommand.Parameters.Add("@type", __
SqlDbType.Char,
SqlDbType.Char, 12,
12, "type")
"type")
titlesSQLDataAdapter.InsertCommand
titlesSQLDataAdapter.InsertCommand == insertTitlesCommand
insertTitlesCommand
titlesSQLDataAdapter.Update(pubsDataSet,
titlesSQLDataAdapter.Update(pubsDataSet, "titles")
"titles")
Explicitly specifying the You use the InsertCommand, UpdateCommand, and DeleteCommand
updates properties of the DataAdapter to identify the changes occurring in your
dataset. You specify each of these as an existing command object for an Insert,
Update, or Delete SQL statement. For any variable columns in the statements,
you use SqlParameter objects to identify the column, data type, size, and data
to be inserted.
The following code shows how to use the InsertCommand property to add a
row to the Titles table in the pubs database:
Dim insertTitlesCommand As New SqlClient.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.
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.
To refresh the view, right-click the results, and then click Run.
8. Switch back to the Store Orders application, delete the new row, and then
click Update.
9. 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
("C:\sampledata\CurrentOrders.xml",
("C:\sampledata\CurrentOrders.xml", __
XmlWriteMode.IgnoreSchema)
XmlWriteMode.IgnoreSchema)
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 Sub ReadXmlDataOnly()
Try
purchaseDataSet = New DataSet()
Console.WriteLine("Reading the Schema file")
purchaseDataSet.ReadXmlSchema _
("C:\sampledata\Purchase.xsd")
Console.WriteLine("Loading the XML data file")
purchaseDataSet.ReadXml _
("C:\sampledata\PurchaseData.xml", _
XmlReadMode.IgnoreSchema)
DataGrid1.DataSource = purchaseDataSet.Tables(0)
Catch e as Exception
Console.WriteLine("Exception: " & e.ToString())
End Try
End Sub
Partial syntax for writing The following code shows partial syntax for the WriteXml method of the
XML data 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 Sub SaveXMLDataOnly()
Try
Dim StrPurchaseSchema as String
purchaseDataSet = New DataSet()
Catch e as Exception
Console.WriteLine("Exception: " & e.ToString())
End Try
End Sub
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
StoresComboBox.DisplayMember = "stor_name"
StoresComboBox.ValueMember = "stor_id"
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.
TextBox1
TextBox1
Currency
Currency Manager1
Manager1
TextBox2
TextBox2
Data Source 1
Currency
Currency Manager2
Manager2
Datagrid
Dim
Dim cm
cm As
As CurrencyManager
CurrencyManager
cm
cm == Me.BindingContext(pubsDataSet,
Me.BindingContext(pubsDataSet, "Authors")
"Authors")
cm.Position
cm.Position +=
+= 11
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
CurrencyManager is managing. For example, to access the
CurrencyManager that manages the Authors table of DataSet1 you would use
the following code:
Dim cm As CurrencyManager
cm = Me.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:
Me.BindingContext(objOrdersDataSet, "Orders").Position = _
(Me.BindingContext(objOrdersDataSet, "Orders").Position + _
1)
2. Locate the objOrdersDataSet_PositionChanged() procedure, and discuss
the following line of code:
Me.lblNavLocation.Text = _
(((Me.BindingContext(objOrdersDataSet, _
"Orders").Position + 1).ToString + " of ") _
+ Me.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:
Me.BindingContext(objOrdersDataSet, "Orders").Position =
(Me.objOrdersDataSet.Tables("Orders").Rows.Count - 1)
4. In Solution Explorer, right-click the BindingContextNavigation project,
and then click Properties.
5. Set DataForm1 as the Startup object, and then click OK.
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
You can use the Format and Parse events to create custom formats for
displaying data. For example, if the data in a table is of type Decimal, you can
display the data in the local currency format by setting the Value property of
the ConvertEventArgs object to the formatted value in the Format event.
Consequently, you must remove the format from the displayed value in the
Parse event.
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 Sub BindControl()
Dim priceBinding As Binding = New Binding("Text", _
TitlesDataSet1, "titles.price")
AddHandler priceBinding.Parse, AddressOf _
ParseStringToDecimal
AddHandler priceBinding.Format, AddressOf _
FormatDecimalToString
PriceTextBox.DataBindings.Add(priceBinding)
End Sub
! 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 Sub ParseStringToDecimal(ByVal sender As Object, _
ByVal convertArgs As ConvertEventArgs)
Dim stringValue As String = convertArgs.Value
convertArgs.Value = Decimal.Parse(stringValue, _
NumberStyles.Currency)
End Sub
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:
AddHandler priceBinding.Parse, AddressOf
ParseStringToDecimal
3. The priceBinding object is a Binding object that is added to the
DataBindings collection of PriceTextBox. Review the following code:
Dim priceBinding As Binding = New Binding("Text", _
TitlesDataSet1, "titles.price")
…
PriceTextBox.DataBindings.Add(priceBinding)
Note This lab focuses on the concepts in Module 4, “Using Data in Windows
Forms Applications,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic® .NET). As a result, this lab may not
comply with Microsoft security recommendations.
48 Module 4: Using Data in Windows Forms Applications
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.
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\2565.
50 Module 4: Using Data in Windows Forms Applications
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resource:
PurchaseOrderApplication • The Visual Studio .NET Help documentation. For additional
.sln file. To open the information about opening a project file, in Search, select the
solution file, 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 2565A,
information, and create the Developing Microsoft .NET Applications for Windows
following SQL Select (Visual Basic .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 2565A,
@EmployeeID) Developing Microsoft .NET Applications for Windows
• Ensure that the wizard (Visual Basic .NET).
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.
• Change the name of the
new SQLDataAdapter
to OrdersDataAdapter.
3. Use the Task List to locate Additional information is not necessary for this task.
the code section 'TODO: 1',
and create a local variable to
hold an instance of
NorthwindDataSet and
name it tempDataSet.
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 2565A, Developing Microsoft .NET Applications for
the SelectCommand Windows (Visual Basic .NET).
property of
OrdersDataAdapter and • Practice: Populating and Updating DataSets in Module 4, “Using
OrderDetailsDataAdapter. Data in Windows Forms Applications,” in Course 2565A,
Developing Microsoft .NET Applications for Windows
(Visual Basic .NET).
• The Visual Studio .NET SDK documentation. Search by using the
phrase Using Parameters with a DataAdapter.
Module 4: Using Data in Windows Forms Applications 51
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 2565A, Developing Microsoft .NET Applications for
to fill the Orders and Windows (Visual Basic .NET).
OrderDetails tables of
tempDataSet. • Practice: Populating and Updating DataSets in Module 4, “Using
Data in Windows Forms Applications,” in Course 2565A,
Developing Microsoft .NET Applications for Windows
(Visual Basic .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\2565.
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:
PurchaseOrderApplication.s • The Visual Studio .NET Help documentation. For additional
ln file. To open the solution information about opening a project file, in Search, select the
file, 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. From the
Data menu, click Refresh
Data. 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.
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\2565.
Module 4: Using Data in Windows Forms Applications 55
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resource:
PurchaseOrderApplication • The Visual Studio .NET Help documentation. For additional
.sln file. To open the information about opening a project file, in Search, select the
solution file, 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 2565A, 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 2565A, 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
.vb and update the database Course 2565A, Developing Microsoft .NET Applications for
by using the Update method Windows (Visual Basic .NET).
of OrdersDataAdapter and
OrderDetailsDataAdapter. • Practice: Populating and Updating DataSets in Module 4, “Using
Data in Windows Forms Applications,” in Course 2565A,
The Cascading Update rule Developing Microsoft .NET Applications for Windows (Visual
enforced by the relation Basic .NET).
between the two tables
should automatically • The Visual Studio .NET Help documentation. Search by using the
retrieve the OrderID phrase Updating the Database with a DataAdapter and the
generated by the server. DataSet.
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 in 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 install_folder\Labfiles\
Lab04_1\Ex04\Starter to find the starter files, and browse to install_folder\Labfiles\Lab04_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\2565.
1. Open Visual Studio .NET, a. For more information about opening a project file, see the following
and open the resources
PurchaseOrderApplication.s • The Visual Studio .NET Help documentation. For additional
ln file. To open the solution information about opening a project file, in Search, select the
file, 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 view of • Lesson: Binding Data to Controls in Module 4, “Using Data in
OrderItemControl.vb, and Windows Forms Applications,” in Course 2565A, Developing
assign the DataSource of Microsoft .NET Applications for Windows (Visual Basic .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 2565A, Developing
procedure. Assign the Microsoft .NET Applications for Windows (Visual Basic .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 2565A, Developing
Text property of Microsoft .NET Applications for Windows (Visual Basic .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 2565A, Developing
GetProductData procedure. Microsoft .NET Applications for Windows (Visual Basic .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 2565A, Developing
DecimalToCurrency that Microsoft .NET Applications for Windows (Visual Basic .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 2565A,
format. Developing Microsoft .NET Applications for Windows (Visual
Basic .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 2565A, Developing
Binding object created in Microsoft .NET Applications for Windows (Visual Basic .NET).
step 4.
• Practice: Creating an Event Handler for a Control in Module 2,
“Working with Controls,” in Course 2565A, Developing
Microsoft .NET Applications for Windows (Visual Basic .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)
h s
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 2565A,
Developing Microsoft .NET Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET Applications for Windows
(Visual Basic .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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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.
Alternatively, you can use WSDL to generate a proxy. The following code
generates a proxy by using Visual Basic .NET and default protocol (SOAP).
wsdl http://www.contoso.com/ExpenseReportWebService/
ExpenseReportWebService.asmx?wsdl
Module 4: Using Data in Windows Forms Applications 69
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:
Dim WS As 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
Dim ds As DataSet = WS.GetReportsForEmployee(username, _
passwordToken, 0, 10, totalReports)
70 Module 4: Using Data in Windows Forms Applications
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(Nothing, Nothing, 0, 10, _
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.
Module 4: Using Data in Windows Forms Applications 75
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.
Imports System
Imports System.IO
Class MyStream
Private Const FILE_NAME As String = "Test.data"
Public Shared Sub Main()
' Create the new, empty data file.
If (File.Exists(FILE_NAME)) Then
Console.WriteLine("{0} already exists!", FILE_NAME)
Return
End If
Dim fs As New FileStream(FILE_NAME, FileMode.CreateNew)
' Create the writer for data.
Dim w As New BinaryWriter(fs)
' Write data to Test.data.
Dim i As Integer
For i = 0 To 10
w.Write(i)
Next i
w.Close()
fs.Close()
' Create the reader for data.
fs = New FileStream(FILE_NAME, FileMode.Open, _
FileAccess.Read)
Dim r As New BinaryReader(fs)
' Read data from Test.data.
For i = 1 To 10
Console.WriteLine(r.ReadInt32())
w.Close()
Next i
End Sub
End Class
76 Module 4: Using Data in Windows Forms Applications
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:
Imports System
Imports System.IO
Class CharsFromStr
Public Shared Sub Main()
' Create a string to read characters from.
Dim str As String = "Some number of characters"
' Size the array to hold all the characters of the
' string, so that they are all accessible.
Dim b(24) As Char
' Create a StringReader and attach it to the string.
Dim sr As New StringReader(str)
' Read 13 characters from the array that holds
' the string, starting from the first array member.
sr.Read(b, 0, 13)
' Display the output.
Console.WriteLine(b)
' Close the StringReader.
sr.Close()
End Sub
End Class
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.
Module 4: Using Data in Windows Forms Applications 77
! Binary serialization
! XML serialization
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 OrderDate As DateTime
End Class
! 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.
80 Module 4: Using Data in Windows Forms Applications
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.
Module 4: Using Data in Windows Forms Applications 81
CodeExample
Procedure: Saving data There are three main steps to accessing isolated storage:
by using XML
serialization 1. Open the store.
Dim isoStore As IsolatedStorageFile = Nothing
isoStore = IsolatedStorageFile.GetUserStoreForDomain()
2. Create a stream for reading or writing files in the store.
Dim dataFile As IsolatedStorageFileStream = Nothing
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()
Module 4: Using Data in Windows Forms Applications 83
! 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
Note This lab focuses on the concepts in Module 4, “Using Data in Windows
Forms Applications,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .NET). As a result, this lab may not
comply with Microsoft security recommendations.
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
Visual Studio .NET. Browse to install_folder\ file and starting an application, see the following
Labfiles\Lab04_2\Ex01\Starter to find the project resource:
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 service a. For more information about how to add a Web
on your local computer. The URL for this XML reference, see the following resources:
Web service is: • Practice: Calling an XML Web Service in
http://localhost/ Module 4, “Using Data in Windows Forms
ExpenseReportWebService/ Applications,” in Course 2565A, Developing
ExpenseReportWebService.asmx Microsoft .NET Applications for Windows
(Visual Basic .NET).
• Lesson: Creating a Simple XML Web
Services Client in Module 4, “Using Data in
Windows Forms Applications,” in Course
2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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
Add the code to create the XML Web service following 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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .NET).
• Lesson: Creating a Simple XML Web
Services Client in Module 4, “Using Data in
Windows Forms Applications,” in Course
2565A, Developing Microsoft .NET
Applications for Windows
(Visual Basic .NET).
Module 4: Using Data in Windows Forms Applications 87
4. Open the ExpenseReportList form, and view its a. For more information about how to call a
code. Find the two TODO comments in the method of an XML Web service, see the
constructor. Add the code to make the XML Web following resources:
service calls after the comments. In each case, you • Practice: Calling an XML Web Service in
will retrieve the XML Web service proxy from the Module 4, “Using Data in Windows Forms
static (shared) Utilities object, by using the Applications,” in Course 2565A, Developing
following syntax: Microsoft .NET Applications for Windows
Utilities.WS (Visual Basic .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 2565A, Developing Microsoft .NET
following parameters. Applications for Windows
Parameter Value (Visual Basic .NET).
username UCred.UserNameString
passwordToken UCred.PasswordTokenString
reportIndex RecordCursor
numberReports 10
totalNumberReports TotalNumRecords
Review
3. How do you access tables and columns in a typed and untyped dataset?
Typed dataset
pubsDataSet.Titles
Untyped dataset
pubsDataSet.Tables("Titles")
Module 4: Using Data in Windows Forms Applications 89
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.
90 Module 4: Using Data in Windows Forms Applications
Overview 1
Lesson: Using .NET and COM Components
in a Windows Forms Application 2
Lesson: Calling Win32 APIs from Windows
Forms Applications 16
Lesson: Upgrading Visual Basic 6.0
Applications to Visual Basic .NET 29
Review 36
Lab 5.1: Interoperating with COM and
Calling Win32 APIs 39
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: Students will also learn how to upgrade their existing Microsoft Visual Basic®
30 minutes 6.0 applications to Visual Basic .NET.
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.
! Upgrade Visual Basic 6.0 applications to Visual Basic .NET.
Required materials To teach this module, you need the Microsoft PowerPoint® file 2565A_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. The
module also covers how to upgrade existing Microsoft Visual Basic® 6.0
applications to Visual Basic .NET.
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.
! Upgrade Visual Basic 6.0 applications to Visual Basic .NET.
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 always Object based. .NET Framework objects can
communicate through interfaces. pass data directly to each other, without
implementing interfaces.
Identity Globally unique identifiers (GUIDs). GUIDs Strong names. Strong names consist of a
identify a specific unmanaged type and unique assembly name in addition to a type
provide no location information for that name. Because the assembly name uniquely
type. 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 layout Type standard. The .NET common type
of classes must comply with COM rules. system specification establishes a framework
that enables cross-language integration, type
safety, and so on.
Type definition Type library. Type information is stored Metadata. Type information is stored as
only for public types. Moreover, a type metadata and is mandatory for all types.
library is optional. Metadata is embedded inside assemblies.
Module 5: Interoperating with Managed Objects 5
(continued)
Characteristic COM .NET Framework
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 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
Primary interop A shared interop assembly signed by the company that produced the original
assemblies type library is called a primary interop assembly. An assembly signed by any
other company or individual is called an alternate interop assembly.
Primary interop assemblies (PIA) are provided by the same publisher as the
type library that they describe, and provide the official definitions of the types
defined with that type library. Primary interop assemblies are always signed by
their publisher to ensure uniqueness. A primary interop assembly is created
from a type library by running TLBIMP with the /primary switch.
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 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
Role of platform invoke When platform invoke calls an unmanaged function, it performs the following
in calling Win32 APIs set of actions.
1. Locates the DLL containing the function.
To locate a function in a DLL, platform invoke must have the following
information.
a. The name of the DLL file, such as User32.dll, GDI32.dll, or
Kernel32.dll.
b. The name of the function or ordinal number, such as MessageBox or
exported function number #452.
c. The character set which will be used—ANSI or Unicode.
Win32 API contains two versions of each function: a single-Byte
character ANSI version and a double-Byte character Unicode version.
For instance, MessageBoxA is the ANSI entry point for the MessageBox
function and MessageBoxW is the Unicode version.
The character set is controlled by the value of the CharSet field of
DllImportAttribute, which will be discussed later in more detail.
2. Loads the DLL into memory.
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.
Module 5: Interoperating with Managed Objects 19
Public
Public Class
Class Win32PlaySound
Win32PlaySound
Public
Public Declare
Declare Auto
Auto Function
Function PlaySound
PlaySound Lib
Lib
"winmm.dll"
"winmm.dll" Alias
Alias "PlaySound"
"PlaySound" __
(ByVal
(ByVal pszSound
pszSound As
As String,
String, ByVal
ByVal hmod
hmod As
As Long,
Long,
ByVal
ByVal fdwSound
fdwSound As
As Long)
Long) As
As Boolean
Boolean
End
End Class
Class
Note The Declare statement has only a subset of the features provided by
DllImport. So, in some cases, you may not be able to use the Declare statement.
For example, the Declare statement does not allow you to alter the
ExactSpelling, CallingConvention, or SetLastError default values. You must
use DllImport to change these settings.
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 Shared Function _
MoveFile(ByVal src As String, ByVal dst As String) As Boolean
End Function
22 Module 5: Interoperating with Managed Objects
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.
5. Use a Boolean value to hold the results of the function. Your code should
look like the following.
Public Declare Auto Function PlaySound_Declare
Lib "winmm.dll" Alias "PlaySound" (ByVal pszSound As
String, _
ByVal hmod As Long, ByVal fdwSound As Long) As Boolean
pszSound soundFileName
hmod 0
fdwSound 0
Note If there are no speakers available to test the sound, test the value of the
result variable in the debug mode.
Module 5: Interoperating with Managed Objects 27
____________________________________________________________
____________________________________________________________
____________________________________________________________
End Function
28 Module 5: Interoperating with Managed Objects
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.
Module 5: Interoperating with Managed Objects 29
! Advantages of Upgrading
! Results of the Upgrade Wizard
! Demonstration: Upgrading Visual Basic 6.0
Applications to Visual Basic .NET
Advantages of Upgrading
Advantages
Advantages
Deployment
Deployment
Language
Language integration
integration
Object-oriented
Object-oriented language
language
IImproved
!
mproved RAD
! RAD experience
experience
No
No DLL
DLL versioning
versioning issues
issues
Important There are a number of syntax changes between Visual Basic .NET
and previous versions, and a few of the features that are supported in
Visual Basic 6.0 have been removed from Visual Basic .NET. Therefore, it is
important that you review your existing Visual Basic 6.0–based applications for
incompatibility issues between the two languages and update those features
before you upgrade the applications by using the Upgrade Wizard.
Language changes The Upgrade Wizard modifies the code where possible to take into account the
syntax changes in Visual Basic .NET. This includes:
! Resolving parameterless default properties.
! Adding the ByRef keyword to procedure parameters.
! Changing property procedures to the new syntax.
! Adding parentheses to all function calls.
! Changing all data types to their new equivalents.
Module 5: Interoperating with Managed Objects 33
Form changes Visual Basic forms are upgraded to Windows Forms, although a few controls
cannot be upgraded because they have no counterpart in Visual Basic .NET.
These include the following, which all upgrade to Visual Studio .NET Label
controls:
! OLE Container controls
! Shape controls
! Line controls
Other Changes Other functionality in applications created in Visual Basic 6.0 may not have a
direct counterpart in Visual Basic .NET but will be left as is or upgraded to
similar objects. For example:
! Code that performs drag-and-drop operations will not upgrade.
! Code that uses GDI will not upgrade to GDI+.
! Resource files will upgrade to .resx files that can store any .NET data type.
! Web classes will not upgrade.
! ADO data environments will not upgrade.
! ADO code and ADO data binding will remain unchanged.
! Property pages are no longer used in Visual Basic .NET.
! 1 based arrays will not upgrade.
34 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.
7. List some of the components of a Visual Basic 6.0 application that do not
upgrade to .NET.
Code that performs drag-and-drop operations will not upgrade.
Code that uses GDI will not upgrade to GDI+.
Web classes will not upgrade.
ADO data environments will not upgrade.
ADO code and ADO data binding will remain unchanged.
1 based arrays will not upgrade.
Module 5: Interoperating with Managed Objects 39
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
Module 5: Interoperating with Managed Objects 41
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\2565.
42 Module 5: Interoperating with Managed Objects
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 install_folder\ Search in titles only check box, then search by using the phrase
Labfiles\ Lab05_1\Ex01\ Open Project Dialog Box.
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 install_folder\ • Lesson: Using .NET and COM Components in a Windows Forms
Labfiles\Lab05_1\Ex01\ Application in Module 5, “Interoperating with Managed
Starter\ using the REGSVR32 Objects,” in Course 2565A, Developing Microsoft .NET
utility and add a reference to Applications for Windows (Visual Basic .NET).
the component.
• Practice: Using COM Components in .NET-Based Applications
When you use the IDE to in Module 5, “Interoperating with Managed Objects,” in
create a reference to a COM Course 2565A, Developing Microsoft .NET Applications for
component, it uses TLBIMP Windows (Visual Basic .NET).
to create an Interop assembly.
• The Visual Studio .NET Help documentation. For additional
If you have already registered information about creating References, search by using the
this component in Practice: phrase Adding and Removing References.
Using COM Components in
.NET Applications in • The.NET Framework SDK documentation. For additional
Module 5, “Interoperating information about creating Interop assemblies, search by using
with Managed Objects,” in the phrase Importing a Type Library as an Assembly.
Course 2565A, Developing
Microsoft .NET Applications
for Windows
(Visual Basic .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.
Interop.NorthwindData_COM
.dll is the Interop assembly
that was generated when you
added a reference to the
NorthwindData_COM.dll.
Module 5: Interoperating with Managed Objects 43
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 • Lesson: Using .NET and COM Components in a Windows Forms
'TODO 1. Create an instance Application in Module 5, “Interoperating with Managed
of the NorthwindData_ Objects,” in Course 2565A, Developing Microsoft .NET
COMRemainingInventory Applications for Windows (Visual Basic .NET).
Class COM component.
• Practice: Using COM Components in .NET-Based Applications
in Module 5, “Interoperating with Managed Objects,” in
Course 2565A, Developing Microsoft .NET Applications for
Windows (Visual Basic .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 2565A, Developing Microsoft .NET Applications for
of the OrderItemControl. Windows (Visual Basic .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 resource:
a Try, Catch block and call • Lesson: Using .NET and COM Components in a Windows Forms
the ShowUnitsInStock Application in Module 5, “Interoperating with Managed
method of the Objects,” in Course 2565A, Developing Microsoft .NET
RemainingInventoryClass Applications for Windows (Visual Basic .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
SQL Server with the Course 2565A, Developing Microsoft .NET Applications for
Northwind database installed. Windows (Visual Basic .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
The name of the SQL Server phrase Using the Try/Catch Block to Catch Exceptions.
uses syntax similar to • The Visual Studio .NET SDK documentation. For help with
LONDON\MOC. using COM components in managed code, search by using the
phrase Using COM Types in Managed Code.
44 Module 5: Interoperating with Managed Objects
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.
A message box appears that
displays the current number of
units in stock.
Module 5: Interoperating with Managed Objects 45
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\2565.
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 install_folder\ Search in titles only check box, then search by using the phrase
Labfiles\Lab05_1\Ex02\ Open Project Dialog Box.
Starter\OrderApplication.
2. Add the Save.wav sound file a. For more information about adding new items to a project, see the
located in install_folder\ following resource:
Labfiles\Lab05_1\Ex02\Starter • The Visual Studio .NET Help documentation. Search by using
to the Bin directory of the the phrase Adding Projects and Items to the New Application.
PurchaseOrderApplication
project .
46 Module 5: Interoperating with Managed Objects
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.vb. 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 2565A, Developing Microsoft .NET Applications for
Windows (Visual Basic .NET).
• Practice: Calling Win32 APIs in Module 5, “Interoperating with
Managed Objects,” in Course 2565A, Developing
Microsoft .NET Applications for Windows (Visual Basic .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 • Lesson: Calling Win32 APIs from Windows Forms Applications
'TODO 1. Create a variable to in Module 5, “Interoperating with Managed Objects,” in
hold an instance of the Course 2565A, Developing Microsoft .NET Applications for
Win32PlaySound class. Call Windows (Visual Basic .NET).
the PlaySound function with
the variable. Pass “Save.wav” • Practice: Calling Win32 APIs in Module 5, “Interoperating with
as the name of the media file, Managed Objects,” in Course 2565A, Developing
a 0 for the second argument, Microsoft .NET Applications for Windows (Visual Basic .NET).
and a 0 for the third argument. • The .NET Framework SDK documentation. For help with using
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.
You should hear a sound play.
If sound is not available with
your computer, test the
Boolean value returned by the
PlaySound function; this
value indicates success or
failure.
Module 6: Printing and
Reporting in Windows
Forms Applications
Contents
Overview 1
Lesson: Printing from a Windows Forms
Application 2
Lesson: Using the Print Preview, Page
Setup, and Print Dialogs 15
Lesson: Constructing Print Document
Content by Using GDI+ 31
Lesson: Creating Reports by Using
Crystal Reports 46
Review 54
Lab 6.1: Printing Formatted Documents 56
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 following materials: Microsoft PowerPoint®
file 2565A_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
printing
But
But How
How Do
Do II • PrintPreviewDialog
Actually
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 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 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 2565A,
Developing Microsoft .NET Applications for Windows (Visual Basic .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
subroutine 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
____________________________________________________________
____________________________________________________________
! Create a print loop to ensure that all of the document pages are printed
1. Modify the contents of the If-Then-Else statement near the bottom of your
MyPrintPage subroutine so that it appears as follows:
If currentPage < totalPages Then
currentPage += 1
e.HasMorePages = True
Else
e.HasMorePages = False
End If
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.
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 subroutine is called from an event handler.
Private Sub PrintPreview()
' ensure that the first page of the print document is shown
PrintPreviewDialog1.PrintPreviewControl.StartPage = 0
' maximize the size of the dialog box on the display screen
PrintPreviewDialog1.WindowState = FormWindowState.Maximized
End Sub
____________________________________________________________
Module 6: Printing and Reporting in Windows Forms Applications 19
____________________________________________________________
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.
____________________________________________________________
____________________________________________________________
Example The following code shows an example of how to use the PageSetupDialog
control.
Private Sub PageSetup()
Try
Dim pageDialog As New PageSetupDialog()
pageDialog.PageSettings = storedPageSettings
pageDialog.ShowDialog
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
PrintDocument1.DefaultPageSettings = storedPageSettings
End Sub
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
____________________________________________________________
24 Module 6: Printing and Reporting in Windows Forms Applications
____________________________________________________________
6. Close the application, and then add the following code lines to the top of the
PageSetup subroutine.
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.
____________________________________________________________
____________________________________________________________
____________________________________________________________
If time permits
! Examine some additional members of the PageSetupDialog control
1. In the Code Editor, examine the code in the pageSetupButton_Click
subroutine.
2. Remove the comment character from the front of the code lines one section
at a time, and view the changes to the PageSetup dialog box and Print
Preview by running the application and opening the two dialog boxes.
3. Close the application and Visual Studio .NET.
4. 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.
____________________________________________________________
____________________________________________________________
____________________________________________________________
26 Module 6: Printing and Reporting in Windows Forms Applications
PrintDialog
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 Sub PrintDoc()
Dim userResponse As DialogResult
PrintDialog1.Document = PrintDocument1
userResponse = PrintDialog1.ShowDialog()
End If
End Sub
28 Module 6: Printing and Reporting in Windows Forms Applications
____________________________________________________________
Module 6: Printing and Reporting in Windows Forms Applications 29
____________________________________________________________
7. Click OK, close the application, and then add the following code line to the
top of the PrintDoc subroutine.
PrintDialog1.Document = PrintDocument1
____________________________________________________________
____________________________________________________________
____________________________________________________________
Note For more information about the DialogResult object, see the Visual
Studio .NET Help documentation.
30 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.DrawLine(myPen,X1,Y1,X2,Y2)
myGraphic.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
Dim myGraphic as Graphics
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.
Dim myBrush As New SolidBrush(Color.Blue)
Dim myGradientBrush as New LinearGradientBrush( _
myRectangle As New Rectangle(0,0,100,100), _
Color.White, _
Color.LightBlue, _
LinearGradientMode.Horizontal)
For more information about Hatched, Textured, and Gradient 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.
Dim fontSmall As Font = New Font("Arial", 10)
Dim fontLarge As Font
fontLarge = New Font("Lucida", 12, _
FontStyle.Bold, GraphicsUnit.Millimeters)
Module 6: Printing and Reporting in Windows Forms Applications 37
! 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,
e.Graphics.MeasureString(myText,
myFont).Width
myFont).Width
textHeight
textHeight == e.Graphics.MeasureString(myText,
e.Graphics.MeasureString(myText,
myFont).Height
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)
Module 6: Printing and Reporting in Windows Forms Applications 39
Finally
Finally
StreamToPrint.Close()
StreamToPrint.Close()
End
End Try
Try
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 the PrintPage event handler
While currentLine < linesPerPage
' read a line of text from the StreamReader object
textLine = streamToPrint.ReadLine()
End While
Else
e.HasMorePages = False
End If
Module 6: Printing and Reporting in Windows Forms Applications 41
____________________________________________________________
____________________________________________________________
____________________________________________________________
If time permits, examine the code used to create the gradient filled text.
6. Save your application, and then close Visual Studio .NET.
46 Module 6: Printing and Reporting in Windows Forms Applications
! Crystal Reports
! How to Create and Format a Report by Using Crystal
Reports
! How to View a Report by Using Crystal Report Viewer
! How to Add DataSets to a Report
! Practice: Creating and Viewing Crystal Reports
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 data source
Expert template
Expert
Note Use the existing connection information for the Pubs database if it
already exists and skip to the next procedure.
Review
Note This lab focuses on the concepts in Module 6, “Printing and Reporting in
Windows Forms Applications,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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-2565P (portrait) and NT-2565L (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
58 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 subroutine 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\2565.
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 59
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 resources:
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.
You can open two instances
of Visual Studio .NET when
you want to work on an
application and an external
class library at the same
time.
2. Use the Task List in the a. For more information about the Drawing and Drawing2D namespaces
Lab06Class.vb file to locate and why you should use them, see the following resources:
the code section 'TODO: • Lesson: Constructing Print Document Content by Using GDI+ in
Programmatically reference Module 6, “Printing and Reporting in Windows Forms
required namespaces' and Applications,” in Course 2565A, Developing Microsoft .NET
then add code statements Applications for Windows (Visual Basic .NET).
that reference the Drawing
and Drawing2D • The Visual Studio .NET Help documentation. For additional
namespaces. information about creating a reference to a namespace, search by
using the phrases References and the Imports Statement,
When you create a reference Namespaces and Imports Statement. For additional information
to a namespace, you can about the Drawing and Drawing2D namespaces, search by using
refer to the namespace the phrases System.Drawing and System.Drawing.Drawing2D.
members without having to
fully qualify member names
in your code. This makes
your code easier to develop
and easier to read.
60 Module 6: Printing and Reporting in Windows Forms Applications
3. Use the Task List in the a. For more information about the PrintPage event and the
Lab06Class.vb 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 2565A, Developing Microsoft .NET Applications for
Subroutine’ and then create Windows (Visual Basic .NET).
the declaration statement for
a subroutine 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 2565A, Developing Microsoft .NET
event. Add code statements Applications for Windows (Visual Basic .NET).
to the subroutine that call • The Visual Studio .NET Help documentation. For additional
the information about the PrintPage event, search by using the phrases
PrintingEmptyForm2565 Creating Standard Windows Forms Print Jobs and
and PrintDocument.PrintPage Event. For additional information
PrintingContentsForm256 about the PrintPageEventArgs class, search by using the phrases
5 subroutines. PrintPageEventArgs Class and PrintPageEventArgs Members.
The PrintPage subroutine
handles all requests for a
page of the print document.
The PrintPageEventArgs
class that is passed to the
PrintPage subroutine
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.vb 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 2565A, Developing Microsoft .NET Applications for
create a code section that Windows (Visual Basic .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 Applications,” in Course 2565A, Developing Microsoft .NET
currentPurchaseItemNum Applications for Windows (Visual Basic .NET).
ber is less than • The Visual Studio .NET Help documentation. Search by using the
totalPurchaseItems, phrase PrintPageEventArgs.HasMorePages Property.
otherwise specify that there
are no more pages to print.
In Visual Studio .NET, you
must create your own
programming logic to set the
HasMorePages property to
generate print documents
that consist of more than one
page.
Module 6: Printing and Reporting in Windows Forms Applications 61
5. Rebuild the Lab06Class a. For more information about referencing an external class, see the
project, and then, 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.
After you rebuild a class
library, ensure that your
applications reference the
new version.
6. Open the code editor view a. For more information about the code editor view and the Task List, see
of MainForm.vb in the the following resource:
Lab06Application project, • The Visual Studio .NET Help documentation. For help with the
and configure the Task List code editor, search by using the phrase Managing the Code
to display comments. Editor and View. For help with Task List, search by using the
Using the Task List and phrase Task List Views.
TODO comments can help
you remember development
tasks that must still be done.
7. Use the Task List to locate a. For more information about the PrintPreviewDialog class and how to
the code section ‘TODO: add an instance of this dialog box to your application, see the following
Create an instance of the resources:
PrintPreviewDialog class’. • Lesson: Using the Print Preview, Page Setup, and Print Dialogs in
Add code below the Module 6, “Printing and Reporting in Windows Forms
comment line that creates an Applications,” in Course 2565A, Developing Microsoft .NET
instance of the Applications for Windows (Visual Basic .NET).
PrintPreviewDialog class
named • Practice: Using the PrintPreviewDialog Control in Module 6,
form2565PreviewDialog. “Printing and Reporting in Windows Forms Applications,” in
Course 2565A, Developing Microsoft .NET Applications for
Windows (Visual Basic .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrase Introduction to the Windows Forms PrintPreviewDialog
Control.
62 Module 6: Printing and Reporting in Windows Forms Applications
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 2565A,Developing Microsoft .NET
comment line that creates an Applications for Windows (Visual Basic .NET).
instance of the
PageSetupDialog class • Practice: Using the PageSetupDialog Control in Module 6,
named “Printing and Reporting in Windows Forms Applications,” in
form2565SetupDialog. Course 2565A, Developing Microsoft .NET Applications for
Windows (Visual Basic .NET).
The PageSetupDialog class
enables users to modify the • The Visual Studio .NET Help documentation. Search by using the
page settings of a print phrases Introduction to the Windows Forms PageSetupDialog
document. You can use it to Component, PageSetupDialog Class, and PageSetupDialog
test the code that constructs Members.
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 2565A, Developing Microsoft .NET
creates an instance of the Applications for Windows (Visual Basic .NET).
PrintDialog class named
form2565PrintDialog. • Practice: Using the PageSetupDialog Control in Module 6,
“Printing and Reporting in Windows Forms Applications,” in
Course 2565A, Developing Microsoft .NET Applications for
Windows (Visual Basic .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 63
10. Use the Task List to locate a. The purchaseItemNumber and purchaseItemCount variables are passed
the code section ‘TODO: to the Lab06Class class (inherits from PrintDocument) and used to
Set purchaseItemNumber determine when HasMorePages should be set to True or False. The
and purchaseItemCount’. purchaseItemNumber variable is the current purchase item being
Add 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.
In addition to developing the
code logic that determines
when HasMorePages is
True or False, you must
reset the variables that are
used to make this
determination every time a
print document is generated.
11. Use the Task List to locate a. For more information about the PrintPreviewDialog class and how it
the code section ‘TODO: can be used in the print process, see the following resources:
Add support for a full screen • Lesson: Using the Print Preview, Page Setup, and Print Dialogs in
preview of the print Module 6, “Printing and Reporting in Windows Forms
document’. Add code below Applications,” in Course 2565A, Developing Microsoft .NET
the comment line that Applications for Windows (Visual Basic .NET).
assigns the
form2565Document • Practice: Using the PrintPreviewDialog Control in Module 6,
instance of the Lab06Class “Printing and Reporting in Windows Forms Applications,” in
class to the Document Course 2565A, Developing Microsoft .NET Applications for
property of Windows (Visual Basic .NET).
form2565PreviewDialog • The Visual Studio .NET Help documentation. Search by using the
(the print preview dialog phrase Displaying Print Preview in Windows Applications.
box) and displays the print
document by using the full
display screen.
Implementing support for
the print preview dialog box
early in the development
process enables you to
preview the print document
as you develop the code that
constructs your document.
64 Module 6: Printing and Reporting in Windows Forms Applications
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, use
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 2565A, Developing Microsoft .NET
you can now display the Applications for Windows (Visual Basic .NET).
print preview dialog box.
Close the Lab06Application • In 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 2565A, Developing Microsoft .NET
comment line that disables Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET Applications for
only those page settings that Windows (Visual Basic .NET).
are required will help to
eliminate support issues that • The Visual Studio .NET Help documentation. Search by using the
would be generated when phrase PageSetupDialog Members.
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 Module 6, “Printing and Reporting in Windows Forms
code statements below the Applications,” in Course 2565A, Developing Microsoft .NET
comment line that will send Applications for Windows (Visual Basic .NET).
form2565Document
document to the printer • Practice: Using the PageSetupDialog Control in Module 6,
when the application user “Printing and Reporting in Windows Forms Applications,” in
clicks OK to close the print Course 2565A, Developing Microsoft .NET Applications for
dialog. Windows (Visual Basic .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.
66 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 67
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\2565.
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-2565P and NT-2565L. To correct this problem, you will review the data contained in the
NT-2565P and NT-2565L 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-2565P and NT-2565L 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 install_folder\ the phrase Debugging Windows Applications.
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.vb 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 2565A, Developing Microsoft .NET
Create the pageBorderPen'. Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
characteristics: Applications for Windows (Visual Basic .NET).
Color = Gray, width = 3, • The Visual Studio .NET Help documentation. Search by using the
DashStyle = Dash. phrases Pens, Brushes, and Colors; Setting Pen Width and
Alignment (in the .NET Framework Developer’s Guide) and
Using a Brush to Fill Shapes.
68 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 Applications,” in Course 2565A, Developing Microsoft .NET
black brush named Applications for Windows (Visual Basic .NET).
footerBrush.
• Practice: How to Construct Print Document Content Using GDI+ in
Module 6, “Printing and Reporting in Windows Forms
Applications,” in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
line that creates a font Applications for Windows (Visual Basic .NET).
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 2565A, Developing Microsoft .NET
emSize = 7. Applications for Windows (Visual Basic .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 69
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 2565A, Developing Microsoft .NET
required to draw the border Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
customerSectionLeft, Applications for Windows (Visual Basic .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.
GDI+ offers many ways to
draw an outlined shape such
as a rectangle. As a
developer, it is important to
consider whether the
parameters used to draw a
shape can be used again
later in your program before
you select a drawing
method.
6. 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 a rectangle that • Lesson: Constructing Print Document Content Using GDI+ in
defines the margin limits'. Module 6, “Printing and Reporting in Windows Forms
Create the code statements Applications,” in Course 2565A, Developing Microsoft .NET
required to draw a rectangle Applications for Windows (Visual Basic .NET).
that defines the limits of the
page by using the following • Practice: How to Construct Print Document Content Using GDI+ in
variables: pageBorderPen, Module 6, “Printing and Reporting in Windows Forms
pageLeft, pageTop, Applications,” in Course 2565A, Developing Microsoft .NET
pageWidth, pageHeight. Applications for Windows (Visual Basic .NET).
• The Visual Studio .NET Help documentation. Search by using the
phrases Pens, Lines, and Rectangles; Using a Pen to Draw Lines
and Rectangles; and Graphics Methods.
70 Module 6: Printing and Reporting in Windows Forms Applications
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 2565A, Developing Microsoft .NET
Create the code statements Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
purchaseSectionHeaderRow Applications for Windows (Visual Basic .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.
When you use filled shapes
on a print document,
consider how the document
will look when it is
photocopied or printed by
using a gray scale.
8. Use Task List to locate the a. For more information about drawing lines, see the following resources:
code section 'TODO: Draw • Lesson: Constructing Print Document Content Using GDI+ in
the horizontal lines inside Module 6, “Printing and Reporting in Windows Forms
the Purchase Items table'. Applications,” in Course 2565A, Developing Microsoft .NET
Create the code statements Applications for Windows (Visual Basic .NET).
required to draw the interior
lines by using the following • Practice: How to Construct Print Document Content Using GDI+ in
variables: Module 6, “Printing and Reporting in Windows Forms
sectionInteriorPen, Applications,” in Course 2565A, Developing Microsoft .NET
purchaseSectionLeft, Applications for Windows (Visual Basic .NET).
verticalPosition, • The Visual Studio .NET Help documentation. Search by using the
purchaseSectionRight, phrases Using a Pen to Draw Lines and Rectangles, Drawing a
verticalPosition. Line with Line Caps, and Using a Pen to Draw Lines and
In addition to using the Shapes.
width and color properties to
change the appearance of a
line, you should consider
using line styles and line
caps.
Module 6: Printing and Reporting in Windows Forms Applications 71
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 2565A, Developing Microsoft .NET
printText variable by using Applications for Windows (Visual Basic .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 2565A, Developing Microsoft .NET
horizontalPosition has a Applications for Windows (Visual Basic .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.
By default, text is drawn
below and to the right of the
position specified in a
DrawString command.
10. Rebuild the Lab06Class a. For more information about building and debugging your application,
project, reconstruct the use the following resource:
reference to the class library • The Visual Studio .NET Help documentation. Search by using the
in the Lab06Application phrases Default and Custom Builds and Using the Debugger.
project, and then view the
updated print document by
using Lab06Application.
11. Save your projects, and then Additional information is not necessary for this task.
close Visual Studio .NET.
72 Module 6: Printing and Reporting in Windows Forms Applications
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-2565P
height*, full width
Address Table 25% of available Same as NT-2565P
height*, full width
Purchase Table 62.5% of available Same as NT-2565P
height*, full width
This table is incomplete. The complete Page Layout Table for Forms NT-2565P
and NT-2565L table would contain additional information required to recreate the
NT-2565P and NT-2565L 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 33
Lab 7.1: Making Asynchronous Calls to
an XML Web Service 35
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 2565A_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 2415B,
Programming with the Microsoft .NET Framework (Microsoft
Visual Basic® .NET).
10 Module 7: Asynchronous Programming
Invoke
Invoke the
the BeginOperation
BeginOperation method,
method, passing
passing itit the
the callback delegate
delegate
Inside the
the callback,
callback, invoke
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 End Sub
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
Dim
Dim delCB
delCB As
As New
New AsyncCallback(AddressOf
AsyncCallback(AddressOf __
Me.AsyncCB)
Me.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, Nothing)
Nothing)
Inside
Inside the
the callback,
callback, invoke the
the EndOperation
EndOperation method
method to
to retrieve the
the
results
results of the asynchronous
asynchronous 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
Sub
Sub AsyncCB(ByVal
AsyncCB(ByVal result
result As
As IAsyncResult)
IAsyncResult)
Invoke EndOperation method
...
...
ExpRepDataSet
ExpRepDataSet == WS.EndGetReportsForEmployee(
WS.EndGetReportsForEmployee( __
ar,
ar, TotalNumRecords)
TotalNumRecords)
...
...
End
End Sub
Sub
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 to the main 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
Dim
Dim mi
mi As
As New
New MethodInvoker(Me.UpdateUI)
MethodInvoker(Me.UpdateUI)
'' Use
Use the
the current
current form’s
form’s BeginInvoke
BeginInvoke to
to
'' invoke
invoke the
the delegate
delegate
Me.BeginInvoke(mi)
Me.BeginInvoke(mi)
Me.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
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, _
TotalReports)
7. Find the next TODO comment. Add the code to instantiate a
MethodInvoker delegate that points to the UpdateUI method of this class.
Dim mi As New MethodInvoker(AddressOf Me.UpdateUI)
8. Find the next TODO comment. Add the code to call BeginInvoke on this
form, passing the MethodInvoker delegate created in step 6.
Me.BeginInvoke(mi)
9. Save your files and build the project.
Follow
Follow the
the design pattern for asynchronous programming
Techniques for protecting state and data is covered in the topic How to Protect
State and Data in a Multithreaded Environment.
Module 7: Asynchronous Programming 21
Declare
Declare the
the delegate
delegate
Delegate keyword
The delegate's
Delegate
Delegate Function
Function CalcDelegate
CalcDelegate (( __ signature matches
ByVal
ByVal startingValue As
startingValue As Integer,
Integer, __ that of the method it
ByVal
ByVal interestRate
interestRate As
As Integer)
Integer) __ will point to
As
As Integer
Integer
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
Dim
Dim tr
tr As
As New
New TotalReturnCalc()
TotalReturnCalc()
'' Instantiate
Instantiate the
the delegate,
delegate, passing
passing it
it the
the method
method to
to call
call
Dim
Dim cd
cd As
As 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.
22 Module 7: Asynchronous Programming
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
Dim
Dim ar
ar As
As IAsyncResult
IAsyncResult == cd.BeginInvoke(startVal,
cd.BeginInvoke(startVal, intRate,
intRate, __
cb,
cb, Nothing)
Nothing)
In the code example above, Me 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
BeginInvoke method code example, to the BeginInvoke method as the second to last parameter.
Dim ar As IAsyncResult = cd.BeginInvoke(startVal, intRate, _
cb, Nothing)
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
Sub
Sub ResultsCB(ByVal
ResultsCB(ByVal ar
ar As
As IAsyncResult)
IAsyncResult)
...
...
Dim
Dim result
result As
As Integer
Integer == cd.EndInvoke(ar)
cd.EndInvoke(ar)
...
...
End
End Sub
Sub
Update
Update the UI
UI to reflect the results of the 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
Dim
Dim mi
mi As
As New
New MethodInvoker(Me.UpdateUI)
MethodInvoker(Me.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
Me.BeginInvoke(mi)
Me.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 Basic .NET, the
keyword is SyncLock. This keyword uses the Monitor class to lock the object.
For example, to synchronize access in a static method:
Class Cache
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 2415B, Programming
with the Microsoft .NET Framework (Microsoft Visual Basic® .NET).
30 Module 7: Asynchronous Programming
Lock test:
Start Resource writing (Thread=0) count: 0
Stop Resource writing (Thread=0) count: 1
Start Resource reading (Thread=1)count: 1
Stop Resource reading (Thread=1) count: 1
Start Resource writing (Thread=2) count: 1
Stop Resource writing (Thread=2) count: 2
Start Resource reading (Thread=3)count: 2
Stop Resource reading (Thread=3) count: 2
Start Resource writing (Thread=4) count: 2
Stop Resource writing (Thread=4) count: 3
Start Resource reading (Thread=5)count: 3
Stop Resource reading (Thread=5) count: 3
Start Resource writing (Thread=6) count: 3
Stop Resource writing (Thread=6) count: 4
Start Resource reading (Thread=7)count: 4
Stop Resource reading (Thread=7) count: 4
Start Resource writing (Thread=8) count: 4
Stop Resource writing (Thread=8) count: 5
Start Resource reading (Thread=9)count: 5
Stop Resource reading (Thread=9) count: 5
All Lock threads have completed.
Note that even though 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.
Module 7: Asynchronous Programming 33
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.
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 from only 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 have already been written, and some of the XML Web
service calls have already been 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\2565.
Estimated time to
complete this lab:
15 minutes
Module 7: Asynchronous Programming 37
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 install_folder\ and starting an application, see the following
Labfiles\Lab07_1\Ex01\Starter to find the project resource:
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 five parameters should be the same. service calls in the constructor to asynchronous
calls.
• The sixth parameter should be the callback
delegate. b. For more information about how to make
asynchronous calls, see the following resources:
• The seventh parameter should be Nothing.
• Practice: Making an Asynchronous Call to an
XML Web Service in Module 7,
“Asynchronous Programming,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: The Asynchronous Programming
Model Design Pattern in Module 7,
“Asynchronous Programming,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• The .NET Framework SDK documentation.
For more information about the asynchronous
design pattern, search by using the phrase
Including Asynchronous Calls.
38 Module 7: Asynchronous Programming
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
Step through the code, and make sure it Course 2565A, Developing Microsoft .NET
executes as expected. Applications for Windows (Visual Basic
b. Confirm the correct behavior in the user .NET). This practice contains information
interface by making sure that the expense about how 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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET). This lesson contains information about
the flow of control of an asynchronous call.
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.
Lab: After completing this module, students will be able to:
30 minutes
! Use .NET Framework features to add and enable accessibility features in an
application.
! Add support for context-sensitive Help, Help menus, and ToolTips to an
application.
! Use localization properties and resource files to create a localized version of
a .NET Framework Windows Forms application.
Required materials To teach this module, you need the following materials: Microsoft PowerPoint®
file 2565A_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
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
Me.AppExitButton
Me.AppExitButton == New
New System.Windows.Forms.PushButton()
System.Windows.Forms.PushButton()
Me.AppExitButton.Text
Me.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"
Me.Controls.Add(Me.AppExitButton)
Me.Controls.Add(Me.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 Me keyword in the code refers to the form to which the button is added.
Me.AppExitButton = New System.Windows.Forms.PushButton()
Me.AppExitButton.Text = "E&xit"
AppExitButton.AccessibleRole = _
System.Windows.Forms.AccessibleRole.PushButton
AppExitButton.AccessibleName = "Exit"
AppExitButton.AccessibleDescription = _
"Use this button to exit the application"
Me.Controls.Add(Me.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 (Me,
(Me, 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(Me, HelpProvider.HelpNamespace)
In the previous code:
• The first parameter (Me) 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
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.
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.,
resources you 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 UsabilityDemo 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\culture (for example, UsabilityDemo\bin\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
Imports System.Resources
' provides classes and interfaces
' that allow developers to create, store and
' manage various culture-specific resources
' used in an application
Imports 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 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 Dim rm As 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)
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 2565A, Developing Microsoft .NET Applications
for Windows (Visual Basic .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\2565.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to install_folder\ and starting an application, see the following
Labfiles\Lab08_1\Ex01\Starter to find the 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 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 2565A,
Developing Microsoft .NET Applications for
Windows (Visual Basic .NET).
• Lesson: Adding Accessibility Features in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 2565A,
Procurement Procurement Developing Microsoft .NET Applications for
Exit Exit the Application Windows (Visual Basic .NET).
• Lesson: Adding Accessibility Features in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 2565A,
Developing Microsoft .NET Applications for
Windows (Visual Basic .NET).
• Lesson: Adding Accessibility Features in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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\2565.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to install_folder\ and starting an application, see the following
Labfiles\Lab08_1\Ex02\Starter to find the 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 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 • Practice: Adding Help to an Application in
HelpProvider control to Module 8, “Enhancing the Usability of
InternalBusinessAppHelpProvider. Applications,” in Course 2565A, Developing
b. Set the HelpNamespace property to Microsoft .NET Applications for Windows
http://localhost/ (Visual Basic .NET).
InternalBusinessAppHelp.htm. • Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .NET).
• The .NET Framework SDK documentation.
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 2565A, Developing
HelpKeyword IBA_ControlPanel Microsoft .NET Applications for Windows
HelpNavigator Topic (Visual Basic .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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 2565A, Developing
Property Value Microsoft .NET Applications for Windows
(Visual Basic .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 2565A, Developing
b. Expense Reporting control Microsoft .NET Applications for Windows
(Visual Basic .NET).
Property Value
• The .NET Framework SDK documentation.
HelpKeyword IBA_Expense In Search, select the Search in titles only
HelpNavigator Topic check box, then search by using the phrase
HelpString Log expenses for Introduction to the Windows Forms
reimbursement. HelpProvider.
c. Procurement control
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.
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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .NET).
• Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .NET).
• Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 in the Designer, 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
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\2565.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to install_folder\ and starting an application, see the following
Labfiles\Lab08_1\Ex03\Starter to find the 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 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 2565A, Developing
control to ApplicationToolTip. Microsoft .NET Applications for Windows
(Visual Basic .NET).
• Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 • Practice: Adding ToolTips to an Application
the ToolTip on ApplicationToolTip in Module 8, “Enhancing the Usability of
property for each control. Applications,” in Course 2565A, Developing
Control Value Microsoft .NET Applications for Windows
(Visual Basic .NET).
Form Accesses internal
applications. • Lesson: Adding Help to an Application in
Module 8, “Enhancing the Usability of
Make Travel Plans Allows you to plan a Applications,” in Course 2565A, Developing
business trip. Microsoft .NET Applications for Windows
Expense Reporting Allows you to submit and (Visual Basic .NET).
check expense reports. • The .NET Framework SDK documentation.
Procurement Allows you to purchase Search by using the phrase ToolTip
items at company rates. Component.
Exit Exit the application.
Status bar Displays the network
connection status.
4. Run the application to test the ToolTips. 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 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 the
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\2565.
1. Open the InternalBusinessApp project in a. For more information about opening a project file
Visual Studio .NET. Browse to install_folder\ and starting an application, see the following
Labfiles\Lab08_1\Ex04\Starter to find the 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 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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
Form Tableau de bord .NET).
des applications
• Lesson: Localizing an Application in Module
HelpMenu Aide 8, “Enhancing the Usability of Applications,”
HelpMenuItem Aide in Course 2565A, Developing Microsoft .NET
AboutMenuItem À propos de l’application Applications for Windows (Visual Basic
interne d’entreprise .NET).
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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.NET).
• Lesson: Localizing an Application in Module
8, “Enhancing the Usability of Applications,”
in Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic
.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 the 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\2565.
1. Open the InternalBusinessApp project in a. For more information about opening a project
Visual Studio .NET. Browse to install_folder\ file, see the following resource:
Labfiles\Lab08_1\Ex05\Starter to find the project. • The Visual Studio.NET Help documentation.
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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .NET).
• Lesson: Localizing an Application in
Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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
Name Value Module 8, “Enhancing the Usability of
Applications,” in Course 2565A, Developing
AppUnavailable Application non disponible Microsoft .NET Applications for Windows
Message (Visual Basic .NET).
PermissionDenied Autorisation refusée • Lesson: Localizing an Application in
Message Module 8, “Enhancing the Usability of
Unauthorized Vous ne disposez pas des Applications,” in Course 2565A, Developing
Message autorisations nécessaires Microsoft .NET Applications for Windows
pour utiliser cette (Visual Basic .NET).
application • The .NET Framework SDK documentation.
OfflineMode Mode hors connexion Search by using the phrase Developing
OnlineMode Mode connexion World-Ready Applications.
Course Evaluation
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 2565A_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
Dim
Dim PrivateAssembly
PrivateAssembly As
As [Assembly]
[Assembly]
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.
Dim
Dim Method
Method As
As MethodInfo
MethodInfo == __
PrivateAssembly.GetTypes(0).GetMethod("CalculateSum")
PrivateAssembly.GetTypes(0).GetMethod("CalculateSum")
Where private When the common language runtime searches for a private assembly, it uses the
assemblies can reside assembly’s simple name to locate the referenced assembly.
When the application is installed, the private assembly is also installed in the
same root directory of the application, or in a subdirectory that appears under
the root directory of the application.
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 Imports System.Reflection. The following code demonstrates
how to call LoadFrom():
Dim PrivateAssembly As [Assembly]
PrivateAssembly = Assembly.LoadFrom("C:\PrivateAssembly.dll")
' Obtain a reference to a method known to exist in assembly.
Dim Method As MethodInfo = _
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.
Module 9: Deploying Windows Forms Applications 7
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.
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) when the integrity/security validation
occurs. 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 runtime.
8 Module 9: Deploying Windows Forms Applications
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.
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 within 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):
Imports 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.
Instructions
! To add ILDASM to the Visual Studio .NET environment
1. Start Visual Studio .NET.
2. From the Tools menu, select External Tools.
3. In the External Tools dialog box, click Add.
4. In the Title box type, MSIL Disassembler.
5. Click the … button to the right of the Command field.
6. In the Open File dialog box, browse to C:\Program Files\
Microsoft Visual Studio .NET\FrameworkSDK\bin.
7. Select ildasm.exe and click Open.
8. On the External Tools dialog box, click OK.
9. View the Tools menu again and notice that a menu item for MSIL
Disassembler is now available.
14 Module 9: Deploying Windows Forms Applications
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.vb source file.
10. Locate the TODO comment. Change the versionInfo string from v2.0.1.1 to
v3.0.1.1.
Private Shared versionInfo As String = _
"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.
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 GACUtil.exe GACUtil.exe is a command line utility that allows you to view and manipulate
the contents of the global assembly cache. GACUtil.exe options include:
! /i or –i: installs a strong-named assembly into the global assembly cache.
! /l or –l: lists the contents of the global assembly cache.
! /u or –u: removes one or more assemblies from the global assembly cache.
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.
Module 9: Deploying Windows Forms Applications 19
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.
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, in Module 9,
“Deploying Windows Forms Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Microsoft Windows (Visual Basic .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.
22 Module 9: Deploying Windows Forms Applications
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
! 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
Packaging Options This table compares packaging options available for .NET applications.
Packaging Option Description Comments
Executables and DLLs A set of executables and DLLs in No packaging is required with .NET applications
the original folder hierarchy in and assemblies. You can use the EXE and DLL
which the application was built. 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 Windows installing applications that run on the desktop.
Installer. Other applications can also be deployed by using
.msi files. For example, Microsoft ASP.NET
applications can be packaged in an .msi file.
Cabinet Files Use Visual Studio .NET to create The following restrictions apply when creating the
cabinet (.cab) files for deployment .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.
• After you have created a .cab file, it can be
downloaded by specifying its location by
using the <codeBase> element in one of the
configuration files.
Deployment Options This table compares the deployment options available for .NET applications.
Deployment Option Description Comments
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
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\2565.
1. Open the ExpenseReport project in Visual Studio a. For more information about opening a project
.NET. Browse to install_folder\Labfiles\ file, see the following resource:
Lab09_1\Ex01\Starter\ExpenseReportApp to find • The Visual Studio .NET Help documentation.
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 2565A,
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.
Module 9: Deploying Windows Forms Applications 51
6. Open a Visual Studio .NET Command Prompt a. For more information about how to open a
window and change directories to the location of Visual Studio .NET Command Prompt window,
InternalBusinessApp.exe. Browse to see the following resource:
install_folder\Labfiles\Lab09_1\Ex01\Starter\ • Practice: Calling a Strong-Named Assembly
Business Application Shell\bin to find the in Module 9, “Deploying Windows Forms
executable. Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
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 2565A, 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 2565A, 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.
52 Module 9: Deploying Windows Forms Applications
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 in Module 9, “Deploying Windows Forms
file. Applications,” in Course 2565A, Developing
b. Rebuild the ExpenseReport project. 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 2565A, 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 • The .NET Framework SDK documentation.
now includes a public key token. Search by using the phrase MSIL
Disassembler (Ildasm.exe).
Module 9: Deploying Windows Forms Applications 53
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\2565.
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 to find the DLL. .NET, see the following resource:
• Practice: Working with the Global Assembly
Cache in Module 9, “Deploying Windows
Forms Applications,” in Course 2565A,
Developing Microsoft .NET Applications for
Windows (Visual C# .NET).
54 Module 9: Deploying Windows Forms Applications
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
bin folder of the Internal Business
Application.
b. Build the Internal Business Application.
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 to find the in Module 9, “Deploying Windows Forms
file. Applications,” in Course 2565A, 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:
a. 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 2565A,
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
window and change directories to the location Visual Studio .NET Command Prompt window,
where InternalBusinessApp.exe is located. see the following resource:
Browse to install_folder\Labfiles\Lab09_1\ • Practice: Calling a Strong-Named Assembly
Ex02\Starter\Business Application Shell\bin to in Module 9, “Deploying Windows Forms
find the executable file. Applications,” in Course 2565A, 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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual C# .NET).
• The .NET Framework SDK documentation.
Search by using the phrase MSIL
Disassembler (Ildasm.exe).
Module 9: Deploying Windows Forms Applications 55
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.
There are solution files associated with this exercise. Browse to install_folder\Labfiles\Lab09_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\2565.
1. Open the InternalBusinessApp project in Visual a. For more information about opening a project
Studio .NET. Browse to install_folder\Labfiles\ file, see the following resource:
Lab09_1\Ex03\Starter\Business Application Shell • The Visual Studio .NET Help documentation.
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 InternalBusinessApp project. Close the a. For more information about building an
InternalBusinessApp solution, but keep application, see the following resource:
Visual 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 • The How to Create and Use a Windows
InternalBusinessApplication. Installer Setup Project topic in Module 9,
• Set the project location to “Deploying Windows Forms Applications,”
install_folder\Labfiles\Lab09_1\ in Course 2565A, Developing Microsoft .NET
Ex03\Starter. Applications for Windows (Visual C# .NET).
56 Module 9: Deploying Windows Forms Applications
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 2565A, 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
2565A, 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, in Course 2565A, Developing Microsoft .NET
and ja-JP. 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
2565A, 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 to find the Applications in Module 9, “Deploying
InternalBusinessApp.exe file. Windows Forms Applications,” in
Course 2565A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
Module 9: Deploying Windows Forms Applications 57
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 2565A, 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 2565A, 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 to find the folders that contain the
localized resource files.
The localized resource files are named
InternalBusinessApp.resources.dll and can be
found in the folders named de, de-DE, en, en-US,
fr, fr-FR, ja, and ja-JP under install_folder\
Labfiles\Lab09_1\Ex03\Starter\
Business Application Shell\bin.
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
2565A, 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.
58 Module 9: Deploying Windows Forms Applications
10. Set the following project properties. No additional information is necessary for this task.
Property Value
Author Contoso, Ltd.
Manufacturer Contoso, Ltd.
ProductName International Business
Application
Title International 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 2565A, 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 2565A, 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 2565A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Deploying Applications.
Module 9: Deploying Windows Forms Applications 59
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\2565.
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
ExpenseReport.dll file. Course 2565A, 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 2565A, 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 2565A, 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 2565A, Developing Microsoft .NET
Applications for Windows (Visual C# .NET).
• The .NET Framework SDK. Search by using
the phrase Configuration Files.
3. Run the application. No additional information is necessary for this task.
• Verify that the application still runs with the
new version of ExpenseReport.dll.
This page intentionally left blank.
Module 10: Securing
Windows Forms
Applications
Contents
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 2565A_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
What is Authentication? This topic defines authentication and provides some examples of authentication
authorities.
What is Authorization? This topic defines authorization. Emphasize to students that there is an order
relationship here: authentication is first, then authorization.
Module 10: Securing Windows Forms Applications v
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
! 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
same security
security check
check
for
for assembly
assembly for
for all
all security
security policy
policy levels
levels
Policy Levels
Assign
Assign 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.
! 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 to
to 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:=UIPermissionWindow.SafeTopLevelWindows)>
Window:=UIPermissionWindow.SafeTopLevelWindows)>
'' Request
Request for
for aa permission
permission set
set
<Assembly:PermissionSet(
<Assembly:PermissionSet( __
SecurityAction.RequestMinimum,
SecurityAction.RequestMinimum, __
Name:="LocalIntranet")>
Name:="LocalIntranet")>
Procedure: Making To better document your code, place your assembly permission requests in the
assembly permission AssemblyInfo source file.
requests
1. Open the AssemblyInfo.vb source file for the appropriate project and add
attributes for permission requests. Be sure to include the assembly scope
qualifier to the request, as in the following examples:
Example: Assembly ' Add attributes to the AssemblyInfo source file
permission request ' Request for a specific permission
attributes <Assembly:UIPermission( _
SecurityAction.RequestMinimum, _
Window:=UIPermissionWindow.SafeTopLevelWindows)>
Try
' open a file for reading
fs = New FileStream("C:\log.txt", _
FileMode.Open, _
FileAccess.Read)
' read from file
…
Catch se As SecurityException
' display error message
MessageBox.Show("ExceptionMessage: " + se.Message)
End Try
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
that appears 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
(continued)
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
3. To list permission sets, in the Visual Studio .NET Command Prompt
window type the following command:
Caspol –lp
4. To reset the current policy level to default security policy, in the
Visual Studio .NET Command Prompt window type the following
command:
Caspol –reset
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.
Module 10: Securing Windows Forms Applications 25
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
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
Identities An identity object encapsulates information about the user or entity being
validated, such as the user name and authentication type. The .NET Framework
provides three kinds of identity objects:
! Windows identity
Represents the identity of the user based on a method of authentication that
is supported by the Windows operating system. A Windows identity
provides the ability to impersonate another user, so resources can be
accessed on behalf of that other user. The WindowsIdentity class
implements this kind of identity.
! Generic identity
Represents the identity of the user based on a custom authentication method,
which is defined by the application. The GenericIdentity class implements
this kind of identity.
! 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
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 shared 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.
Dim Name As String = MyPrincipal.Identity.Name
Dim Type As String = _
MyPrincipal.Identity.AuthenticationType
Dim Auth As String = _
MyPrincipal.Identity.IsAuthenticated.ToString()
'Identity values.
Dim IdentName As String = MyIdentity.Name
Dim IdentType As String = MyIdentity.AuthenticationType
Dim IdentIsAuth As String = _
MyIdentity.IsAuthenticated.ToString()
Dim ISAnon As String = MyIdentity.IsAnonymous.ToString()
Dim IsG As String = MyIdentity.IsGuest.ToString()
Dim IsSys As String = MyIdentity.IsSystem.ToString()
Dim Token As String = MyIdentity.Token.ToString()
…
End Sub
End Class
Module 10: Securing Windows Forms Applications 35
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.
38 Module 10: Securing Windows Forms Applications
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")
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.
Module 10: Securing Windows Forms Applications 41
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 b 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 2565A, Developing Microsoft .NET
Applications for Windows (Visual Basic .NET). As a result, this lab may not
comply with Microsoft security recommendations.
Scenario To follow best practices, you want to document the permissions that your
application requires and to run it with the fewest privileges possible. To do this
with the .NET Framework security system, you will use permission requests.
This will also help you to configure the security policy if you decide to deploy
your application in other security contexts.
In this lab, you will add minimum permission requests for the permissions that
you need and an optional permission request for no permissions to prevent any
additional permissions from being granted to your application.
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\2565.
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 install_folder\ and starting an application, see the following
Labfiles\Lab10_1\Ex01\Starter to find the project resource:
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.vb 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 2565A, Developing
and user. Use the following syntax (this Microsoft .NET Applications for Windows
attribute should appear on a single line—line (Visual Basic .NET). This practice contains
continuation marks have been omitted for information about how to add the minimum
space reasons): permission request for the use of all windows
and the optional permission request for no
<Assembly: permissions.
IsolatedStorageFilePermission(
SecurityAction.RequestMinimum, • Lesson: Using Code Access Security in
UsageAllowed:=IsolatedStorageContai Module 10, “Securing Windows Forms
nment.DomainIsolationByUser)> Applications,” in Course 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .NET). This lesson contains
• Use of Web access for the Expense Report information about how to make permission
Web service. Use the following syntax (this requests.
attribute should appear on a single line—line
continuation marks have been omitted for • The .NET Framework SDK documentation.
space reasons): In Search, select the Search in titles only
check box, then search by using the phrase
<Assembly: WebPermission( Requesting Permissions.
SecurityAction.RequestMinimum,
Connect:="http://localhost/ExpenseR
eportWebService/
ExpenseReportWebService.asmx")>
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 2565A, Developing
Microsoft .NET Applications for Windows
(Visual Basic .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 15
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 using GDI+. Students learn how to use solid, hatch, texture, linear
gradient, path gradient, and transparent brushes to fill shapes. They will also
Lab: learn how to load, skew, rotate, reflect, crop, and scale images.
00 minutes
After completing this appendix, 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
2565A_XA.ppt.
Preparation tasks To prepare for this module:
! Read all of the materials for this module.
! 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 last line of the code example statement
fills the ellipse with repeated copies of the image.
Dim imageFileName As String = "C:\Images\Image01.jpg"
Dim brushImage = New Bitmap(imageFileName)
Dim myImageBrush As New TextureBrush(brushImage)
e.Graphics.FillEllipse(myImageBrush, 0, 0, 120, 40)
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
…
Dim myHatchBrush = New HatchBrush( _
HatchStyle.Horizontal, Color.Red, Color.Cyan)
e.Graphics.FillEllipse(myHatchBrush, 0, 200, 120, 40)
6 Appendix A: Using Filled Shapes and Images
Dim
Dim rect
rect As
As Rectangle
Rectangle == New
New Rectangle(
Rectangle( __
hPos,
hPos, vPos,
vPos, txtWidth,
txtWidth, txtHeight)
txtHeight)
Dim
Dim myBrush
myBrush As
As LinearGradientBrush
LinearGradientBrush == New
New __
LinearGradientBrush(rect,
LinearGradientBrush(rect, Color.SeaGreen,
Color.SeaGreen, __
Color.BlueViolet,
Color.BlueViolet, LinearGradientMode.Horizontal)
LinearGradientMode.Horizontal)
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.
Dim rect As Rectangle = New Rectangle( _
hPos, vPos, txtWidth, txtHeight)
Dim myBrush As LinearGradientBrush = 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.
Appendix A: Using Filled Shapes and Images 9
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.
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.
Dim path As 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.
Dim bitmap As New Bitmap(imageFileName)
e.Graphics.DrawImage(bitmap, 50, 50, bitmap.Width, _
bitmap.Height)
____________________________________________________________
! 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.
Appendix A: Using Filled Shapes and Images 15
! 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
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
Dim
Dim fileName
fileName As
As String
String == Application.StartupPath
Application.StartupPath __
&& "\WinForms.jpg"
"\WinForms.jpg"
Dim
Dim fileImage
fileImage As
As New
New Bitmap(fileName)
Bitmap(fileName)
Dim
Dim pThumbnail
pThumbnail As
As Image
Image == __
fileImage.GetThumbnailImage(
fileImage.GetThumbnailImage( __
fileImage.Width
fileImage.Width // 6,
6, __
fileImage.Height
fileImage.Height // 6,
6, __
Nothing,
Nothing, New
New IntPtr())
IntPtr())
e.Graphics.DrawImage(pThumbnail,
e.Graphics.DrawImage(pThumbnail, 100,
100, 100,
100, __
pThumbnail.Width,
pThumbnail.Width, pThumbnail.Height)
pThumbnail.Height)