Professional Documents
Culture Documents
20483A ENU TrainerHandbook
20483A ENU TrainerHandbook
20483A
Programming in Visual C#
MCT USE ONLY. STUDENT USE PROHIBITED
ii Programming in Visual C#
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 manufacturers, products, or URLs are provided for informational purposes only and
Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding
these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a
manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links
may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not
responsible for the contents of any linked site or any link contained in a linked site, or any changes or
updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission
received from any linked site. Microsoft is providing these links to you only as a convenience, and the
inclusion of any link does not imply endorsement of Microsoft of the site or the products contained
therein.
2012 Microsoft Corporation. All rights reserved.
Released: xx/20xx
MCT USE ONLY. STUDENT USE PROHIBITED
MICROSOFT LICENSE TERMS
OFFICIAL MICROSOFT LEARNING PRODUCTS
MICROSOFT OFFICIAL COURSE Pre-Release and Final Release Versions
These license terms are an agreement between Microsoft Corporation and you. Please read them. They apply to
the Licensed Content named above, which includes the media on which you received it, if any. These license
terms also apply to any updates, supplements, internet based services and support services for the Licensed
Content, unless other terms accompany those items. If so, those terms apply.
BY DOWNLOADING OR USING THE LICENSED CONTENT, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT
THEM, DO NOT DOWNLOAD OR USE THE LICENSED CONTENT.
If you comply with these license terms, you have the rights below.
1. DEFINITIONS.
a. Authorized Learning Center means a Microsoft Learning Competency Member, Microsoft IT Academy
Program Member, or such other entity as Microsoft may designate from time to time.
b. Authorized Training Session means the Microsoft-authorized instructor-led training class using only
MOC Courses that are conducted by a MCT at or through an Authorized Learning Center.
c. Classroom Device means one (1) dedicated, secure computer that you own or control that meets or
exceeds the hardware level specified for the particular MOC Course located at your training facilities or
primary business location.
d. End User means an individual who is (i) duly enrolled for an Authorized Training Session or Private
Training Session, (ii) an employee of a MPN Member, or (iii) a Microsoft full-time employee.
e. Licensed Content means the MOC Course and any other content accompanying this agreement.
Licensed Content may include (i) Trainer Content, (ii) software, and (iii) associated media.
f. Microsoft Certified Trainer or MCT means an individual who is (i) engaged to teach a training session
to End Users on behalf of an Authorized Learning Center or MPN Member, (ii) currently certified as a
Microsoft Certified Trainer under the Microsoft Certification Program, and (iii) holds a Microsoft
Certification in the technology that is the subject of the training session.
g. Microsoft IT Academy Member means a current, active member of the Microsoft IT Academy
Program.
h. Microsoft Learning Competency Member means a Microsoft Partner Network Program Member in
good standing that currently holds the Learning Competency status.
i. Microsoft Official Course or MOC Course means the Official Microsoft Learning Product instructor-
led courseware that educates IT professionals or developers on Microsoft technologies.
MCT USE ONLY. STUDENT USE PROHIBITED
j. Microsoft Partner Network Member or MPN Member means a silver or gold-level Microsoft Partner
Network program member in good standing.
k. Personal Device means one (1) device, workstation or other digital electronic device that you
personally own or control that meets or exceeds the hardware level specified for the particular MOC
Course.
l. Private Training Session means the instructor-led training classes provided by MPN Members for
corporate customers to teach a predefined learning objective. These classes are not advertised or
promoted to the general public and class attendance is restricted to individuals employed by or
contracted by the corporate customer.
m. Trainer Content means the trainer version of the MOC Course and additional content designated
solely for trainers to use to teach a training session using a MOC Course. Trainer Content may include
Microsoft PowerPoint presentations, instructor notes, lab setup guide, demonstration guides, beta
feedback form and trainer preparation guide for the MOC Course. To clarify, Trainer Content does not
include virtual hard disks or virtual machines.
2. INSTALLATION AND USE RIGHTS. The Licensed Content is licensed not sold. The Licensed Content is
licensed on a one copy per user basis, such that you must acquire a license for each individual that
accesses or uses the Licensed Content.
2.1 Below are four separate sets of installation and use rights. Only one set of rights apply to you.
ii. Use of Instructional Components in Trainer Content. You may customize, in accordance with the
most recent version of the MCT Agreement, those portions of the Trainer Content that are logically
associated with instruction of a training session. If you elect to exercise the foregoing rights, you
agree: (a) that any of these customizations will only be used for providing a training session, (b) any
customizations will comply with the terms and conditions for Modified Training Sessions and
Supplemental Materials in the most recent version of the MCT agreement and with this agreement.
For clarity, any use of customize refers only to changing the order of slides and content, and/or
not using all the slides or content, it does not mean changing or modifying any slide or content.
2.2 Separation of Components. The Licensed Content components are licensed as a single unit and you
may not separate the components and install them on different devices.
2.4 Third Party Programs. The Licensed Content may contain third party programs or services. These
license terms will apply to your use of those third party programs or services, unless other terms accompany
those programs and services.
2.5 Additional Terms. Some Licensed Content may contain components with additional terms,
conditions, and licenses regarding its use. Any non-conflicting terms in those conditions and licenses also
apply to that respective component and supplements the terms described in this Agreement.
3. PRE-RELEASE VERSIONS. If the Licensed Content is a pre-release (beta) version, in addition to the other
provisions in this agreement, then these terms also apply:
a. Pre-Release Licensed Content. This Licensed Content is a pre-release version. It may not contain the
same information and/or work the way a final version of the Licensed Content will. We may change it
for the final version. We also may not release a final version. Microsoft is under no obligation to
provide you with any further content, including the final release version of the Licensed Content.
b. Feedback. If you agree to give feedback about the Licensed Content to Microsoft, either directly or
through its third party designee, you give to Microsoft without charge, the right to use, share and
commercialize your feedback in any way and for any purpose. You also give to third parties, without
charge, any patent rights needed for their products, technologies and services to use or interface with
any specific parts of a Microsoft software, Microsoft product, or service that includes the feedback. You
will not give feedback that is subject to a license that requires Microsoft to license its software,
technologies, or products to third parties because we include your feedback in them. These rights
MCT USE ONLY. STUDENT USE PROHIBITED
survive this agreement.
c. Term. If you are an Authorized Training Center, MCT or MPN, you agree to cease using all copies of the
beta version of the Licensed Content upon (i) the date which Microsoft informs you is the end date for
using the beta version, or (ii) sixty (60) days after the commercial release of the Licensed Content,
whichever is earliest (beta term). Upon expiration or termination of the beta term, you will
irretrievably delete and destroy all copies of same in the possession or under your control.
4. INTERNET-BASED SERVICES. Microsoft may provide Internet-based services with the Licensed Content,
which may change or be canceled at any time.
a. Consent for Internet-Based Services. The Licensed Content may connect to computer systems over an
Internet-based wireless network. In some cases, you will not receive a separate notice when they
connect. Using the Licensed Content operates as your consent to the transmission of standard device
information (including but not limited to technical information about your device, system and
application software, and peripherals) for internet-based services.
b. Misuse of Internet-based Services. You may not use any Internet-based service in any way that could
harm it or impair anyone elses use of it. You may not use the service to try to gain unauthorized access
to any service, data, account or network by any means.
5. SCOPE OF LICENSE. The Licensed Content is licensed, not sold. This agreement only gives you some rights
to use the Licensed Content. Microsoft reserves all other rights. Unless applicable law gives you more
rights despite this limitation, you may use the Licensed Content only as expressly permitted in this
agreement. In doing so, you must comply with any technical limitations in the Licensed Content that only
allows you to use it in certain ways. Except as expressly permitted in this agreement, you may not:
install more copies of the Licensed Content on devices than the number of licenses you acquired;
allow more individuals to access the Licensed Content than the number of licenses you acquired;
publicly display, or make the Licensed Content available for others to access or use;
install, sell, publish, transmit, encumber, pledge, lend, copy, adapt, link to, post, rent, lease or lend,
make available or distribute the Licensed Content to any third party, except as expressly permitted
by this Agreement.
reverse engineer, decompile, remove or otherwise thwart any protections or disassemble the
Licensed Content except and only to the extent that applicable law expressly permits, despite this
limitation;
access or use any Licensed Content for which you are not providing a training session to End Users
using the Licensed Content;
access or use any Licensed Content that you have not been authorized by Microsoft to access and
use; or
transfer the Licensed Content, in whole or in part, or assign this agreement to any third party.
6. RESERVATION OF RIGHTS AND OWNERSHIP. Microsoft reserves all rights not expressly granted to you in
this agreement. The Licensed Content is protected by copyright and other intellectual property laws and
treaties. Microsoft or its suppliers own the title, copyright, and other intellectual property rights in the
Licensed Content. You may not remove or obscure any copyright, trademark or patent notices that
appear on the Licensed Content or any components thereof, as delivered to you.
MCT USE ONLY. STUDENT USE PROHIBITED
7. EXPORT RESTRICTIONS. The Licensed Content is subject to United States export laws and regulations. You
must comply with all domestic and international export laws and regulations that apply to the Licensed
Content. These laws include restrictions on destinations, End Users and end use. For additional
information, see www.microsoft.com/exporting.
8. LIMITATIONS ON SALE, RENTAL, ETC. AND CERTAIN ASSIGNMENTS. You may not sell, rent, lease, lend or
sublicense the Licensed Content or any portion thereof, or transfer or assign this agreement.
9. SUPPORT SERVICES. Because the Licensed Content is as is, we may not provide support services for it.
10. TERMINATION. Without prejudice to any other rights, Microsoft may terminate this agreement if you fail
to comply with the terms and conditions of this agreement. Upon any termination of this agreement, you
agree to immediately stop all use of and to irretrievable delete and destroy all copies of the Licensed
Content in your possession or under your control.
11. LINKS TO THIRD PARTY SITES. You may link to third party sites through the use of the Licensed Content.
The third party sites are not under the control of Microsoft, and Microsoft is not responsible for the
contents of any third party sites, any links contained in third party sites, or any changes or updates to third
party sites. Microsoft is not responsible for webcasting or any other form of transmission received from
any third party sites. Microsoft is providing these links to third party sites to you only as a convenience,
and the inclusion of any link does not imply an endorsement by Microsoft of the third party site.
12. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates and support services are
the entire agreement for the Licensed Content.
b. Outside the United States. If you acquired the Licensed Content in any other country, the laws of that
country apply.
14. LEGAL EFFECT. This agreement describes certain legal rights. You may have other rights under the laws of
your country. You may also have rights with respect to the party from whom you acquired the Licensed
Content. This agreement does not change your rights under the laws of your country if the laws of your
country do not permit it to do so.
15. DISCLAIMER OF WARRANTY. THE LICENSED CONTENT IS LICENSED "AS-IS," "WITH ALL FAULTS," AND "AS
AVAILABLE." YOU BEAR THE RISK OF USING IT. MICROSOFT CORPORATION AND ITS RESPECTIVE
AFFILIATES GIVE NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS UNDER OR IN RELATION TO
THE LICENSED CONTENT. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS UNDER YOUR LOCAL LAWS
WHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS,
MICROSOFT CORPORATION AND ITS RESPECTIVE AFFILIATES EXCLUDE ANY IMPLIED WARRANTIES OR
CONDITIONS, INCLUDING THOSE OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT.
MCT USE ONLY. STUDENT USE PROHIBITED
16. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. TO THE EXTENT NOT PROHIBITED BY
LAW, YOU CAN RECOVER FROM MICROSOFT CORPORATION AND ITS SUPPLIERS ONLY DIRECT
DAMAGES UP TO USD$5.00. YOU AGREE NOT TO SEEK TO RECOVER ANY OTHER DAMAGES, INCLUDING
CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES FROM MICROSOFT
CORPORATION AND ITS RESPECTIVE SUPPLIERS.
It also applies even if Microsoft knew or should have known about the possibility of the damages. The
above limitation or exclusion may not apply to you because your country may not allow the exclusion or
limitation of incidental, consequential or other damages.
Please note: As this Licensed Content is distributed in Quebec, Canada, some of the clauses in this agreement
are provided below in French.
Remarque : Ce le contenu sous licence tant distribu au Qubec, Canada, certaines des clauses dans ce
contrat sont fournies ci-dessous en franais.
EXONRATION DE GARANTIE. Le contenu sous licence vis par une licence est offert tel quel . Toute
utilisation de ce contenu sous licence est votre seule risque et pril. Microsoft naccorde aucune autre garantie
expresse. Vous pouvez bnficier de droits additionnels en vertu du droit local sur la protection dues
consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties
implicites de qualit marchande, dadquation un usage particulier et dabsence de contrefaon sont exclues.
Elle sapplique galement, mme si Microsoft connaissait ou devrait connatre lventualit dun tel dommage.
Si votre pays nautorise pas lexclusion ou la limitation de responsabilit pour les dommages indirects,
accessoires ou de quelque nature que ce soit, il se peut que la limitation ou lexclusion ci-dessus ne sappliquera
pas votre gard.
EFFET JURIDIQUE. Le prsent contrat dcrit certains droits juridiques. Vous pourriez avoir dautres droits prvus
par les lois de votre pays. Le prsent contrat ne modifie pas les droits que vous confrent les lois de votre pays
si celles-ci ne le permettent pas.
Acknowledgments
Microsoft Learning wants to acknowledge and thank the following for their contribution toward
developing this title. Their effort at various stages in the development has ensured that you have a good
classroom experience.
Contents
Module 1: Review of Visual C# Syntax
Lesson 1: Overview of Writing Applications by Using Visual C# page 3
Lesson 2: Data Types, Operators, and Expressions page 11
Lesson 3: Visual C# Programming Language Constructs page 25
Lab: Developing the Class Enrollment Application page 38
Course Description
Note: This first release (A) MOC version of course 20483A has been developed on RTM software.
Microsoft Learning will release a B version of this course with enhanced PowerPoint slides, copy-
edited content, and Course Companion content on Microsoft Learning site.
This training course teaches developers the programming skills that are required for developers to create
Windows applications using the Visual C# language. During their five days in the classroom students
review the basics of Visual C# program structure, language syntax, and implementation details, and then
consolidate their knowledge throughout the week as they build an application that incorporates several
features of the .NET Framework 4.5.
Audience
This course is intended for experienced developers who already have programming experience in C, C++,
JavaScript, Objective-C, Microsoft Visual Basic, or Java and understand the concepts of object-oriented
programming.
The developers targeted by this training are professional developers who have 3-6 months of experience
creating software applications for a production environment and who have a basic understanding of
Windows client application development. Students should have a minimum of the following experience:
3 months of experience creating .NET Framework applications.
This course is not designed for students who are new to programming; it is targeted at professional
developers with at least one month of experience programming in an object-oriented environment.
Student Prerequisites
Before attending this course, students must have at least three months professional development
experience.
Additionally, developers attending this should already have gained some limited experience using Visual
C# to complete basic programming tasks. More specifically, students should have hands-on experience
using Visual C# that demonstrates their understanding of the following:
How to name, declare, initialize and assign values to variables within an application.
How to use:
How to create the code syntax for simple programming statements using Visual C# language
keywords and recognize syntax errors by using the Visual Studio IDE.
MCT USE ONLY. STUDENT USE PROHIBITED
ii About This Course
How to create a simple looping structure using a for statement to iterate through a data array.
How to use the Visual Studio IDE to locate simple logic errors.
How to create a method that accepts arguments and returns a value of a specified type.
How to design and build a simple user interface by using standard controls from the Visual
Studio toolbox.
How to connect to a SQL Server database and the basics of how to retrieve and store data.
Course Objectives
After completing this course, students will be able to:
Create methods, handle exceptions, and describe the monitoring requirements of large-scale
applications.
Implement the basic structure and essential elements of a typical desktop application.
Create classes, define and implement interfaces, and create and use generic collections.
Use inheritance to create a class hierarchy and to extend a .NET Framework class.
Read and write data by using file input/output and streams, and serialize and deserialize data in
different formats.
Create and use an entity data model for accessing a database and use LINQ to query data.
Access and query remote data by using the types in the System.Net namespace and WCF Data
Services.
Build a graphical user interface by using XAML.
Improve the throughput and response time of applications by using tasks and asynchronous
operations.
Integrate unmanaged libraries and dynamic components into a Visual C# application.
Examine the metadata of types by using reflection, create and use custom attributes, generate
code at runtime, and manage assembly versions.
Encrypt and decrypt data by using symmetric and asymmetric encryption.
Course Outline
The course outline is as follows:
Course Materials
The following materials are included with your kit:
Course Handbook: a succinct classroom learning guide that provides the critical technical
information in a crisp, tightly-focused format, which is essential for an effective in-class learning
experience.
Lessons: guide you through the learning objectives and provide the key points that are critical to
the success of the in-class learning experience.
Labs: provide a real-world, hands-on platform for you to apply the knowledge and skills learned
in the module.
Module Reviews and Takeaways: provide on-the-job reference material to boost knowledge
and skills retention.
Modules: include companion content, such as questions and answers, detailed demo steps and
additional reading links, for each lesson. Additionally, they include Lab Review questions and
answers and Module Reviews and Takeaways sections, which contain the review questions and
answers, best practices, common issues and troubleshooting tips with answers, and real-world
issues and scenarios with answers.
Resources: include well-categorized additional resources that give you immediate access to the
most current premium content on TechNet, MSDN, or Microsoft Press.
Note: For this version of the Courseware on Prerelease Software, Companion Content is not
available. However, the Companion Content will be published when the next (B) version of this
course is released, and students who have taken this course will be able to download the
Companion Content at that time from the
http://www.microsoft.com/learning/companionmoc site. Please check with your instructor
when the B version of this course is scheduled to release to learn when you can access
Companion Content for this course.
Student Course files: includes the Allfiles.exe, a self-extracting executable file that contains all
MCT USE ONLY. STUDENT USE PROHIBITED
iv About This Course
Note: For this version of the Courseware on Prerelease Software, Allfiles.exe file is not available.
However, this file will be published when the next (B) version of this course is released, and students
who have taken this course will be able to download the Allfiles.exe at that time from the
http://www.microsoft.com/learning/companionmoc site.
Course evaluation: at the end of the course, you will have the opportunity to complete an online
evaluation to provide feedback on the course, training facility, and instructor.
Important: At the end of each lab, you must close the virtual machine and must not save
any changes. To close a virtual machine (VM) without saving the changes, perform the
following steps:
2. In the Close dialog box, in the What do you want the virtual machine to do? list, click
Turn off and delete changes, and then click OK.
The following table shows the role of each virtual machine that is used in this course:
Software Configuration
The following software is installed on each VM:
Microsoft Windows 8 Enterprise
Course Files
The files associated with the labs in this course are located in the E:\Labfiles folder on each virtual
machine.
Classroom Setup
Each classroom computer will have the same virtual machines configured in the same way.
Hardware Level 6+
Module 1
Review of Visual C# Syntax
Contents:
Module Overview 1-2
Modu
ule Ove
erview
The Microsoft .NET Framew work version 44.5 provides a comprehensiive development platform that you
can use to buildd, deploy, and manage app plications and services. By using the .NET
T Framework, yyou can
cre
eate visually ccompelling appplications, enable seamlesss communicattion across tecchnology bouundaries,
and provide sup pport for a wid
de range of bbusiness proceesses.
In this module, yyou will learn about some of the core fe eatures provid
ded by the .NEET Frameworkk and
Miicrosoft Visual Studio. Yo ou will also leaarn about som
me of the core Visual C# cconstructs thaat enable
you to start devveloping .NET Framework aapplications.
Ob
bjectives
e, you will be able to:
Aftter completing this module
Lesson 1
Overrview of Writin
ng App
plication
n by Ussing Vissual C#
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
W
What Is the
e .NET Framework?
The .NET Frame ework 4.5 provvides a comprrehensive devvelopment plaatform that offfers a fast and
d efficient
waay to build applications and
d services. By using Visual SStudio 2012, you
y can use thhe .NET Frame ework 4.5
to create a widee range of solu
utions that op
perate across a broad range e of computin
ng devices.
The .NET Frame
ework 4.5 provvides three prrincipal eleme
ents:
The Commo
on Language Runtime (CLR
R).
Th
he Common
n Language
e Runtime
The .NET Frame ework provide
es an environm
ment called thhe CLR. The CLLR manages the execution of code
and simplifies th
he developme execution environment
ent process byy providing a robust and hiighly secure e
tha
at includes:
Memory maanagement.
Transaction
ns.
Multithread
ding.
Th
he .NET Fra
amework Cllass Library
y
The .NET Frame ework provide es a library of reusable classses that you caan use to builld application
ns. The
cla
asses provide a foundation of common ffunctionality and a constructss that help to simplify application
deevelopment byy, in part, elim
minating the n need to constaantly reinvent logic. For exaample, the
Sy
ystem.IO.File class containss functionalityy that enabless you to manip pulate files on
n the Window ws file
sysstem. In addittion to using tthe classes in tthe .NET Fram
mework class library, you caan extend thesse classes
byy creating your own librariees of classes.
De
evelopmen
nt Framewo
orks
The .NET Frame ework provide es several deve
elopment fram
meworks that you can use to
t build comm
mon
ap
pplication type
es, including:
Desktop clie
ent applicatio
ons, by using W
Windows Pressentation Foundation (WPFF).
Programming in Visual C# 1-5
Server-side web applications, by using Active Server Pages (ASP.NET) Web Forms or ASP.NET MVC.
Service-oriented web applications, by using Windows Communication Foundation (WCF).
Each framework provides the necessary components and infrastructure to get you started.
Additional Reading: For more information about the .NET Framework, see the Overview
of the .NET Framework page at http://go.microsoft.com/fwlink/?LinkID=267639.
1-6 Review off Visual C# Syntax
Ke
ey Feature
es of Visuaal Studio 2012
Vissual Studio 20
012 provides a single development envirronment that enables you tto rapidly design,
implement, build, test, and deploy various types of applications and components by using a rannge of
proogramming laanguages.
Some of the keyy features of V
Visual Studio 2
2012 are:
Intuitive inttegrated deve elopment enviironment (IDE E). The Visual Studio 2012 IDE provides aall of the
features and d tools that are necessary tto design, imp
plement, buildd, test, and de
eploy applicattions and
componentts.
Rapid application develo opment. Visuaal Studio 2012 2 provides dessign views for graphical com
mponents
that enablee you to easilyy build comple
ex user interfaaces. Alternatively, you can use the Codee Editor
views, which provide mo ore control but are not as eaasy to use. Vissual Studio 20
012 also proviides wizards
that help sp
peed up the d development o of particular components.
c
Internet Infformation Servvices (IIS) Express. Visual Studio 2012 pro weight version of IIS as
ovides a lightw
the default web server fo
or debugging your web app plications.
Debugging features. Visuual Studio 20112 provides a debugger tha at enables you
u to step thro
ough local
or remote ccode, pause att breakpoints,, and follow e
execution path
hs.
Additiona
al Reading: FFor more inforrmation about what is new in Visual Studdio 2012, see
the
e What's New
w in Visual Sttudio 2012 p
page at http:///go.microsoft..com/fwlink/??LinkID=26776 68.
Programmingg in Visual C# 1-7
7
T
Templates
s in Visual Studio 2
2012
Include su
upporting com
mponents and
d controls thaat are relevantt to the projecct type.
Configure
e the Visual Sttudio 2012 ID
DE to the type of application that you are
e developing.
T
Types of Te
emplates
The following table describ
T bes some of th
he common application tem mplates that yyou might use
e when you
d
develop .NET Framework applications byy using Visuall Studio 2012..
Template Descripttion
Console Application Providess the environmment settings,, tools, projecct references, aand starter co
ode
to devellop an applicaation that runs in a commaand-line interfface. This type e of
applicattion is conside
ered lightweig
ght because th here is no graphical user
interface
e.
Template Description
Class Library Provides the environment settings, tools, and starter code to build a .dll
assembly. You can use this type of file to store functionality that you might
want to invoke from many other applications.
ASP.NET Web Application Provides the environment settings, tools, project references, and starter code
to create a server-side, compiled ASP.NET web application.
ASP.NET MVC 4 Provides the environment settings, tools, project references, and starter code
Application to create a Model-View-Controller (MVC) Web application. An ASP.NET MVC
web application differs from the standard ASP.NET web application in that
the application architecture helps you separate the presentation layer,
business logic layer, and data access layer.
WCF Service Application Provides the environment settings, tools, project references, and starter code
to build Service Orientated Architecture (SOA) services.
Programmingg in Visual C# 1-9
9
C
Creating a .NET Fraamework A
Applicatio
on
The applicatio
T on templates provided in Visual
V 2012 enable you to start cre
Studio 2 eating an app
plication with
m
minimal effort. You can the
en add your code and custoomize the pro
oject to meet your own req quirements.
1
1. Open Visual Studio 2012.
2
2. In Visual Studio, on the
e File menu, p
point to New,, and then clicck Project.
3
3. In the Ne
ew Project dia
alog box, do the
t following::
a. Expand Template
es, Visual C#, and then clickk Windows.
c. In the
e Name box, specify a nam
me for the pro
oject.
d. In the
e Location bo
ox, specify the
e path where you want to ssave the proje
ect.
4
4. Click OK.
5
5. The Codee Editor window now show
ws the default Program class, which contains the entrry point
method ffor the applicaation.
P
Program Classs
using Syste
em;
using Syste
em.Collectio
ons.Generic;
using Syste
em.Linq;
using Syste
em.Text;
using Syste
em.Threading
g.Tasks;
namespace C
ConsoleApplication1
{
class Pr
rogram
{
stat
tic void Main(string[] args)
{
}
}
1-10 Review of Visual C# Syntax
After you create a project, you can then use the features that Visual Studio provides to create your
application.
The Quick Info option displays the complete declaration for any identifier in your code. Move the
mouse so that the pointer rests on an identifier to display Quick Info for that identifier, which appears
in a yellow pop-up box.
The Complete Word option enters the rest of a variable, command, or function name after you have
typed enough characters to disambiguate the term. Type the first few letters of the name and then
press Alt+Right Arrow or Ctrl+Spacebar to complete the word.
Programming in
i Visual C# 1-11
1
Lesson 2
Data Types,, Opera
ators, an
nd Exprressions
All application
A ns use data. This data mighht be suppliedd by the user tthrough a use
er interface, fro
om a
d
database, from
m a network sservice, or from some otherr source. To sttore and use data
d in your applications,
a
y must fam
you miliarize yourseelf with how tto define and use variables and how to create
c and use e expressions
w the varie
with ety of operators that Visual C# provides.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create an
nd use expresssions.
Declare aand assign varriables.
pe to another.
Cast dataa from one typ
Concaten
nate and validate strings.
1-12 Review of Visual C# Syntaxx
W
What are Data
D Typess?
A variable
v holdss data of a spe
ecific type. When you declaare a variable to store data in an applicaation, you
ne
eed to choose an appropriaate data type forf that data. Visual C# is a type-safe lan nguage, which h means
tha
at the compileer guaranteess that values stored in variaables are alwayys of the apprropriate type.
Co
ommonly Used
U Data T
Types
The following taable shows the commonly u
used data typ
pes in Visual C#,
C and their characteristics
c .
T
Type Desccription Size (b
bytes) Range
i
int Who
ole numbers 4 2,147,483,648 to 2,147
7,483,647
l
long Who ole numbers 8 9,223,372,036,854,775
5,808 to
(bigger range) 9,223,372,036,854,775,807
f
float Floaating-point 4 +/3.4 1
10^38
nummbers
d
double Douuble precision 8 +/1.7 1
10^308
(more accurate)
floatting-point
nummbers
d
decimal Mon
netary values 16 28 significcant figures
c
char Sing
gle character 2 N/A
b
bool Boolean 1 True or false
D
DateTime Mom
ments in time 8 0:00:00 on
n 01/01/2001 to
23:59:59 o
on 12/31/9999
s
string Sequuence of 2 per character N/A
charracters
Programming in Visual C# 1-13
Additional Reading: For more information about data types, see the Reference Tables
for Types (C# Reference) page at http://go.microsoft.com/fwlink/?LinkID=267770.
1-14 Review of Visual C# Syntaxx
Operators ddefine operatiions to perforrm on operand ds, for exampple, addition oor multiplicatioon.
Operators eexist for all of the basic matthematical op
perations, as wwell as for more advanced o operations
such as logical compariso on or the mannipulation of tthe bits of datta that constittute a value.
Op
perators in Visual C#
Opperators comb bine operandss together into expressionss. Visual C# prrovides a wide
e range of opeerators that
you can use to pperform mostt fundamental mathematica al and logical operations. O
Operators fall into the
folllowing three categories:
Unary. This type of operaator operates on a single operand. For e c use the - operator as
example, you can
a unary ope e it immediately before a numeric
erator. To do this, you place n operaand, and it converts the
value of the
e operand to its current vallue multiplied
d by 1.
Binary. Thiss type of operaand operates on two valuees. This is the m n type of operator, for
most common
example, *, which multip plies the value
e of two opera
ands.
T
Type Operators
Programming in Visual C# 1-15
Type Operators
Arithmetic +, -, *, /, %
String concatenation +
Casting ( ), as
Assignment =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, ??
Expression Examples
You can combine the basic building blocks of operators and operands to make expressions as simple or as
complex as you like.
The following code example shows how to use the + operator.
+ Operator
a + 1
The + operator can operate on different data types, and the result of this expression depends on the data
types of the operands. For example, if a is an integer, the result of the expression is an integer with the
value 1 greater than a. If a is a double, the result is a double with the value 1 greater than a. The
difference is subtle but important. In the second case (a is a double), the Visual C# compiler has to
generate code to convert the constant integer value 1 into the constant double value 1 before the
expression can be evaluated. The rule is that the type of the expression is the same as the type of the
operands, although one or more of the operands might need to be converted to ensure that they are all
compatible.
The following code example shows how to use the / operator to divide two int values.
/ Operator
5 / 2
The value of the result is the integer value 2 (not 2.5). If you convert one of the operands to a double, the
Visual C# compiler will convert the other operand to a double, and the result will be a double.
1-16 Review of Visual C# Syntax
The following code example shows how to use the / operator to divide a double value by an int value.
/ Operator
5.0 / 2
The value of the result now is the double value 2.5. You can continue building up expressions with
additional values and operators.
The following code example shows how use the + and operators in an expression.
+ and Operators
a + b - 2
This expression evaluates to the sum of variables a and b with the value 2 subtracted from the result.
Some operators, such as +, can be used to evaluate expressions that have a range of types.
The following code example shows how to use the + operator to concatenate two string values.
+ Operator
"ApplicationName: " + appName.ToString()
The + operator uses an operand that is a result of a method call, ToString(). The ToString() method
converts the value of a variable into a string, whatever type it is.
The .NET Framework class library contains many additional methods that you can use to perform
mathematical and string operations on data, such as the System.Math class.
Additional Reading: For more information about operators, see the C# Operators page at
http://go.microsoft.com/fwlink/?LinkID=267771.
Programming in
i Visual C# 1-17
7
D
Declaring and Assig
gning Varriables
When declarin
W ng variables yyou should use
e meaningful names for yo
our variables, because
b this ccan make
y
your code eassier to understand. You sho
ould also adop
pt a naming cconvention annd use it!
D
Declaring a
and Assigniing Variable
When you declare a variable, you reservve some storag
W ge space for tthat variable in
n memory and the type of
d
data that it wiill hold. You ccan declare multiple variablles in a single declaration by
b using the comma
s
separator; all vvariables decllared in this w
way have the ssame type.
D
Declaring aV
Variable
// DataTypee variableNa
ame;
int price;
// OR
// DataTypee variableNa
ame1, variableName2;
int price, tax;
Assigning a Variable
// variableName = value;
price = 10;
The value on the right side of the expression is assigned to the variable on the left side of the expression.
You can declare a variable and assign a value to it at the same time.
The following code example declares an int named price and assigns the value 10.
When you declare a variable, it contains a random value until you assign a value to it. This behavior was a
rich source of bugs in C and C++ programs that created a variable and accidentally used it as a source of
information before giving it a value. Visual C# does not allow you to use an unassigned variable. You must
assign a value to a variable before you can use it; otherwise, your program might not compile.
In this example, the price variable is an implicitly typed variable. However, the var keyword does not
mean that you can later assign a value of a different type to price. The type of price is fixed, in much the
same way as if you had explicitly declared it to be an integer variable.
Implicitly typed variables are useful when you do not know, or it is difficult to establish explicitly, the type
of an expression that you want to assign to a variable.
Object Variables
When you declare an object variable, it is initially unassigned. To use an object variable, you must create
an instance of the corresponding class, by using the new operator, and assign it to the object variable.
The new operator does two things: it causes the CLR to allocate memory for your object, and it then
invokes a constructor to initialize the fields in that object. The version of the constructor that runs
depends on the parameters that you specify for the new operator.
The following code example shows how to create an instance of a class by using the new operator.
Additional Reading: For more information about declaring and assigning variables, see
the Implicitly Typed Local Variables (C# Programming Guide) page at
http://go.microsoft.com/fwlink/?LinkID=267772.
Programming in
i Visual C# 1-19
9
A
Accessing
g Type Me
embers
I
Invoking Me
embers
var config = new ServiceConfiguration();
// Invoke t
the LoadConf
figuration method.
var loadSuc
ccessful = config.LoadC
c onfiguration
n();
// Get the value from the ApplicationName prooperty.
var applica
ationName = config.ApplicationName;;
// Set the .DatabaseSe
erverName property.
config.Data
abaseServerN
Name = "78.45.81.23";
// Invoke t
the SaveConf
figuration method.
var saveSuc
ccessful = config.SaveC
c onfiguration
n();
Additio
onal Reading: For more infformation aboout using prop
perties, see th
he Propertiess (C#
Programming Guide) pag
P ge at http://go
o.microsoft.co
om/fwlink/?Lin
nkID=267773.
Additio
onal Reading: For more infformation aboout using metthods, see the
e Methods (C
C#
Programming Guide) pag
P ge at http://go
o.microsoft.co
om/fwlink/?Lin
nkID=267774 4.
1-20 Review of Visual C# Syntaxx
Implicit con
nversion, whicch is automatically performed by the CLR
R on operations that are gu
uaranteed
to succeed without losing g information
n.
Explicit conversion, which
h requires you
u to write cod
de to perform a conversion that otherwisse could
lose information or produce an error.
Im
mplicit Conv
versions
An
n implicit convversion occurss when a value is converted d automatically from one d data type to an
nother. The
conversion doess not require aany special syyntax in the so
ource code. Viisual C# only allows safe im
mplicit
conversions, succh as the wide
ening of an integer.
The following co
ode example shows how daata is converted implicitly from
f an integer to a long, which
w is
terrmed widening
g.
Im
mplicit Conversion
int a = 4;
long b;
b = a; // Implici
it conversio
on of int to long.
This conversion always succeeds and never results in a loss of information. However, you canno ot implicitly
convert a long vvalue to an in
nt, because this conversion risks losing in
nformation (th
he long value
e might be
ou
utside the rang
ge supported by the int typ pe). The follow
wing table shoows the implicit type conve
ersions that
are
e supported in
n Visual C#.
Programming in Visual C# 1-21
From To
float double
Explicit Conversions
In Visual C#, you can use a cast operator to perform explicit conversions. A cast specifies the type to
convert to, in round brackets before the variable name.
Explicit Conversion
int a;
long b = 5;
a = (int) b; // Explicit conversion of long to int.
You can also perform an explicit conversion by using the as operator, but only for reference type objects.
The advantage of using the as operator is that if the conversion fails due to the types being incompatible,
instead of the CLR throwing an InvalidCastException, the cast operation will return null, which you can
then check for in your code.
The following code example shows how to use the as operator to cast between two data types.
You can only perform meaningful conversions in this way, such as converting a long to an int. You cannot
use a cast if the format of the data has to physically change, such as if you are converting a string to an
integer. To perform these types of conversions, you can use the methods of the System.Convert class.
the CLR can use this class. You might find this class easier to use for conversions than implicit or explicit
conversions because IntelliSense helps you to locate the conversion method that you need.
Some of the built-in data types in Visual C# also provide a TryParse method, which enables you to
determine whether the conversion will succeed before you perform the conversion.
The following code example shows how to convert a string to an int by using the int.TryParse() method.
TryParse Conversion
int number = 0;
string numberString = "1234";
if (int.TryParse(numberString, out number))
{
// Conversion succeeded, number now equals 1234.
}
else
{
// Conversion failed, number now equals 0.
}
Additional Reading: For more information about casting variables, see the Casting and
Type Conversions (C# Programming Guide) page at
http://go.microsoft.com/fwlink/?LinkID=267775.
Programming in
i Visual C# 1-23
3
M
Manipulat
ting String
gs
S
Strings are a vvery useful daata type that enable
e you to capture and store alphanu
umeric data.
C
Concatenat
ting Stringss
Concatenating
C g multiple strings in Visual C# is simple tto achieve byy using the + ooperator. How
wever, this is
c
considered baad coding praactice becausee strings are im
mmutable. This means thatt every time yo ou
c
concatenate a string, you ccreate a new sstring in memory and the o old string is discarded.
C
Concatenatio
on by Using tthe + Operattor
string addr
ress = "23";
address = a
address + ", Main Street";
address = a
address + ", Buffalo";
An alternative
A e approach is to use the StrringBuilder class,
c which en
nables you to build a string
g dynamically
a much mo
and ore efficiently..
C
Concatenatio
on by Using tthe StringBuilder Class
StringBuild
der address = new StringBuilder();
address.App
pend("23");
address.App
pend(", Main
n Street");
address.App
pend(", Buff
falo");
string conc
catenatedAdd
dress = address.ToStringg();
V
Validating Strings
When acquiring input from
W m the user inte erface of an application, daata is often pro
ovided as strin
ngs that you
n
need to validaate and then convert
c into a format that yyour applicatiion logic expe ects. For exam
mple, a text
b control in
box n a WPF appliccation will retturn its conten
nts as a string er specified an integer
g, even if a use
v
value. It is imp
portant that yyou validate suuch input so tthat you minim mize the risk of
o errors, suchh as
I
InvalidCastEx xceptions.
Regular expre
R essions provide a mechanism that enable
es you to valid
date input. Th
he .NET Frameework
p
provides System.Text.RegularExprressions name
the S espace that in
ncludes the Reegex class. Yo
ou can use the
e
1-24 Review of Visual C# Syntax
Regex class in your applications to test a string to ensure that it conforms to the constraints of a regular
expression.
The following code example shows how to use the Regex.IsMatch method to see if a string value
contains any numerical digits.
Regex.IsMatch Method
var textToTest = "hell0 w0rld";
var regularExpression = "\\d";
var result = Regex.IsMatch(textToTest, regularExpression, RegexOptions.None);
if (result)
{
// Text matched expression.
}
Regular expressions provide a selection of expressions that you can use to match to a variety of data
types. For example, the \d expression will match any numeric characters.
Additional Reading: For more information about using regular expressions, see the Regex
Class page at http://go.microsoft.com/fwlink/?LinkID=267776.
Programming in
i Visual C# 1-25
5
Lesson 3
Visua
al C# Prrogram
mming LLanguage Con
nstructss
When develop
W ping an appliccation, you will often need to execute loogic based on a condition, o
or to
r
repeatedly execute a sectioon of logic until a conditionn is met. You may
m also want to store a co ollection of
r
related data in
n a single variiable. Visual C
C# provides a number of coonstructs than
n enable you mmodel
c
complex behaavior in your aapplications.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create an
nd use arrays.
Im
mplementing Condiitional Log
gic
Co
onditional S
Statementss
Yo
ou use if statements to test the truth of a statement. Iff the statemennt is true, the
e block of code
asssociated with the if statement is execute ement is false, control passes over the block.
ed, if the state
The following co
ode shows ho
ow to use an if statement to
o determine iff a string con
ntains the valu
ue
co
onnection_failed.
if Statement
S
s
string respon
nse = ".";
if (response == "connect
tion_failed")
{
// Block of code to execute if the value of
f the respon
nse variable
e is
"connection_f
failed".
}
if statements
s ca
an have associiated else clau
uses. The else
e block executtes when the if statement is false.
The following co
ode example shows how to
o use an if elsse statement tto execute cod
de when a condition is
fallse.
if else
e Stateme
ents
s
string respon
nse = ".";
if (response == "connect
tion_failed")
{
// Block of code exe
ecutes if th
he value of t
the response
e variable is
"connection_f
failed".
}
Programming in Visual C# 1-27
else
{
// Block of code executes if the value of the response variable is not
"connection_failed".
}
if statements can also have associated else if clauses. The clauses are tested in the order that they appear
in the code after the if statement. If any of the clauses returns true, the block of code associated with that
statement is executed and control leaves the block of code associated with the entire if construct.
The following code example shows how to use an if statement with an else if clause.
else if Statements
string response = ".";
if (response == "connection_failed")
{
// Block of code executes if the value of the response variable is
"connection_failed".
}
else if (response == "connection_error")
{
// Block of code executes if the value of the response variable is
"connection_error".
}
else
{
// Block of code executes if the value of the response variable is not
"connection_failed" or "connection_error".
}
Selection Statements
If there are too many if/else statements, code can become messy and difficult to follow. In this scenario, a
better solution is to use a switch statement. The switch statement simply replaces multiple if/else
statements.
The following sample shows how you can use a switch statement to replace a collection of else if clauses.
switch Statement
string response = ".";
switch (response)
{
case "connection_failed":
// Block of code executes if the value of response is "connection_failed".
break;
case "connection_success":
// Block of code executes if the value of response is "connection_success".
break;
case "connection_error":
// Block of code executes if the value of response is "connection_error".
break;
default:
// Block executes if none of the above conditions are met.
break;
}
In each case statement, notice the break keyword. This causes control to jump to the end of the switch
after processing the block of code. If you omit the break keyword, your code will not compile.
Notice that there is an else block labeled default:. This block of code will execute when none of the other
blocks match.
1-28 Review of Visual C# Syntax
Additional Reading: For more information about selection statements, see the Selection
Statements (C# Reference) page at http://go.microsoft.com/fwlink/?LinkID=267777.
Programming in
i Visual C# 1-29
9
I
Implemen
nting Itera
ation Logiic
F Loops
For
The for loop e
T executes a blo
ock of code re ed expression evaluates to ffalse. You can
epeatedly unttil the specifie
d
define a for lo
oop as followss.
f ([initializerrs]; [expression]; [iterators])
for
[body]
}
f Loop
for
for (int i = 0 ; i < 10;
1 i++)
{
// Code
e to execute
e.
}
F Each Lo
For oops
While a for lo
W oop is easy to use, it can be ample, when itterating over a collection
e tricky to get right. For exa
o an array, yo
or ou have to knnow how many elements th he collection or
o array contains. In many ccases this is
s
straightforwarrd, but somettimes it can be
e easy to get wrong.
w Thereffore, it is sometimes betterr to use a
f
foreach loop..
foreach Loop
string[] names = new string[10];
// Process each name in the array.
foreach (string name in names)
{
// Code to execute.
}
While Loops
A while loop enables you to execute a block of code while a given condition is true. For example, you can
use a while loop to process user input until the user indicates that they have no more data to enter.
while Loop
bool dataToEnter = CheckIfUserWantsToEnterData();
while (dataToEnter)
{
// Process the data.
dataToEnter = CheckIfUserHasMoreData();
}
Do Loops
A do loop is very similar to a while loop, with the exception that a do loop will always execute at least
once. Whereas if the condition is not initially met, a while loop will never execute. For example, you can
use a do loop if you know that this code will only execute in response to a user request to enter data. In
this scenario, you know that the application will need to process at least one piece of data, and can
therefore use a do loop.
do Loop
do
{
// Process the data.
moreDataToEnter = CheckIfUserHasMoreData();
} while (moreDataToEnter);
Additional Reading: For more information about loops, see the Iteration Statements (C#
Reference) page at http://go.microsoft.com/fwlink/?LinkID=267778.
Programming in
i Visual C# 1-31
1
C
Creating aand Using
g Arrays
Every elem
ment in the array contains a value.
Arrays are
e zero-indexe
ed, that is, the first item in tthe array is ele
ement 0.
The size o
of an array is the
t total num
mber of elemen
nts that it can
n contain.
C
Creating Arrrays
When you declare an arrayy, you specify the type of da
W ata that it con
ntains and a n
name for the aarray.
D
Declaring an array
a brings the array into scope, but do
oes not actually allocate anyy memory forr it. The CLR
p
physically creaates the arrayy when you usse the new keeyword. At thiss point, you should specify the size of
t array.
the
int[] arrayName
a = new int[10];
You can specify up to 32 dimensions, but you will rarely need more than three. You declare a
multidimensional array variable just as you declare a single-dimensional array, but you separate the
dimensions by using commas. The following code example shows how to create an array of integers
with three dimensions.
Jagged arrays. A jagged array is simply an array of arrays, and the size of each array can vary. Jagged
arrays are useful for modeling sparse data structures where you might not always want to allocate
memory for every item if it is not going to be used. The following code example shows how to
declare and initialize a jagged array. Note that you must specify the size of the first array, but you
must not specify the size of the arrays that are contained within this array. You allocate memory to
each array within a jagged array separately, by using the new keyword.
The following code example uses an index to access the element at index two.
Note: Arrays are zero-indexed, so the first element in any dimension in an array is at index
zero. The last element in a dimension is at index N-1, where N is the size of the dimension. If you
attempt to access an element outside this range, the CLR throws an
IndexOutOfRangeException exception.
You can iterate through an array by using a for loop. You can use the Length property of the array to
determine when to stop the loop.
The following code example shows how to use a for loop to iterate through an array.
Additional Reading: For more information about arrays, see the Arrays (C#
Programming Guide) page at http://go.microsoft.com/fwlink/?LinkID=267779.
Programming in
i Visual C# 1-33
3
R
Referenci ng Namesspaces
.
.NET Frame
ework Classs Library Na
amespacess
The most imp
T portant namesspace in the .NNET Framewo ork is the Syste
em namespacce, which contains the
c
classes that m
most applicatio
ons use to inte
eract with the
e operating syystem. A few o
of the namesp
paces
p
provided by the .NET Fram
mework throug gh the System m namespace are listed in the following ttable:
Namespace Definittion
System.Win
ndows Provides the classess that are usefful for building
g WPF applica
ations.
System.Data
a Provides classes for data access.
System.Web
b Provides classes that are useful fo
or building we
eb application
ns.
U
User-Defin ed Namesp
paces
User-defined namespaces are
U a namespacces defined in your code. It is good practtice to define all your
c
classes in nam
mespaces. The Visual Studioo environmentt follows this recommendation by using the name of
y
your project aas the top-level namespace
e in a project.
Defining a Namespace
namespace FourthCoffee.Console
{
class Program
{
static void Main(string[] args)
{
}
}
}
When you create a Visual C# project in Visual Studio, the most common base class assemblies are already
referenced. However, if you need to use a type that is in an assembly that is not already referenced in your
project, you will need to add a reference to the assembly by using the Add Reference dialog box. Then at
the top of your code file, you list the namespaces that you use in that file, prefixed with the using
directive. The using directive is a shortcut that instructs your application that the types in the namespace
can be referenced directly, without using the fully qualified name.
The following code example shows how to import the System namespace and use the Console class.
Importing a Namespace
using System;
Console.WriteLine("Hello, World");
Additional Reading: For more information about namespaces, see the namespace (C#
Reference) page at http://go.microsoft.com/fwlink/?LinkID=267780.
Programming in
i Visual C# 1-35
5
D
Debuggin
ng by Usin
ng Visual S
Studio 2012
Debugging is an essential p
D part of applicaation developpment. You may notice erroors as you writte code, but
s
some errors, e
especially logiic errors, may only occur in
n circumstance
es that you do
o not predict. Users may
r
report these eerrors to you aand you will have
h to correcct them.
Visual Studio 2012 provide
V es several tools to help you debug code. You might usse these while e you develop
p
c
code, during a test phase, o
or after the ap
pplication hass been release
ed. You will usse the tools in the same
w regardlesss of the circumstances.
way
D
Debug Con
ntrols
The following table lists the
T e key items on
n the Debug menu and the
e Debug toolbar, and the
c
correspondingg keyboard sh hortcuts.
Menu item To
oolbar button
n Key
yboard shortccut De
escription
Start Debug
gging Sttart/continue F5 Thhis button is available when
n
yo
our application n is not
running and wh hen you are
in break mode. It will start
yo
our application n in Debug
mode or resume the
pplication if yo
ap ou are in
brreak mode.
Stop Debug
gging Sttop Sh
hift+F5 Th
his button stops
1-36 Review of Visual C# Syntax
Additional Reading: For more information about debugging, see the Debugging in
Visual Studio page at http://go.microsoft.com/fwlink/?LinkID=267781.
Programming in
i Visual C# 1-37
7
D
Demonstr
ration: De
eveloping the Classs Enrollme
ent Appliccation Lab
b
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
1-38 Review of Visual C# Syntaxx
Lab: D
Develop
ping the
e Class Enrollm
ment Applicat
A tion
Sccenario
Yo
ou are a Visual C# develope er working forr a software development ccompany thatt is writing app
plications
of Fine Arts, an elementary school for giffted children.
forr The School o
The school adm ministrators req
quire an appliication that th
hey can use to
o enroll studennts in a class. The
ap
pplication musst enable an aadministrator tto add and re emove students from classe es, as well as to update
the
e details of stu
udents.
Yo
ou have been asked to write at implements the businesss logic for the
e the code tha e application.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
Perform sim
mple data tran
nsformations for
f displaying information.
Password: Pa$$w0rd
1-40 Review of Visual C# Syntax
A list of students is displayed in the user interface of the application. When the user selects a student and
then presses a key on the keyboard, you will check whether the key they pressed was Enter.
If they did press Enter, you will write code to display the students details in a separate form, which the
user can use to modify the details.
When the user closes the form, you will copy the updated details back to the list box displaying the list of
students.
Finally, you will run the application to verify that your code functions as expected, and then use the
debugging tools to examine code as it runs.
2. Initialize the StudentForm window and populate it with the details of the currently selected student
3. Display the StudentForm window and copy the updated student details entered back to the Student
object
4. Run the application and verify that the edit functionality works as expected
X Task 1: Detect whether the user has pressed the Enter key
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. Start the 20483A-SEA-DEV11-01 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio and from the E:\Labfiles\Starter\Exercise 1 folder, and then open the School.sln
solution.
4. In the code for the MainWindow.xaml.cs window, find the studentsList_KeyDown method.
5. In this method, add a switch statement to detect whether the user has pressed Enter.
Note: The second argument passed to this method is a KeyEventArgs object named e.
This object has a Key property which returns the keyboard key associated with the event. You can
use this in conjunction with the Key enumeration to determine which key initiated the KeyDown
event.
6. If the user has pressed Enter, store the selected student in a Student object variable.
Note: Later in this lab, you will be adding code to detect whether the user presses the
Insert or Delete keys, so a switch statement is recommended.
Programming in Visual C# 1-41
X Task 2: Initialize the StudentForm window and populate it with the details of the
currently selected student
1. If the user has pressed the Enter key, create a new instance of the StudentForm window and set the
Title property of the window to Edit Student Details.
2. Populate the following text boxes on the form with the corresponding properties of the current
student:
a. firstName
b. lastName
c. dateOfBirth
3. Display the date of birth by using the standard short date format without the time element by using
the d format specifier.
Note: To store data in a text box in a window, set the Text property of the text box.
X Task 3: Display the StudentForm window and copy the updated student details
entered back to the Student object
1. At the end of the case Key.Enter block, display the StudentForm window by using the ShowDialog
method of the form.
2. If the user clicks OK in the StudentForm window, copy the updated student details from the
StudentForm window back to the Student object.
Note: You can detect whether the user clicked the OK button by examining the return
value of the ShowDialog method. If the Value property is true, the user clicked OK, otherwise
they clicked Cancel.
Note: You can use the DateTime.Parse method to convert the date of birth string from
the text box to a DateTime type.
3. If the user clicks OK, also enable the Save Changes button in the user interface.
Note: To enable an item in a user interface, set the IsEnabled property of the item to true.
X Task 4: Run the application and verify that the edit functionality works as expected
1. Build the solution and resolve any compilation errors.
2. Run the application and verify that it displays the initial list of students.
1-42 Review of Visual C# Syntax
X Task 5: Use the Visual Studio Debugger to step through the code.
1. In Visual Studio, in the studentsList_KeyDown method, insert a breakpoint at the statement that sets
the Title property of the StudentForm.
4. When Visual Studio enters break mode, open the Watch 1 window and populate the grid with a row
for each of the following:
o sf.Title
o sf.firstName.Text
Programming in Visual C# 1-43
o sf.lastName.Text
o sf.dateOfBirth.Text
Note: When Visual Studio enters break mode, the Watch window automatically appears in
the tab group in the bottom left window.
Note: When Visual Studio enters break mode, the Immediate Window automatically
appears in the tab group in the bottom middle window
8. In the Immediate Window, enter sf.lastName.Text and verify that the value "Li" is displayed.
9. Enter code to change the sf.lastName.Text value to "Dubicki", and then verify that value changes in
the Watch 1 window.
10. Continue debugging and verify that the following information is displayed in the Edit Student Details
form:
Field Value
12. In Visual Studio, on the Debug menu, click Delete All Breakpoints, and then close the solution.
Results: After completing this exercise, users will be able to edit the details of a student.
1-44 Review of Visual C# Syntax
A list of students is displayed in the user interface of the application. When the user presses a key on the
keyboard, you will check whether the key they pressed was Insert.
If they did press Insert, you will write code to display a form in which the user can enter the details of a
new student, including their first name, last name, and date of birth.
When the user closes the form, you will add the new student to the list of students and display the details
in the list box.
Finally, you will run the application to verify that your code functions as expected.
1. Add logic to the key down method to detect if the Insert key has been pressed.
3. Display the StudentForm window and enable the user to provide the details of the new student
4. Assign the new student to a class and enable the user to save the details of the new student
5. Run the application and verify that the insert functionality works as expected
X Task 1: Add logic to the key down method to detect if the Insert key has been
pressed.
1. In Visual Studio, from the E:\Labfiles\Starter\Exercise 2 folder, open the School.sln solution.
2. In the code for the MainWindow.xaml.cs window, locate the studentsList_KeyDown method.
3. In this method, add a statement to detect whether the user has pressed Insert.
2. Set the Title property of the window to New Student for Class appended to the Class property of
the teacher object.
Note: You can use code similar to the following to create the string for the Title property.
"New Student for Class " + teacher.Class
X Task 3: Display the StudentForm window and enable the user to provide the details
of the new student
1. Display the StudentForm window by using the ShowDialog method.
2. If the user clicks the OK button in the StudentForm window, create a new student object and copy
the student details from the StudentForm window to the new student object.
X Task 4: Assign the new student to a class and enable the user to save the details of
the new student
1. If the user clicks the OK button in the StudentForm window, use the Students.Add method of the
current teacher to assign the new student to a class.
Programming in Visual C# 1-45
Note: You can use the this.Teacher property to access the current teacher.
2. Add the new student object to the list of students displayed on the form.
X Task 5: Run the application and verify that the insert functionality works as expected
1. Build the solution and resolve any compilation errors.
2. Run the application and verify that it displays the initial list of students.
3. Display the new student window and verify that it contains no data.
4. Insert the details for Darren Parker, date of birth is 02/03/2006, and verify that the new student is
added to the students list.
Note: The ID of any new student will be 0 until they are saved to the database.
Results: After completing this exercise, users will be able to add new students to a class.
1-46 Review of Visual C# Syntax
A list of students is displayed in the user interface of the application. If the user selects a student and then
presses a key on the keyboard, you will check whether the key they pressed was Delete.
If they did press Delete, you will write code to prompt the user to confirm that they want to remove the
selected student from the class.
If they do, the student will be deleted from the students list for the appropriate class, otherwise nothing
changes.
Finally, you will run the application to verify that your code functions as expected.
1. Add logic to the key down method to detect if the Delete key has been pressed.
2. Prompt the user to confirm that they want to remove the selected student from the class
3. Remove the student and enable the user to save the changes
4. Run the application and verify that the delete functionality works as expected
X Task 1: Add logic to the key down method to detect if the Delete key has been
pressed.
1. In Visual Studio, from the E:\Labfiles\Starter\Exercise 3 folder, open the School.sln solution.
2. In the code for the MainWindow.xaml.cs window, find the studentsList_KeyDown method.
3. In this method, add a statement to detect whether the user has pressed Delete.
X Task 2: Prompt the user to confirm that they want to remove the selected student
from the class
1. If the user presses Delete, find the details of the student that the user has selected and display a
message box showing the selected students name. Ask the user to confirm that they want to remove
the student.
X Task 3: Remove the student and enable the user to save the changes
1. If the user confirms that they want to delete the student, delete the current student object from the
schoolContext.Students collection and enable the Save Changes button in the user interface.
Programming in Visual C# 1-47
X Task 4: Run the application and verify that the delete functionality works as expected
1. Build the solution and resolve any compilation errors.
2. Run the application and verify that it displays the initial list of students.
4. Verify that the prompt window appears, the student is removed from the list, and that the Save
Changes button is enabled.
5. Close the application.
Results: After completing this exercise, users will be able to remove students from classes.
1-48 Review of Visual C# Syntax
You will write code in the AgeConverter class that is linked to the grid column displaying student ages. In
this class, you will write code to work out the difference between the current date and the date of birth of
the student, and then convert this value into years.
Then you will run the application to verify that the Age column now displays age in years instead of the
date of birth.
3. Run the application and verify that the students age now appears correctly
4. Note how the Age column in the GridView uses databinding with a value converter (AgeConverter).
X Task 2: Add logic to the AgeConverter class to calculate a students age from their
date of birth
1. In the code for the MainWindow.xaml.cs window, find the Convert method in the AgeConverter
class.
2. In this method, add code that checks that the value parameter of the method contains data. If it does
not, return an empty string.
3. If the value parameter is not null, convert the value parameter to a DateTime object.
4. Calculate the difference between the current date and the students date of birth, and then convert
the result into a number of years.
Note: You can use the DateTime.Now.Subtract method to subtract the date of birth from
the current date and store the result in a TimeSpan object.
You can use the TimeSpan.Days method to retrieve the difference in days and then use the
following formula to calculate the age in years from this difference.
Age in years = difference in days / 365.25
5. Convert the number of years into a string and return it to the calling method.
X Task 3: Run the application and verify that the students age now appears correctly
1. Build the solution and resolve any compilation errors.
2. Run the application and verify it displays the initial list of students, with their ages.
Programming in Visual C# 1-49
Results: After completing this exercise, the application will display a students age in years.
1-50 Review of Visual C# Syntaxx
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou learned about
a some off the core features provided by the .NET
T Framework aand
Miicrosoft Visual Studio. Yo
ou also learned
d about some e of the core Visual
V C# co
onstructs that enable you
to start develop
ping .NET Frammework appliccations.
Q
Question
W
What Visual Studio templaate would you
u use to creatte a .dll?
S
Select the corrrect answer.
Conso
ole application
n
Windo
ows Forms application
WPF aapplication
Class library
Ve
erify the correcctness of the statement by placing a maark in the column to the rig
ght.
S
Statement Answer
Q
Question
G
Given the follo
owing for loo
op statement,, what is the value
v of the ccount variable once the
Programming in Visual C# 1-51
Question
loop has finished executing?
var count = 0;
for (int i = 5; i < 12; i++)
{
count++;
}
11
2-1
Module 2
Creating Methods, Handling Exceptions, and Monitoring
Applications
Contents:
Module Overview 2-2
Modu
ule Ove
erview
Ob
bjectives
Aftter completing this module
e, you will be able to:
Handle exce
eptions.
Lesson 1
Creatting an
nd Invoking M
Methodss
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create methods.
Invoke methods.
Debug m
methods.
2-4 Creating Methods, Handling Exceptions, and Moonitoring Applications
W
What Is a M
Method?
The ability to de
efine and call methods is a fundamental component o of object-oriented program mming,
be
ecause method ds enable youu to encapsulaate operationss that protect data that is stored
s inside a type.
Typically, any ap
pplication thaat you develop
p by using thee Microsoft .N
NET Frameworrk and Visual C# C will
have many methods, each wiith a specific p purpose. Some methods arre fundamenta al to the operration of an
ap
pplication. For example, all VVisual C# desktop applications must havve a method ccalled Main th hat defines
the
e entry point for the appliccation. When tthe user runs a Visual C# application, the
e common lan nguage
run
ntime (CLR) exxecutes the Main
M method for that application.
Me e designed for internal use by a type, and as such are hidden from other types. P
ethods can be Public
meethods may be designed too enable other types to request that an o ms an action, and are
object perform
exposed outside
e of the type.
The .NET Frame ework itself is built from classes that expo
ose methods tthat you can ccall from yourr
ap
pplications to iinteract with the
t user and thet computerr.
Programmingg in Visual C# 2-5
5
C
Creating M
Methods
A method com
mprises of two
o elements:
1
1. The meth
hod specificatiion.
2
2. The meth
hod body.
N
Naming Me
ethods
A method nam me has the same syntactic restrictions ass a variable naame. A metho
od must start with
w a letter
o an undersccore and can o
or only contain letters, undersscores, and nuumeric characters. Visual C#
# is case
s
sensitive, so a class can con
ntain two metthods that havve the same n name and diffe
er only in the casing of
o or more lettersalthough this is no
one ot a good coding practice.
I
Implement
ting a Meth
hod Body
The body of a method is a block of code
T emented by using any of th
e that is imple he available Visual C#
p
programming g constructs. T nclosed in braces.
The body is en
Specifying Parameters
Parameters are local variables that are created when the method runs and are populated with values that
are specified when the method is called. All methods must have a list of parameters. You specify the
parameters in parentheses following the method name. Each parameter is separated by a comma. If a
method takes no parameters, you specify an empty parameter list.
For each parameter, you specify the type and the name. By convention, parameters are named by using
camel case.
The following code example shows a method that accepts an int parameter and a Boolean parameter.
When defining the parameters that a method accepts, you can also prefix the parameter definition with
the ref keyword. By using the ref keyword, you instruct the CLR to pass a reference to the parameter and
not just the value of the parameter. You must initialize the ref parameter, and any changes to the
parameter inside the method body will then be reflected in the underlying variable in the calling method.
The following code example shows how to define a parameter by using the ref keyword.
Additional Reading: For more information about the ref keyword, see the ref (C#
Reference) page at http://go.microsoft.com/fwlink/?LinkID=267782.
The following code example shows how to return a string from a method.
Programming in Visual C# 2-7
The expression that the return statement specifies must have the same type as the method. When the
return statement runs, this expression is evaluated and passed back to the statement that called the
method. The method then finishes, so any other statements that occur after a return statement has been
executed will not run.
2-8 Creating Methods, Handling Exceptions, and Moonitoring Applications
In
nvoking M
Methods
Inv
voking a Metthod Passing
g Parameterss
v
var upTime = 2000;
v
var shutdownA
Automaticall
ly = true;
S
StartService(upTime, shu
utdownAutoma
atically);
/
// StartServi
ice method.
v
void StartService(int up
pTime, bool shutdownAuto
omatically)
{
// Perform
m some proce
essing here.
}
If tthe method re
eturns a value
e, you specify how to handlle this value, ttypically by asssigning it to a variable
of the same type, in your calling code.
Ca
apturing a Me
ethod Return
n Value
v
var serviceNa
ame = GetSer
rviceName();
s
string GetServiceName()
{
return "Fo
ourthCoffee.
.SalesServic
ce";
}
Additiona
al Reading: FFor more inforrmation about methods, se ee the Method
ds (C#
Pro
ogramming G
Guide) page att http://go.miicrosoft.com/ffwlink/?LinkID
D=267774.
Programming in Visual C# 2-9
2-10 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Debugging
g Methodss
Whhen you are ddebugging your application n, you can step through cod de one statem
ment at a time e. This is an
exttremely usefu
ul feature becaause it enable
es you to test tthe logic thatt your applicattion uses one step at a
tim
me.
Vissual Studio prrovides a num
mber of debug gging tools thaat enable youu to step throuugh code in exactly the
waay you want to o. For example, you can ste
ep through ea ach line in eacch method thaat is executed, or you
can ignore the sstatements insside a methodd that you knoow are workin ng correctly. Y
You can also sstep over
code completelyy, preventing some statements from exe ecuting.
Wh hen debuggin ng methods, yyou can use thhe following tthree debug fe
eatures to con
ntrol whetherr you step
ovver, step into, o
or step out off a method:
The Step Into feature exeecutes the statement at the e current execcution position
n. If the statemment is a
method call, the current execution po osition will mo
ove to the codde inside the method.
m Afterr you have
stepped intto a method you
y can contin nue executing g statements inside the metthod, one line e at a time.
You can also use the Step p Into button to start an ap
pplication in d
debug mode. If you do thiss, the
application will enter bre
eak mode as ssoon as it startts.
Additionaal Reading: FFor more inforrmation about stepping thrrough code, see
s the Code
Ste
epping Overview page at h
http://go.microosoft.com/fwllink/?LinkID=267783.
Programming in
i Visual C# 2-11
1
D
Demonstr
ration: Crreating, In
nvoking, and Debug
gging Metthods
I this demon
In nstration, you will create a m
method, invokke the method
d, and then debug the metthod.
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA-DEV11-02 virrtual machine..
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 201
12.
6
6. In Visual Studio, on the
e File menu, p n, and then click Project/Solution.
point to Open
7
7. In the Oppen Project dia wse to the E:\\Democode\Starter\FourthC
alog box, brow Coffee.Metho
odTestHarnesss
folder, click FourthCofffee.MethodTeestHarness.sln, and then clicck Open.
8
8. In Visual Studio, on the
e View menu,, click Task Liist.
9
9. In the Tassk List windo
ow, in the Cate
egories list, click Commen
nts.
1 In the cod
11. de editor, click in the blankk line below th
he comment, and then type
e the followin
ng code:
bool Ini
itialize()
{
var p
path = GetAp
pplicationPa
ath();
retur
rn
!s
string.IsNul
llOrEmpty(pa
ath);
}
1 In the cod
13. de editor, click in the blankk line below th
he comment, and then type
e the followin
ng code:
2-12 Creating Methods, Handling Exceptions, and Monitoring Applications
14. Right-click the call to the Initialize method, point to Breakpoint, and then click Insert Breakpoint.
Lesson 2
Creatting Ov
verload
ded Metthods a
and Using Opttional a
and
Outp
put Paraameterrs
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create an
n overloaded method.
Use optio
onal paramete
ers.
Use name
ed argumentss.
Define ou
utput parametters.
2-14 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Crreating Ov
verloaded
d Methodss
The following co
ode example shows three vversions of the
e StopService
e method, all with a unique
e signature.
Ov
verloaded Me
ethods
v
void StopServ
vice()
{
...
}
v
void StopServ
vice(string serviceName
e)
{
...
}
v
void StopServ
vice(int ser
rviceId)
{
...
}
Whhen you invokke the StopSeervice methodd, you have choice of which overloaded version you u use. You
sim t relevant aarguments to satisfy a particular overload
mply provide the d, and then th
he compiler w
works out
wh o invoke based on the argu
hich version to uments that yo ou passed.
Programming in
i Visual C# 2-15
5
C
Creating M
Methods that
t Use Optional
O P
Parameter
rs
By defining ovverloaded me
B ethods, you caan implementt different verssions of a metthod that take
e different
p
parameters. W
When you build an applicattion that uses overloaded m methods, the compiler
c deteermines which
h
s
specific instan
nce of each method it shouuld use to satissfy each meth
hod call.
There are other languages and technolo
T ogies that developers can use for building applications and
c
components tthat do not fo ollow these rules. A key featture of Visual C# is the abillity to interop
perate with
a
applications aand components that are written
w by usin
ng other techn nologies. One of the princip pal
t
technologies tthat Windowss uses is the CComponent Object Model ((COM). COM d does not supp port
o
overloaded m
methods, but in nstead uses methods
m that ccan take optioonal paramete ers. To make it i easier to
i
incorporate C
COM libraries aand compone on, Visual C# also supports optional
ents into a Vissual C# solutio
p
parameters.
D
Defining aM
Method with Optional
O Parrameters
void StopSe
ervice(bool forceStop, string servi
iceName = nu
ull, int serviceId =1)
{
...
}
You can call a method that takes optional parameters in the same way that you call any other method.
You specify the method name and provide any necessary arguments. The difference with methods that
take optional parameters is that you can omit the corresponding arguments, and the method will use the
default value when the method runs.
The following code example shows how to invoke the StopService method, passing only an argument for
the forceStop mandatory parameter.
The following code example shows how to invoke the StopService method, passing an argument for the
forceStop mandatory parameter, and an argument for the serviceName parameter.
C
Calling aM
Method b
by Using Named
N Arrguments
U
Using Named
d Argumentss
StopService
e(true, serv
viceName: "FourthCoffee.
.SalesServic
ce");
When using n
W named arguments in conjun nction with op ptional param
meters, you can easily omit parameters.
A optional parameters will
Any w receive the ue. However, if you omit an
eir default valu ny mandatoryy parameters,
y
your code will not compile.
Crreating M
Methods th
hat Use Ou
utput Paraameters
A method
m can pass
p a value back to the cod de that calls itt by using a re
eturn statemeent. If you nee
ed to
retturn more thaan a single value to the calling code, you u can use outp put parameters to return addditional
data from the m method. When n you add an output param meter to a metthod, the metthod body is e expected to
asssign a value to
o that parame eter. When the method com mpletes, the vvalue of the output parame eter is
asssigned to a vaariable that is specified as the correspond ding argumen nt in the meth
hod call.
To
o define an ou
utput parametter, you prefixx the paramete
er in the meth
hod signature
e with the outt keyword.
The following co
ode example shows how to
o define a metthod that use
es output para
ameters
De
efining Outpu
ut Parameterrs
b
bool IsServicceOnline(str
ring service
eName, out st
tring status
sMessage)
{
var isOnlline = Fourt
thCoffeeServ
vices.GetStat
tus(serviceN
Name);
if (isOnlline)
{
statu
usMessage = "Services is currently running.";
}
else
{
statu
usMessage = "Services is currently stopped.";
}
return issOnline;
}
A method
m can have
h as many output parammeters as requ
uired. When you declare an n output parammeter, you
muust assign a vaalue to the pa
arameter befo
ore the methood returns, oth
herwise the co
ode will not co
ompile.
To
o use an outpu ut parameter, you must pro ovide a variab
ble for the corresponding argument whe en you call
the
e method, and d prefix that aargument with
h the out keyyword. If you aattempt to spe
ecify an argum
ment that is
no
ot a variable or if you omit tthe out keyword, your codde will not com
mpile.
The following co
ode example shows how to
o invoke a me
ethod that acccepts an outpu
ut parameter..
Programming in Visual C# 2-19
Additional Reading: For more information about output parameters, see the out
parameter modifier (C# Reference) page at http://go.microsoft.com/fwlink/?LinkID=267785.
2-20 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Lesson 3
Handlling Excception
ns
In this lesson, yo
ou will learn h
how to implem
ment effective ur applications and how
e exception haandling in you
you can use excceptions in your methods to or condition to the code th
o elegantly indicate an erro hat calls
your methods.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
Throw an exxception.
Programming in
i Visual C# 2-21
1
W
What Is an
n Exceptio
on?
You need
d to know whyy the method call has failed
d, not just that it has failed..
Unexpectted errors such as running o
out of memory cannot be handled in this way.
Traditionally, applications u
T used the conccept of a global error objecct. When a pie
ece of code caaused an
e
error, it would
d set the data in this objectt to indicate th he error and then return to the caller. It
he cause of th
w the respo
was onsibility of the calling code
e to examine the error obje ect and determ
mine how to handle
h it.
H
However, this approach is n not robust, be
ecause it is too
o easy for a p
programmer to o forget to ha
andle errors
a
appropriately .
H
How Excep
ptions Propagate
The .NET Fram
T mework uses e exceptions to help overcomme these issue es. An exceptioon is an indicaation of an
e
error or excep
ptional condittion. A method
d can throw ana exception w when it detectts that something
u
unexpected h
has happened,, for example,, the application tries to op
pen a file that does not exisst.
T Excepttion Type
The
When an exce
W eption occurs,, it is useful to
o include inforrmation about the original cause so thatt the method
t
that handles tthe exception can take the appropriate ccorrective actiion. In the .NEET Frameworkk, exceptions
2-22 Creating Methods, Handling Exceptions, and Monitoring Applications
are based on the Exception class, which contains information about the exception. When a method
throws an exception, it creates an Exception object and can populate it with information about the cause
of the error. The Exception object is then passed to the code that handles the exception.
The following table describes some of the exception classes provided by the .NET Framework.
Additional Reading: For more information about the Exception class, see the Exception
Class page at http://go.microsoft.com/fwlink/?LinkID=267786.
Programming in
i Visual C# 2-23
3
H
Handling Exception
n by Using
g a Try/Caatch Block
k
T
Try/Catch Sy
yntax
try
{
// Try block.
}
catch ([cat
tch specific
cation 1])
{
// Catc
ch block 1.
}
catch ([cat
tch specific
cation n])
{
// Catc
ch block n.
}
The statements that are enclosed in the braces in the try block can be any Visuaal C# statemen
T nts, and can
i
invoke metho ods in other ob o these statements cause an
bjects. If any of a exception to be thrown,, execution
p
passes to the appropriate ccatch block. The catch speccification for e each block dettermines whicch exceptions
i will catch an
it nd the variablle, if any, in w
which to store the exception n. You can spe
ecify catch blo
ocks for
d
different typees of exceptionns. It is good ppractice to incclude a catch block for the general Exceeption type att
t end of the
the e catch blockss to catch all eexceptions thaat have not be een handled otherwise.
o
When defining more than one catch block, you must ensure that you place them in the correct order.
When an exception is thrown, the CLR attempts to match the exception against each catch block in turn.
You must put more specific catch blocks before less specific catch blocks, otherwise your code will not
compile.
Additional Reading: For more information about try/catch blocks, see the try-catch (C#
Reference) page at http://go.microsoft.com/fwlink/?LinkID=267787.
Programming in
i Visual C# 2-25
5
U
Using a Fiinally Blocck
SSome method ds may contain critical code e that must allways be run, even if an unhandled exception occurs.
F example, a method maay need to enssure that it clo
For oses a file thatt it was writing to or releases some
o
other resource
es before it te
erminates. A finally block en
nables you to o handle this situation.
s
You specify a finally block after
Y a any catch handlers in a try/catch block. It specifiies code that must be
p
performed whhen the block finishes, irresspective of wh
hether any excceptions, hand dled or unhanndled, occur.
I an exception is caught an
If nd handled, thhe exception handler in thee catch block will run beforre the finally
b
block.
T
Try/Catch/Fi nally Blocks
try
{
}
catch (NulllReferenceEx
xception ex)
{
// Catc
ch all NullR
ReferenceException excep
ptions.
}
catch (Exceeption ex)
{
// Catc
ch all other
r exceptions.
}
finally
{
// Code that always
s runs.
}
Additioonal Reading: For more infformation abo out try/catch//finally blocks,, see the try-
ccatch-finally ((C# Reference
e) page at http oft.com/fwlinkk/?LinkID=267788.
p://go.microso
2-26 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Th
hrowing E
Exceptionss
Yo
ou can create aan instance off an exceptionn class in yourr code and throw the excepption to indicaate that an
excception has o
occurred. Wheen you throw an a exception, execution of the current b block of code terminates
and the CLR passses control to
o the first available exceptioon handler th
hat catches the
e exception.
o throw an excception, you use
To u the throw
w keyword and
d specify the e
exception object to throw.
The following co
ode example shows how to
o create an insstance of the NullReferencceException class and
the
en throw the ex object.
Creating and T
Throwing an Exception
v
var ex = new NullReferen
nceException
n("The 'Name' parameter is null.");
t
throw ex;
A common
c strattegy is for a m
method or blo
ock of code too catch any exceptions and attempt to ha andle them.
If tthe catch blocck for an exce eption cannot resolve the error, it can retthrow the excception to pro
opagate it
to the caller.
The following co
ode example shows how to
o rethrow an e
exception that has been caught in a catcch block.
Re
ethrowing an
n Exception
t
try
{
}
c
catch (NullRe
eferenceExce
eption ex)
{
// Catch all NullRef
ferenceExcep
ption excepti
ions.
}
c
catch (Except
tion ex)
{
// Attemp
pt to handle
e the except
tion
...
// If thi
is catch han
ndler cannot
t resolve the
e exception,
,
// throw it to the c
calling code
e
throw;
}
Lesson 4
Programming in
i Visual C# 2-27
7
Monitoring Appliccations
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Use loggiing and tracin
ng in your cod
de.
Use perfo
ormance coun
nters to monittor the perform
mance of you
ur application..
2-28 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Ussing Logg
ging and T
Tracing
Byy contrast, devvelopers use tracing to mon nitor the execution of an ap pplication. Wh hen you imple ement
tra
acing, you add d code that wwrites message es to a trace lisstener, which in turn directts your outputt to a
speecified target. By default, yyour trace messsages are sho own in the Ou utput window w in Visual Stu
udio. You
typpically use tracing to providde information about variable values or condition results, to help you y find out
whhy your appliccation behave es in a particullar way. You can
c also use trracing techniq ques to interru
upt the
exeecution of an application in n response to conditions th hat you define e.
W
Writing to th
he Window
ws Event Log
g
Wrriting to the W
Windows even nt log is one o
of the more coommon logging requireme ents you mighht
encounter. The System.Diag gnostics.Even ntLog class proovides various static metho ods that you ccan use to
wrrite to the Win
ndows event log. In particular, the EventtLog.WriteEn ntry method includes severral
ovverloads that yyou can use to
o log various ccombinationss of informatioon. To write to
o the Windowws event
logg, you need too provide a m
minimum of th hree pieces of information:
The event lo
og. This is the name of the Windows eve
ent log you wa o. In most cases you will
ant to write to
write to the
e Application n log.
The messag
ge. This is the text that you want to add tto the log.
Yo
ou can also use
e the WriteEn
ntry method to specify a caategory, an evvent ID, and aan event severrity if
req
quired.
Additiona al Reading: WWriting to the Windows eve ent log requirres a high leveel of
pe
ermissions. If your
y applicatio
on does not run with sufficcient permissio
ons, it will thro
ow a
Se
ecurityExcepttion when you u attempt to create
c an event source or w write to the evvent log.
Programming in Visual C# 2-29
The following example shows how to write a message to the event log:
Additional Reading: For more information on writing to the Windows event log, see the
How to write to an event log by using Visual C# page at
http://go.microsoft.com/fwlink/?LinkID=267789.
The Debug and Trace classes include methods to write format strings to the Output window in Visual
Studio, as well as to any other listeners that you configure. You can also write to the Output window only
when certain conditions are met, and you can adjust the indentation of your trace messages. For example,
if you are writing details of every object within an enumeration to the Output window, you might want to
indent these details to distinguish them from other output.
The Debug and Trace classes also include a method named Assert. The Assert method enables you to
specify a condition (an expression that must evaluate to true or false) together with a format string. If the
condition evaluates to false, the Assert method interrupts the execution of the program and displays a
dialog box with the message you specify. This method is useful if you need to identify the point in a long-
running program at which an unexpected condition arises.
The following example shows how to use the Debug class to write messages to the Output window, and
to interrupt execution if unexpected conditions arise.
Additional Reading: For more information on tracing, see the How to trace and debug in
Visual C# page at http://go.microsoft.com/fwlink/?LinkID=267790.
2-30 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
1. Create and run a perform mance session.. All performaance analysis ttakes place wiithin a perform
mance
session. Youu can create and
a run a perfformance sesssion by launch hing the Perfoormance Wiza ard from
the Analyze e menu in Vissual Studio. W
When the perfoormance sessiion is running g, you run youur
application as you usually would. While your appliccation is runniing, you typically aim to use
functionalitty that you susspect may be causing perfoormance issue es.
o See wh
hich functions consume the
e most CPU tim
me.
o View a timeline that shows what yyour application was doing
g when.
o View w
warnings and ssuggestions on how to imp
prove your cod
de.
3. Revise yourr code and rep peat the analyysis. When your analysis is complete,
c you
u should makee changes
to your cod
de to fix any isssues that you
u identified. Yo
ou can then run a new perfformance sesssion and
generate a new profiling report. The Visual
V Studio P
Profiling Tools enable you to compare tw
wo reports
to help you
u identify and quantify how w the performa ance of your code
c has chan
nged.
Peerformance sessions work by b sampling. W When you creaate a performance session, you can choo ose whether
you want to sam mple CPU use,, .NET memorry allocation, concurrency
c information fo
or multi-threaaded
ap
pplications, or whether you want to use instrumentatio on to collect d
detailed timin
ng informationn about
eveery function ccall. In most caases you will want
w to start b
by using CPU sampling, wh hich is the deffault
opption. CPU sammpling uses sttatistical pollinng to determine which funcctions are usin ng the most CPU
C time.
This provides ann insight into the performance of your application, without consum ming many ressources and
slo
owing down yyour applicatio on.
Programming in Visual C# 2-31
Additional Reading: For more information on application profiling, see the Analyzing
Application Performance by Using Profiling Tools page at
http://go.microsoft.com/fwlink/?LinkID=267791.
2-32 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Ussing Perfo
ormance C
Counters
Pe
erformance coounters are sysstem tools thaat collect information on hoow resources are used. View wing
pe
erformance coounters can prrovide additioonal insights innto what yourr application is doing, and ccan help
you to troublesh
hoot performance problem ms. Performance counters faall into three main groups:
Counters th
hat are provideed by the operrating system and the undeerlying hardwa are platform. T
This group
includes counters that yoou can use to measure proccessor use, ph hysical memorry use, disk usse, and
network usee. The details of the counte will vary accorrding to the hardware that the
ers available w
computer ccontains.
Counters thhat you create yourself. You can create yoour own perfo
ormance coun nters to examiine specific
aspects of tthe behavior o ample, you can create a performance counter to
of your appliccation. For exa
count the n ular method or to count the
number of callls to a particu e number of times a specifiic exception
is thrown.
Brrowsing and
d Using Performance Counters
Peerformance coounters are orgganized into categories.
c This helps you tto find the cou
unters you waant when
you are capturin
ng and review wing performa ance data. Forr example, thee PhysicalDisk category typically
inccludes counte
ers for the percentage of tim
me spent readding and writing to disk, am mounts of data read
om and written to disk, and
fro d the queue leengths to read
d data from an nd write data to disk.
Note: You u can browse the performance counters available on yyour compute er from Visuall
udio. In Server Explorer, exp
Stu pand Serverss, expand the name of yourr computer, an
nd then expannd
Pe
erformance C Counters.
performance counter categories and add multiple performance counters to a graphical display. You can
also create data collector sets to capture data for reporting or analysis.
Check whether specific performance counter categories or performance counters exist on the local
computer.
You typically create custom performance counter categories and performance counters during an
installation routine, rather than during the execution of your application. After a custom performance
counter is created on a specific computer, it remains there. You do not need to recreate it every time you
run your application. To create a custom performance counter, you must specify a base counter type by
using the PerformanceCounterType enumeration.
The following example shows how to programmatically create a custom performance counter category.
This example creates a new performance counter category named FourthCoffeeOrders. The category
contains two performance counters. The first performance counter tracks the total number of coffee
orders placed, and the second tracks the number of orders placed per second.
Note: You can also create performance counter categories and performance counters from
Server Explorer in Visual Studio.
When you have created custom performance counters, your application must provide the performance
counters with data. Performance counters provide various methods that enable you to update the counter
value, such as the Increment and Decrement methods. How the counter processes the value will depend
on the base type you selected when you created the counter.
The following example shows how to programmatically update custom performance counters.
When you have created a custom performance counter category, you can browse to your category and
select individual performance counters in Performance Monitor. When you run your application, you can
then use Performance Monitor to view data from your custom performance counters in real time.
Programming in
i Visual C# 2-35
5
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
2-36 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Lab: E
Extendin
ng the Class E
Enrollment Applicatio
on
Functionality
y
Sccenario
Yo
ou have been asked to refacctor the code that you wro ote in the lab e
exercises for module
m 1 into
o separate
meethods to avo
oid the duplicaation of code in the Class EEnrollment Appplication.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
Password: Pa$$w0rd
P
Programming in Visual C# 2-37
The application currently enables a user to edit a students details by pressing Enter, but you now want
them to also be able to initiate the edit process by double-clicking on a student in the list. You will begin
by creating a new method that contains the code for editing a students details. This will avoid duplicating
and maintaining the code in both event handlers. You will then call the new method from both the
studentsList_MouseDoubleClick and StudentsList_Keydown events.
While doing this, you also decide to refactor the code for adding and deleting students into separate
methods, so that it can be called from other parts of the application if the need arises.
You will then run the application and verify that users can press Enter or double-click on a student to edit
the students details, can press Insert to add a new student, and can press Delete to remove a student.
2. Run the application and verify that the user can now double-click a student to edit their details
3. Use the Analyze Solution for Code Clones wizard to detect the duplicated code
4. Refactor the logic that adds and deletes a student into the addNewStudent and deleteStudent methods
5. Verify that students can still be added and removed from the application
6. Debug the application and step into the new method calls
X Task 1: Copy the code for editing a student into the studentsList_MouseDoubleClick
event handler
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. Start the 20483A-SEA-DEV11-02 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio and open the School.sln solution from the E:\Labfiles\Starter\Exercise 1 folder.
4. In the code for the MainWindow.xaml.cs window, in the studentsList_KeyDown event, locate the
code for editing student details which is in the case Key.Enter block.
5. Copy the code in this block to the clipboard and then paste it into the
StudentsList_MouseDoubleClick method.
X Task 2: Run the application and verify that the user can now double-click a student
to edit their details
1. Build the solution and resolve any compilation errors.
2. Change Kevin Lius last name to Cook by pressing Enter in the main application window.
3. Verify that the updated data is copied back to the students list and that the Save Changes button is
now enabled.
4. Change George Lis name to Darren Parker by double-clicking on his row in the main application
window.
5. Verify that the updated data is copied back to the student list.
6. Close the application.
2-38 Creating Methods, Handling Exceptions, and Monitoring Applications
X Task 3: Use the Analyze Solution for Code Clones wizard to detect the duplicated
code
1. On the Analyze menu, click Analyze Solution for Code Clones.
3. Using the results of the analysis in the Code Clone Analysis Results window, refactor the duplicated
code into a method called editStudent that takes a Student as a parameter.
X Task 4: Refactor the logic that adds and deletes a student into the addNewStudent
and deleteStudent methods
1. Refactor the code in the case Key.Insert code block in the studentsList_KeyDown method into a
method called addNewStudent that takes no parameters.
2. Call this method from the case Key.Insert code block in the studentsList_KeyDown method.
3. Refactor the code in the case Key.Delete code block in the studentsList_KeyDown method into a
method called removeStudent that takes a Student as a parameter.
4. Call this method from the case Key.Delete code block in the studentsList_KeyDown method.
X Task 5: Verify that students can still be added and removed from the application
1. Build the solution and resolve any compilation errors.
3. Add a new student by pressing Insert to display the New Student for Class 3C window, and verify that
it contains no data.
4. Enter details for Dominik Dubicki, whose date of birth is 02/03/2006, and verify that the new
student is added to the students list.
5. Delete the student Run Liu and verify that the prompt window appears and the student is removed
from the student list.
X Task 6: Debug the application and step into the new method calls
1. Add a breakpoint at the start of the switch statement in the studentsList_KeyDown method.
4. Step over the code, watching the Call Stack window and Locals window, until you reach the
editStudent method call, and then step into that method.
8. Step over the code until you reach the addNewStudent method call, and then step into that
method.
12. Step over the code until you reach the removeStudent method call, and then step into that method.
16. In Visual Studio, delete all breakpoints and then close the solution.
Results: After completing this exercise, you should have updated the application to refactor duplicate
code into reusable methods.
2-40 Creating Methods, Handling Exceptions, and Monitoring Applications
Up until this point, almost anything can be entered as student data, and fields can be left blank. This
means, for example, that a student could be added to the student list with no last name or with an invalid
date of birth.
You will write code to check that when adding or editing a student, the first name and last name fields for
the student contain data.
You will also write code to check that the date of birth entered is a valid date and that the student is at
least five years old.
Finally, you will run the application and test your validation code.
1. Run the application and observe that student details that are not valid can be entered
2. Add code to validate the first name and last name fields
4. Run the application and verify that student information is now validated correctly
X Task 1: Run the application and observe that student details that are not valid can be
entered
1. In Visual Studio, from the E:\Labfiles\Starter\Exercise 2 folder, open the School.sln solution.
5. Leave the First Name and Last Name boxes empty, and type 10/06/3012 in the Date of Birth box.
6. Click OK and verify that a new row has been added to the student list, containing a blank first name,
blank last name, and a negative age.
Note: If you enter a date in an invalid format, the application will crash.
X Task 2: Add code to validate the first name and last name fields
1. In the ok_Click method in StudentForm.xaml.cs code, add a statement to check if the First Name
box is empty.
2. If it is empty, display a message box with a caption of Error containing the text The student must
have a first name, and then exit the method.
3. In the ok_Click method in StudentForm.xaml.cs code, add a statement to check if the Last Name
box is empty.
4. If it is empty, display a message box with a caption of Error containing the text The student must
have a last name, and then exit the click method.
Programming in Visual C# 2-41
3. In the ok_Click method in StudentForm.xaml.cs code, add a statement to calculate the students
age in years, and check if the age is less than five years.
4. If the age is less than five years, display a message box with a caption of Error containing the text The
student must at least 5 years old, and then exit the method.
Note: To work out the age in years, use the following formula:
Age in years = Age in Days / 365.25
X Task 4: Run the application and verify that student information is now validated
correctly
1. Build the solution and resolve any compilation errors.
2. Run the application.
4. Leave the First Name, Last Name, and Date of Birth boxes empty.
5. Click OK, verify that an error message appears containing the text The student must have a first
name, then close the error message box.
6. Type Darren into the First Name box, and then click OK.
7. Verify that an error message appears containing the text The student must have a last name, and
then close the error message box.
8. Type Parker into the Last Name box, and then click OK.
9. Verify that an error message appears containing the text The date of birth must be a valid date,
and then close the error message box.
10. Type 10/06/3012 into the Date of Birth box, and then click OK.
11. Verify that an error message appears containing the text The student must be at least 5 years old,
and then close the error message box.
12. Amend the date to 10/06/2006, click OK, and then verify that Darren Parker is added to the student
list with an age appropriate to the current date.
Results: After completing this exercise, student data will be validated before it is saved.
2-42 Creating Methods, Handling Exceptions, and Monitoring Applications
Every time the user closes and opens the application, they are presented with the original student list as it
existed when they first ran the application, regardless of any changes they may have made. You will write
code to save changes back to the database when the user clicks the Save Changes button. You will then
add exception handling code to catch concurrency, update, and general exceptions, and handle the
exceptions gracefully.
Finally, you will run your application and verify that changes you make to student data are persisted
between application sessions.
The main tasks for this exercise are as follows:
4. Run the application and verify that data changes are persisted to the database
X Task 1: Verify that data changes are not persisted to the database
1. In Visual Studio, from the E:\Labfiles\Starter\Exercise 3 folder, open the School.sln solution.
4. Change Kevin Lius last name to Cook by pressing Enter in the main application window.
5. Verify that the updated data is copied to the student list and that the Save Changes button is
enabled.
9. Run the application again and verify that it displays the original list of students, without the changes
that you just made.
2. Add code to perform the following tasks when a user clicks Save Changes:
X Task 3: Add exception handling to the code to catch concurrency, update, and
general exceptions
1. Enclose the lines of code that call the SaveChanges method of the schoolContext object and disable
the Save Changes button in a try block.
Programming in Visual C# 2-43
2. Below the try block, add a catch block to catch any OptimisticConcurrencyException exceptions
that may occur.
// If the user has changed the same students earlier, then overwrite their changes
with the new data
this.schoolContext.Refresh(
RefreshMode.StoreWins, schoolContext.Students);
this.schoolContext.SaveChanges();
4. Add another catch block to catch any UpdateException exceptions that may occur, storing the
exception in a variable named uEx.
// If some sort of database exception has occurred, then display the reason for the
exception and rollback
MessageBox.Show(uEx.InnerException.Message, "Error saving changes");
this.schoolContext.Refresh(RefreshMode.StoreWins, schoolContext.Students);
6. Add another catch block to catch any other type of exception that might occur, storing the exception
in a variable named ex.
X Task 4: Run the application and verify that data changes are persisted to the
database
1. Build the solution and resolve any compilation errors.
2. Run the application.
3. Change Kevin Lius last name to Cook by pressing Enter in the main application window.
6. Click Save Changes and note that the button is disabled when no changes are pending.
8. Run the application and verify that the changes you made to the student data have been saved to the
database and are reflected in the student list.
Results: After completing this exercise, modified student data will be saved to the database
2-44 Creatingg Methods, Handling Exceptions, and M
Monitoring Applicatiions
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou learned how
h to create and use meth hods, and how w to handle exceptions. You also
leaarned how to use logging aand tracing to
o record the details of any e
exceptions tha
at occur.
Ve
erify the correcctness of the statement by placing a maark in the column to the rig
ght.
S
Statement Answer
T return typ
The pe of a metho
od forms part of a methodss signature.
Q
Question
W
When using ooutput parameters in a me
ethod signature, which one
e of the follow
wing
statements is true?
S
Select the corrrect answer.
You m
must assign a vvalue to an ou
utput parametter before the
e method retu
urns.
You de
efine an output parameter by using the output keywo
ord.
Ve
erify the correcctness of the statement by placing a maark in the column to the rig
ght.
S
Statement Answer
Ve
erify the correcctness of the statement by placing a maark in the column to the rig
ght.
Programming in Visual C# 2-45
Statement Answer
Trace statements are active in both Debug and Release mode builds.
3-1
Module 3
Developing the Code for a Graphical Application
Contents:
Module Overview 3-2
Lab: Writing the Code for the Grades Prototype Application 3-41
Modu
ule Ove
erview
In this module, yyou will learn how to creatte and use stru
ucts and enum
ms, organize d
data into colle
ections, and
eate and subscribe to eventts.
cre
Ob
bjectives
Aftter completing this module
e, you will be able to:
Create and use structs an
nd enums.
Lesson 1
Implementiing Stru
ucts and
d Enum
ms
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create an
nd use enums.
Create an
nd use structs..
Define co
onstructors to instantiate sttructs.
Create prroperties to ge
et and set field values in a sstruct.
Create ind
dexers to expose struct me
embers by usin
ng an integerr index.
3-4 Developinng the Code for a Graphical Applicationn
Crreating an
nd Using E
Enums
An
n enumeration n type, or enu ure that enablles you to create a variable
um, is a structu e with a fixed sset of
po
ossible values. The most com mmon examp ple is to use an
n enum to deffine the day oof the week. There are
on
nly seven posssible values for days of the w
week, and you can be reasonably certain n that these vvalues will
ne
ever change.
eclaring an En
De num
e
enum Day { Su
unday, Monda
ay, Tuesday, Wednesday, Thursday, F
Friday, Satu
urday };
To
o use the enum
m, you create an instance o
of your enum variable and sspecify which enum memb
ber you
waant to use.
Ussing an Enum
m
D
Day favoriteD
Day = Day.Fr
riday;
Ussing enums haas several advantages over using text or numerical typ
pes:
Improved manageability.
m . By constrainiing a variable to a fixed sett of valid value
es, you are lesss likely to
experience invalid argum
ments and speelling mistakess.
Improved developer
d expeerience. In Visu e IntelliSense feature will prompt you with the
ual Studio, the
available va
alues when yo
ou use an enum.
Improved co
ode readability
ty. The enum syntax
s makes your code ea
asier to read aand understan
nd.
Each member o of an enum haas a name and d a value. The name is the sstring you deffine in the braaces, such as
Sunday or Mond day. By default, the value iss an integer. If you do not specify a value for each meember, the
me mental values starting with 0. For example, Day.Sunday is equal to
embers are asssigned increm o 0 and
Da
ay.Monday iss equal to 1.
Reference Links: For more information about enums, see the Enumeration Types (C#
Programming Guide) page at http://go.microsoft.com/fwlink/?LinkID=267792.
3-6 Developinng the Code for a Graphical Applicationn
Crreating an
nd Using S
Structs
A struct nam
med Circle might consist o
of fields to rep
present an x-coordinate, a yy-coordinate, and a
radius.
med Color might consist of fields to rep
A struct nam present a red ccomponent, a green compo
onent, and
a blue component.
Crreating a Sttruct
Yo
ou use the stru
uct keyword tto declare a sttruct, as show
wn by the follo
owing example:
De
eclaring a Strruct
p
public struct
t Coffee
{
public int
t Strength;
public string Bean;
public string Country
yOfOrigin;
// Other m
methods, fie
elds, proper
rties, and ev
vents.
}
A
Access Modifiier Detailss
p
public The tyype is available to code run
nning in any assembly.
i
internal The tyype is available to any code
e within the saame assemblyy, but not avaiilable to
code in
i another asssembly. This iss the default vvalue if you do
o not specify an access
modiffier.
Programming in Visual C# 3-7
private The type is only available to code within the struct that contains it. You can only
use the private access modifier with nested structs.
Structs can contain a variety of members, including fields, properties, methods, and events.
Using a Struct
To create an instance of a struct, you use the new keyword, as shown by the following example:
Instantiating a Struct
Coffee coffee1 = new Coffee();
coffee1.Strength = 3;
coffee1.Bean = "Arabica";
coffee1.CountryOfOrigin = "Kenya";
3-8 Developinng the Code for a Graphical Applicationn
In
nitializing Structs
Yo
ou might have e noticed that the syntax fo
or instantiating
g a struct, for example, new w Coffee(), is similar to
the
e syntax for ca
alling a metho
od. This is beccause when yo ou instantiate
e a struct, you are actually ccalling a
spe
ecial type of m
method calledd a constructoor. A constructtor is a metho
od in the strucct that has the
e same
name as the struuct.
Whhen you instantiate a structt with no arguuments, such as new Coffe ee(), you are ccalling the deffault
con by the Visual C# compiler. If you want to
nstructor whicch is created b o be able to specify defaultt field
values when you u instantiate a struct, you can
c add constructors that aaccept parame eters to your sstruct.
Ad
dding a Consstructor
p
public struct
t Coffee
{
// This is
s the custom
m constructo
or.
public Cof
ffee(int str
rength, string bean, string country
yOfOrigin)
{
this.St
trength = st
trength;
this.Be
ean = bean;
this.Co
ountryOfOrig
gin = countr
ryOfOrigin;
}
// These st
tatements de
eclare the s
struct fields
s and set th
he default v
values.
public int
t Strength;
public string Bean;
public string Country
yOfOrigin;
// Other m
methods, fie
elds, proper
rties, and ev
vents.
}
Ca
alling a Consttructor
/
// Call the c
custom const
tructor by p
providing arg
guments for the three r
required para
ameters.
C
Coffee coffee
e1 = new Cof
ffee(4, "Ara
abica", "Colu
umbia");
Yo
ou can add mu ultiple constru
uctors to yourr struct, with e
each constructtor accepting a different co
ombination
However, you cannot add a default consstructor to a struct because
of parameters. H e it is created by the
compiler.
Programming in Visual C# 3-9
3-10 Developping the Code for a Graphical Applicatioon
Crreating Prroperties
Im
mplementing a Property
p
public struct
t Coffee
{
private in
nt strength;
;
public int
t Strength
{
get { return stren
ngth; }
set { s
strength = v
value; }
}
}
Ussing a Properrty
C
Coffee coffee
e1 = new Cof
ffee();
/
// The follow
wing code in
nvokes the s
set accessor.
c
coffee1.Stren
ngth = 3;
/
// The follow
wing code in
nvokes the g
get accessor.
int coffeeStrength = cof
ffee1.Streng
gth;
Programming in Visual C# 3-11
The client code uses the property as if as it was a public field. However, using public properties to expose
private fields offers the following advantages over using public fields directly:
You can use properties to control external access to your fields. A property that includes only a get
accessor is read-only, while a property that includes only a set accessor is write-only.
You can change the implementation of properties without affecting client code. For example, you can
add validation logic, or call a method instead of reading a field value.
Properties are required for data binding in WPF. For example, you can bind controls to property
values, but you cannot bind controls to field values.
When you want to create a property that simply gets and sets the value of a private field without
performing any additional logic, you can use an abbreviated syntax.
To create a property that reads and writes to a private field, you can use the following syntax:
To create a property that reads from a private field, you can use the following syntax:
To create a property that writes to a private field, you can use the following syntax:
In each case, the compiler will implicitly create a private field and map it to your property. These are
known as auto-implemented properties. You can change the implementation of your property at any time.
C
Creating IIndexers
C
Creating a Sttruct that Inccludes an Arrray
public stru
uct Menu
{
public s
string[] bev
verages;
public M
Menu(string bev1, string bev2)
{
bever
rages = new string[] { "Americano",
, "Caf au Lait",
L "Caf Macchiato",
"Cappuccino
o", "Espress
so" };
}
}
A
Accessing Arrray Items Directly
Menu myMenu
u = new Menu
u();
string firs
stDrink = my
yMenu.beverages[0];
A more intuitiive approach would be if you could acce ess the first ite
em from the m menu by using g the syntax
m
myMenu[0]. You can do th
his by creatingg an indexer. An indexer is similar to a pproperty, in that it uses get
a set accesssors to contro
and ol access to a field.
f More im
mportantly, an n indexer enab bles you to access
c
collection members directlyy from the naame of the con ntaining strucct or class by p
providing an integer
i index
v
value. To decllare an indexe
er, you use thee this keyworrd, which indiccates that the property will be accessed
b using the n
by name of the struct instance e.
3-14 Developing the Code for a Graphical Application
Creating an Indexer
public struct Menu
{
private string[] beverages;
// This is the indexer.
public string this[int index]
{
get { return this.beverages[index]; }
set { this.beverages[index] = value; }
}
// Enable client code to determine the size of the collection.
public int Length
{
get { return beverages.Length; }
}
}
When you use an indexer to expose the array, you use the following syntax to retrieve the beverages from
the list:
Just like a property, you can customize the get and set accessors in an indexer without affecting client
code. You can create a read-only indexer by including only a get accessor, and you can create a write-
only indexer by including only a set accessor.
Reference Links: For more information about indexers, see the Using Indexers (C#
Programming Guide) page at http://go.microsoft.com/fwlink/?LinkID=267794.
Programming in
i Visual C# 3-15
5
D
Demonstr
ration: Crreating an
nd Using a Struct
IIn this demon nstration, you will create a sstruct named Coffee and aadd several prroperties to th
he struct. You
w then creatte an instance
will e of the Coffeee struct, set some
s propertyy values, and display these property
v
values in a console windoww.
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA-DEV11-03 virrtual machine..
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Visual Studio, on the
e File menu, p
point to New,, and then clicck Project.
7
7. In the Ne ew Project dia
alog box, in th
he Templatess list, click Vissual C#, and tthen in the Prroject Type
list, click Console
C Appplication.
8
8. In the Na
ame box, type
e UsingStructts
9
9. In the Loccation box, se
et the location
n to E:\Demo
ocode, and then click OK.
struct C
Coffee
{
publi
ic string Na
ame { get; set; }
publi
ic string Be
ean { get; set; }
publi
ic string Co
ountryOfOrigin { get; se
et; }
publi
ic int Stren
ngth { get; set; }
}
3-16 Developing the Code for a Graphical Application
11. In the Program class, in the Main method, add the following code:
12. Notice that you are able to use the Coffee struct in the same way that you would use a standard .NET
Framework type.
15. Notice that the Coffee struct works just like a standard .NET Framework type at runtime.
Lesson 2
Orga
anizing Data in
nto Collection
ns
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Choose appropriate co different scenarios.
ollections for d
Manage items
i in a colllection.
Ch
hoosing C
Collectionss
Count the n
number of items in the collection.
Eveery collection class in Visuaal C# providess methods and d properties tthat support these core ope erations.
Be
eyond these operations, how wever, you wiill want to maanage collectio ons in differennt ways depennding on
the
e specific requuirements of your
y applicatiion. Collection
n classes in Visual C# fall into the followiing broad
cattegories:
Wh
hen you choo
ose a built-in ccollection classs for a specifiic scenario, assk yourself the
e following qu
uestions:
Programming in Visual C# 3-19
If you are using a dictionary class, will you need to retrieve items by index as well as by key?
If you can answer all of these questions, you will be able to select the Visual C# collection class that best
meets your needs.
3-20 Developping the Code for a Graphical Applicatioon
C
Class Descrription
A
ArrayList The AArrayList is a general-purp
pose list that sstores a linearr collection off objects.
The AArrayList includes method ds and properrties that enab ble you to add d items,
remoove items, couunt the numbber of items in the collection n, and sort the
colle
ection.
B
BitArray The BitArray is a list class that represents a collection
c of b
bits as Boolean values.
The BitArray is m
most commonlly used for bittwise operatio ons and Boole ean
hmetic, and includes metho
arith ods to performm common Bo oolean operattions such
as AND, NOT, and d XOR.
H
Hashtable The Hashtable claass is a generaal-purpose dictionary classs that stores a collection
ey/value pairss. The Hashtable includes m
of ke methods and properties thaat enable
you to retrieve ite
ems by key, addd items, remove items, and check for particular
keys and values wwithin the colle
ection.
Q
Queue The Queue class is a first in, lasst out collectio
on of objects. The Queue in
ncludes
methhods to add oobjects to the back of the q queue (Enqueue) and retrieeve objects
from
m the front of the queue (Dequeue).
S
SortedList The SortedList claass stores a coollection of ke
ey/value pairs that are sorte
ed by key.
ddition to the functionality provided by the Hashtablle class, the So
In ad ortedList
enabbles you to rettrieve items either by key or
o by index.
S
Stack The Stack class is a first in, firstt out collection of objects. T
The Stack includes
meth hods to view the
t top item iin the collectio on without reemoving it (Peeek), add
an ittem to the top
p of the stack (Push), and rremove and re eturn the item
m at the top
of th
he stack (Pop)).
Programming in Visual C# 3-21
Reference Links: For more information about the classes listed in the previous table, see
the System.Collections Namespace page at http://go.microsoft.com/fwlink/?LinkID=267795.
3-22 Developping the Code for a Graphical Applicatioon
Sp
pecialized Collectio
on Classes
The System.Collections.Spe ecialized namespace provid des collection classes that aare suitable fo
or more
spe
ecialized requ
uirements, succh as specializzed dictionaryy collections and strongly tyyped string co ollections.
The following taable shows the most imporrtant collection classes in th he System.Co ollections.Spe ecialized
namespace:
C
Class Descriptio
on
L
ListDictionar
ry The LListDictionary y is a dictionaary class that is optimized foor small
collecctions. As a ge
eneral rule, if yyour collectio
on includes 10 0 items or
fewerr, use a ListDiictionary. If yyour collectionn is larger, use
ea
Hashhtable.
H
HybridDictio
onary The HybridDiction
H nary is a dictionary class th
hat you can usse when
you cannot
c estimate the size of the collectionn. The HybriddDictionary
uses a ListDictionaary implemen ntation when the collectionn size is
small, and switchess to a Hashtaable implemen ntation as the
e collection
size g
grows larger.
O
OrderedDicti
ionary The OrderedDictio
O onary is an in
ndexed diction
nary class thatt enables
you to retrieve item ms by key or by
b index. Note that unlike tthe
SorteedList class, ittems in an OrdderedDiction nary are not ssorted by
key.
N
NameValueC
Collection The NameValueCo
N ollection is an indexed dicctionary class iin which
both the key and tthe value are strings.
s The N
NameValueCo ollection
will th
hrow an errorr if you attemppt to set a keyy or a value to
o anything
otherr than a string
g. You can retrrieve items byy key or by inddex.
S
StringCollect
tion The StringCollecti
S ion is a list claass in which e
every item in tthe
collecction is a strin
ng. Use this claass when you want to store e a simple,
linearr collection off strings.
S
StringDiction
nary The StringDiction
S nary is a dictio
onary class in which both thhe key and
the vaalue are string
gs. Unlike the NameValueC Collection cla
ass, you
cannoot retrieve items from a StrringDictionarry by index.
Programming in Visual C# 3-23
Class Description
BitVector32 The BitVector32 is a struct that can represent a 32-bit value as both
a bit array and an integer value. Unlike the BitArray class, which can
expand indefinitely, the BitVector32 struct is a fixed 32-bit size. As a
result, the BitVector32 is more efficient than the BitArray for small
values. You can divide a BitVector32 instance into sections to
efficiently store multiple values.
Reference Links: For more information about the classes and structs listed in the previous
table, see the System.Collections.Specialized Namespace page at
http://go.microsoft.com/fwlink/?LinkID=267796.
3-24 Developping the Code for a Graphical Applicatioon
Ussing List C
Collections
The most comm monly used listt collection is the ArrayListt class. The ArrrayList storees items as a linear
collection of objjects. You cann add objects of any type to o an ArrayLisst collection, b
but the Array yList
reppresents each item in the ccollection as a System.Obje ect instance. W
When you add d an item to aan
ArrrayList collecction, the ArraayList implicittly casts, or co
onverts, your item to the O
Object type. W When you
rettrieve items frrom the collecction, you must explicitly caast the object back to its orriginal type.
The following exxample showss how to add and retrieve iitems from an
n ArrayList co
ollection:
Ad
dding and Re
etrieving Item
ms from an A
ArrayList
/
// Create a n
new ArrayLis
st collectio
on.
A
ArrayList bev
verages = ne
ew ArrayList
t();
/
// Create som
me items to add to the collection.
C
Coffee coffee
e1 = new Cof
ffee(4, "Ara
abica", "Coluumbia");
C
Coffee coffee
e2 = new Cof
ffee(3, "Ara
abica", "Viettnam");
C
Coffee coffee
e3 = new Cof
ffee(4, "Rob
busta", "Indoonesia");
/
// Add the it
tems to the collection.
/
// Items are implicitly cast to the
e Object typee when you a
add them.
b
beverages.Add
d(coffee1);
b
beverages.Add
d(coffee2);
b
beverages.Add
d(coffee3);
/
// Retrieve i
items from t
the collection.
/
// Items must
t be explici
itly cast ba
ack to their original tyype.
C
Coffee firstC
Coffee = (Co
offee)bevera
ages[0];
C
Coffee second
dCoffee = (C
Coffee)bever
rages[1];
Reference Links: For more information on the ArrayList class, see the ArrayList Class page
at http://go.microsoft.com/fwlink/?LinkID=267797.
3-26 Developping the Code for a Graphical Applicatioon
Dicctionary classe
es store collecctions of key//value pairs. Th
he most comm monly used dictionary classs is the
Haashtable. Whe en you add an n item to a Ha ashtable colle must specify a key and a value. Both
ection, you m
the
e key and the value can be e instances of any type, but the Hashtab ble implicitly ccasts both the key and
the
e value to thee Object type.. When you re etrieve values from the collection, you mmust explicitly cast the
ob
bject back to itts original typ
pe.
The following exxample showss how to add and retrieve iitems from a Hashtable
H co
ollection. In th
his case
bo
oth the key an
nd the value are strings:
Ad
dding and Re
etrieving Item
ms from a Ha
ashtable
/
// Create a n
new Hashtabl
le collectio
on.
H
Hashtable ing
gredients = new Hashtab
ble();
/
// Add some k
key/value pa
airs to the collection.
ingredients.A
Add("Caf au
u Lait", "Co
offee, Milk"));
ingredients.A
Add("Caf Mo
ocha", "Coff
fee, Milk, Chhocolate");
ingredients.A
Add("Cappucc
cino", "Coff
fee, Milk, Fooam");
ingredients.A
Add("Irish C
Coffee", "Co
offee, Whiskeey, Cream, S
Sugar");
ingredients.A
Add("Macchia
ato", "Coffe
ee, Milk, Foaam");
/
// Check whet
ther a key e
exists.
if(ingredient
ts.ContainsK
Key("Caf Mo
ocha"))
{
// Retriev
ve the value
e associated
d with a key.
Console.WriteLine("Th
he ingredien
nts of a Caf Mocha are:
: {0}", ingr
redients["Caf
f
M
Mocha"]);
}
Dicctionary classe
es, such as the
e Hashtable, actually contain two enum merable collecttionsthe ke eys and the
values. You can iterate over e either of these
e collections. In
I most scenaarios, howeverr, you are likelly to iterate
thrrough the keyy collection, fo
or example too retrieve the value
v associatted with each key in turn.
Reference Links: For more information on the Hashtable class, see the Hashtable Class
page at http://go.microsoft.com/fwlink/?LinkID=267798.
3-28 Developping the Code for a Graphical Applicatioon
Querying a Collectio
on
LINNQ is a query technology that is built in to .NET languuages such as Visual C#. LIN
NQ enables yoou to use a
staandardized, deeclarative que
ery syntax to q
query data froom a wide ran
nge of data soources, such ass .NET
collections, SQLL Server databbases, ADO.NE ET datasets, an
nd XML docum ments. A basicc LINQ query uses the
folllowing syntaxx:
fro
om <variable names> in <data source>
wh
here <selectio
on criteria>
orderby <resultt ordering critteria>
The following exxample showss how to use a LINQ expresssion to queryy a Hashtable
e:
}
Console.ReadLine();
Note: Appending the suffix m or M to a number indicates that the number should be
treated as a decimal type.
In addition to this basic query syntax, you can call a variety of methods on your query results. For
example:
Call the FirstOrDefault method to get the first item from the results collection, or a default value if
the collection contains no results. This method is useful if you have ordered the results of your query.
Call the Last method to get the last item from the results collection. This method is useful if you have
ordered the results of your query.
Call the Max method to find the largest item in the results collection.
Call the Min method to find the smallest item in the results collection.
Note: Most built-in types provide methods that enable you to compare one instance to
another to determine which is considered larger or smaller. The Max and Min methods rely on
these methods to find the largest or smallest items. If your collection contains numerical types,
these methods will return the highest and lowest values, respectively. If your collection contains
strings, members are compared alphabeticallyfor example, "Z" is considered greater than "A". If
your collection contains custom types, the Max and Min methods will use the comparison logic
created by the type developer.
For example, if you have ordered your results by ascending cost, the first item in the results collection will
be the cheapest and the last item in the results collection will be the most expensive. As such, you can use
the FirstOrDefault and Last methods to find the cheapest and most expensive drinks, respectively.
The following example shows how to retrieve the smallest and largest items from a collection based on
the sort criteria in the LINQ expression:
Note: The return type of a LINQ expression is IEnumerable<T>, where T is the type of the
items in the collection. IEnumerable<T> is an example of a generic type. The methods you use
on a results set, such as FirstOrDefault, Last, Max, and Min, are extension methods. Generic
types and extension methods are covered later in this course.
3-30 Developing the Code for a Graphical Application
Reference Links: For more information about using LINQ to query collections, see the
LINQ Query Expressions (C# Programming Guide) page at
http://go.microsoft.com/fwlink/?LinkID=267799.
Programming in
i Visual C# 3-31
1
Lesson 3
Hand
dling Ev
vents
Events are me
E echanisms thaat enable obje other objects when someth
ects to notify o hing happens.. For example,,
c
controls on a web page or in a WPF user interface generate eventss when a user interacts with h the control,
s
such as by cliccking a button
n. You can cre
eate code that subscribes to
o these eventss and takes so
ome action in
r
response to an event.
Without events, your code would need tto constantly read control values
W v to lookk for any channges in state
t
that require action. This wo
ould be a veryy inefficient way of developping an appliccation. In this lesson, you
w learn how
will w to create, or raise, events, and how to ssubscribe to e
events.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create evvents and dele
egates.
Raise events.
Subscribe
e to events an
nd unsubscribe
e from eventss.
3-32 Developping the Code for a Graphical Applicatioon
Crreating Ev
vents and Delegates
Create a me
ethod with a signature
s thatt matches the
e event delegaate. This meth
hod is known aas the event
handler.
Wh e delegate invokes all the evvent handler methods thatt have subscribed to the
hen the eventt is raised, the
eve
ent.
Suppose you cre eate a struct n
named Coffeee. One of the responsibilitie
es of this strucct is to keep ttrack of the
sto
ock level for e
each Coffee in nstance. When
n the stock levvel drops belo
ow a certain ppoint, you mig ght want to
raise an event too warn an orddering system that you are running out o of beans.
The first thing yyou need to doo is to define a delegate. To define a delegate, you usse the delega
ate
keyyword. A dele egate includess two parameters:
In this example, you define an event named OutOfBeans. You associate a delegate named
OutOfBeansHandler with your event. The OutOfBeansHandler delegate takes two parameters, an
instance of Coffee that will represent the object that raised the event and an instance of EventArgs that
could be used to provide more information about the event.
3-34 Developping the Code for a Graphical Applicatioon
Raaising Eve
ents
aising an Even
Ra nt
p
public struct
t Coffee
{
// Declare
e the event and the delegate.
public Eve
entArgs e = null;
public del
legate void OutOfBeansH
Handler(Coffe
ee coffee, E
EventArgs ar
rgs);
public eve
ent OutOfBea
ansHandler O
OutOfBeans;
int curren
ntStockLevel
l;
int minimu
umStockLevel
l;
public voi
id MakeCoffe
ee()
{
// Decrement the s
stock level.
current
tStockLevel-
--;
// If t
the stock le
evel drops b
below the min
nimum, raise
e the event.
if (currentStockLe
evel < minim
mumStockLevel
l)
{
// C
Check whethe
er the event
t is null.
if (OutOfBeans != null)
{
/
// Raise the
e event.
O
OutOfBeans(t
this, e);
}
}
}
Programming in Visual C# 3-35
To raise the event, you use a similar syntax to calling a method. You provide arguments to match the
parameters required by the delegate. The first argument is the object that raised the event. Note how the
this keyword is used to indicate the current Coffee instance. The second parameter is the EventArgs
instance, which can be null if you do not need to provide any other information to subscribers.
3-36 Developping the Code for a Graphical Applicatioon
Su
ubscribing
g to Eventts
Create a me
ethod with a signature
s thatt matches the
e delegate for the event.
For example, suppose you haave created ann instance of tthe Coffee strruct named co
offee1. In you
ur
ventory class, you want to subscribe to the OutOfBe
Inv eans that mayy be raised by coffee1.
e previous top
Note: The pic shows howw the Coffee sstruct, the OutOfBeans eve
ent, and the
Ou
utOfBeansHaandler delegaate are defined
d.
ubscribing to an Event
Su
p
public class Inventory
{
public void
d HandleOutO
OfBeans(Coff
fee sender, E
EventArgs ar
rgs)
{
string coffeeBean = sender.Be
ean;
// Reorder the cof
ffee bean.
}
public voi
id Subscribe
eToEvent()
{
coffee1
1.OutOfBeans
s += HandleO
OutOfBeans;
}
}
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
3. Log on to W
Windows 8 as Student with
h the password Pa$$w0rd.
6. udio, on the F
In Visual Stu a then clickk Project/Solution.
File menu, point to Open, and
7. In the Open
n Project diallog box, brow
wse to the E:\D
Democode\Starter folder, click
EventsAnddXAML.sln, an nd then click Open.
O
Note: The
e Events butto
on is marked with a lightning icon.
12. Notice that the Propertiies window no ents to which you can subscribe.
ow displays a list of the eve
perties window
13. In the Prop w, double-clicck inside the C
Click text boxx.
Programming in Visual C# 3-39
14. Notice that Visual Studio creates an event handler method for you and switches to the code behind
page.
lblShowTime.Content = DateTime.Now.ToLongTimeString();
16. In Solution Explorer, expand MainWindow.xaml, expand MainWindow.xaml.cs, and then double-
click MainWindow.
17. Switch back to the MainWindow.xaml window.
18. In the Button element, note that the designer has added the following attribute:
Click="btnGetTime_Click"
20. Near the bottom of the file, notice that Visual Studio has added the following line of code:
this.btnGetTime.Click += new
System.Windows.RoutedEventHandler(this.btnGetTime_Click);
This demonstrates that Visual Studio parses the XAML to create the code that subscribes your event
handler method to the Click event of the button.
In this demonstration, you wiill learn aboutt the tasks thaat you will perrform in the laab for this mo
odule.
Programming in
i Visual C# 3-41
1
S
Scenario
The School off Fine Arts hass decided thatt they want to
T o extend their basic class en nrollment app plication to
e
enable teacheers to record tthe grades thaat students in their class haave achieved ffor each subje ect, and to
a
allow students to view their own grades.. This function nality necessittates impleme enting applicaation log on
f
functionality tto authenticatte the user an
nd to determin ne whether th he user is a teaacher or a student.
You decide to
Y o start by deve
eloping parts of a prototyppe application to test prooff of concept and to obtain
c
client feedbacck before emb barking on the ototype appliccation will use basic WPF
e final applicaation. The pro
v
views rather than separate forms for the
e user interface. These views have alreadyy been design ned and you
m
must add the code to naviggate among them.
O
Objectives
A
After completting this lab, you
y will be able to:
Navigate among viewss.
Create an
nd use collectiions of structss.
Handle evvents.
E
Estimated Tim
me: 60 minutes
3A-SEA-DEV11-03, MSL-TM
Virtual Machine: 20483 MG1
User Nam
me: Student
Password
d: Pa$$w0rd
3-42 Developing the Code for a Graphical Application
First, you will examine the window and views in the application so that you are familiar with the existing
structure of the application.
You will define a public event handler named LogonSuccess that will be raised when a user successfully
logs on to the application. You will add dummy code to the Logon_Click event handler to store the
username and role of the logged on user and raise the LogonSuccess event. Then you will add markup to
the LogonPage XAML code to connect the Logon button to the Logon_Click event handler.
Next, you will add code to the GotoLogon method to display the logon view and to hide the other views.
You will implement the Logon_Success method to handle a successful log on by displaying the logged
on views, and then you will add markup to the MainWindow XAML code to connect the LogonSuccess
event to the Logon_Success method.
You will add code to the MainWindow to determine whether the user is a teacher or a student, display
their name in the application, and display either the StudentsPage view for teachers or the
StudentProfile view for students.
You will then add code to the StudentsPage view that catches a student name being clicked and raises
the StudentSelected event for that student and displays their student profile.
Finally, you will run the application and verify that the appropriate views are displayed for students and
teachers upon a successful log on.
2. Start the 20483A- SEA-DEV11-03 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio and open the GradesPrototype.sln solution from the
E:\Labfiles\Starter\Exercise 1 folder.
5. Review MainWindow.xaml, which is the main window for the application and will host the following
views:
LogonPage.xaml
StudentProfile.xaml
StudentsPage.xaml
Programming in Visual C# 3-43
6. In the Views folder, review the LogonPage.xaml. Notice that this view contains text boxes for the
username and password, a check box to identify the user as a teacher, and a button to log on to the
application.
7. In the Views folder, review the StudentProfile.xaml. Notice that this view contains a Report Card
that currently displays a list of dummy grades. The view also contains a Back button and a blank
space that will display the students name. This view is displayed when a student logs on or when a
teacher views a students profile.
8. In the View folder, review the StudentsPage.xaml. Notice that this view contains the list of students
in a particular class. This view is displayed when a teacher logs on. A teacher can click a student and
the Students Profile view will be displayed, containing the selected students data.
X Task 2: Define the LogonSuccess event and add dummy code for the Logon_Click
event
1. In the LogonPage.xaml.cs class, in the Event Members region, define a public event handler named
LogonSuccess.
2. In the Logon Validation region, add an event handler for the Logon_Click event, which takes an
object parameter named sender and a RoutedEventArgs parameter named e.
a. Save the username and role that the user specified on the form in the relevant properties of the
SessionContext object.
b. If the user is a student, set the CurrentStudent property of the SessionContext object to the
string Eric Gruber.
e. Modify the definition to call the Logon_Click method when the button is clicked.
2. In the Event Handlers region, add code to the Logon_Success method to handle a successful log on.
This method should take an object parameter named sender and an EventArgs parameter named e.
The method should update the display and show the data for the logged on user.
3. In the MainWindow.xaml XAML editor, locate the definition of the LogonPage page.
4. Modify the definition to call the Logon_Success method for the LogonSuccess event.
3. In the GotoStudentsPage method, add code to hide the studentProfile view, and then add code to
display and refresh the studentsPage view.
a. Parse the student name into the first name and last name by using a regular expression.
Note: You can use the following code to parse the name:
Match matchNames = Regex.Match(SessionContext.CurrentStudent, @"([^ ]+) ([^ ]+)");
b. If a name is successfully parsed, display the first name and last name of the student in the
appropriate boxes.
5. If the user is a student, hide the btnBack button, or if the user is a teacher, display the btnBack
button.
5. In the MainWindow.xaml XAML editor, locate the definition of the StudentsPage page.
6. Modify the definition to call the studentsPage_StudentSelected method for the StudentSelected
event.
8. Verify that the application displays the student profile page for Eric Gruber.
Results: After completing this exercise, you should have updated the Grades Prototype application to
respond to user events and move among the application views appropriately.
3-46 Developing the Code for a Graphical Application
You will then add a unit test project to the solution to test the creation and use of the structs. You will run
these tests and verify that the structs function as expected.
X Task 1: Define basic structs for holding Grade, Student, and Teacher information
1. Open the GradesPrototype solution from the E:\Labfiles\Starter\Exercise 2 folder.
3. In the GradesPrototype.Data namespace, create a struct named Grade that contains the following
fields:
StudentID as an integer
AssessmentDate as a string
Assessment as a string
Comments as a string
4. In the GradesPrototype.Data namespace, create a struct named Student that contains the
following fields:
StudentID as an integer
UserName as a string
Password as a string
TeacherID as an integer
FirstName as a string
LastName as a string
5. In the GradesPrototype.Data namespace, create a struct named Teacher that contains the
following fields:
TeacherID as an integer
UserName as a string
Password as a string
FirstName as a string
LastName as a string
Class as a string
X Task 2: Add unit tests to create and use the collections of structs
1. Add a Unit Test Project called GradesTest to the solution and reference the GradesPrototype
project from it.
Programming in Visual C# 3-47
3. Add a using directive to the GradesUnitTests file to bring the GradesPrototype.Data namespace
into scope.
StudentTest test method: To create a new student by using the following information, and then
verify that it is created correctly.
Field Value
FirstName Eric
LastName Gruber
UserName grubere
Password password
TeacherTest test method: To create a new teacher by using the following information, and then
verify that it is created correctly.
Field Value
FirstName Esther
LastName Valle
UserName vallee
Password password
Class 3A
createGrade method: Takes an assessment, a subject, and a comments arguments, creates a new
Grade object from them and the current date, and returns the Grade object.
GradeTest test method: To create a new grade by passing the following information to the
createGrade method, and then verify that it is created correctly.
Argument Value
assessment B+
subject Math
comments Good
GradeCollectionTest test method: To create a collection of new grades by passing the following sets
of grade information to the createGrade method, and then verify that one of the collection items is
created correctly.
B+ Math Good
Results: After completing this exercise, the application will contain structs for the teacher, student, and
grade types.
Programming in Visual C# 3-49
You will define a public event handler named LogonFailed that will be raised when a user fails to log on
successfully. You will add code to the Logon_Click event handler to validate the username and password
entered by the user against the Users collection in the MainWindow window. If the user is a teacher or a
student, you will store their details in the global context and then raise the LogonSuccess event, but if the
user is not validated, you will raise the LogonFailed event.
You will handle log on failure in the Logon_Failed method to display a message to the user and then you
will add markup to the MainWindow XAML code to connect the LogonFailed event to the
Logon_Failed method.
You will add code to the StudentsPage view to display students for the current teacher, and to display
the details for a student when the user clicks their name.
You will then use data binding to display the details and grades for the current student in the
StudentProfile view, and to display only the Back button if the user is a teacher.
Finally, you will run the application and verify that only valid users can log on and that valid users can see
only data appropriate to their role.
X Task 1: Examine the dummy data source used to populate the collections
1. Open the GradesPrototype solution from the E:\Labfiles\Starter\Exercise 3 folder.
2. In the Data folder, in the DataSource.cs file, expand the Sample Data region.
3. Note how the Teachers ArrayList is populated with Teacher data, each containing TeacherID,
UserName, Password, FirstName, LastName, and Class fields.
4. Note how the Students ArrayList is populated with Student data, each containing a StudentID,
UserName, Password, TeacherID, FirstName, and LastName fields.
5. Note how the Grades ArrayList is populated with Grade data, each containing a StudentID,
AssessmentDate, SubjectName, Assessment, and Comments fields.
a. Determine whether the user is a teacher by using a LINQ query to retrieve teachers with the same
user name and password as the current user. If the LINQ query returns a result, then the user is a
teacher.
3-50 Developing the Code for a Graphical Application
b. If the user is a teacher, set the UserID, UserRole, UserName, and CurrentTeacher properties of
the SessionContext object to the appropriate fields from the data source, and then raise the
LogonSuccess event.
c. If the user is not a teacher, determine whether the user is a student by using a LINQ query to
retrieve students with the same user name and password as the current user.
d. If the user is a student, set the UserID, UserRole, UserName, and CurrentStudent properties of
the SessionContext object to the appropriate fields from the data source, and then raise the
LogonSuccess event.
e. If the credentials do not match any teachers or students, raise the LogonFailed event.
2. In the Logon_Failed event handler, add code to display an error message to the user.
3. In the MainWindow.xaml XAML editor, locate the definition of the LogonPage page.
4. Modify the definition to call the Logon_Failed method for the LogonFailed event.
6. In the case statement for a student, add code to display the student name in txtName text box at the
top of the page.
7. In the case statement for a teacher, add code to display the teacher name in the banner at the top of
the page.
Note: DataBinding is also used to retrieve the StudentID of a student. This binding is used
when a user clicks on a Student on the Student Page list to identify which students data to
display in the Student Profile page.
2. In the StudentsPage.xaml.cs code, locate the Refresh method, and then add code to do the
following:
a. Find all the students for the current teacher and store them in a new ArrayList object.
3. Locate the Student_Click event and then add code to do the following:
a. Identify which student was clicked by using the Tag property of the button.
b. Find the details of that student by examining the DataContext of the button.
c. Raise the StudentSelected event, passing the student as the second parameter.
d. In the StudentsPage_StudentSelected event handler, add code to set the CurrentStudent
property of the SessionContext object to the student passed to the event by using the Child
property of the e argument.
Programming in Visual C# 3-51
2. In the StudentProfile.xaml XAML editor, locate the definition of the firstName text block.
3. Modify the definition to bind the Text property to the FirstName field.
4. Locate the definition of the lastName text block.
5. Modify the definition to bind the Text property to the LastName field.
6. In the StudentProfile.xaml.cs file, at the end of the Refresh method, add code to iterate the grades
for the current student in DataSource.Grades list and then display them in the studentGrades
control by using data binding.
3. Log on as parkerd with a password of password and verify that the Logon Failed message box
appears.
4. Log on as vallee with a password of password and verify that the Students page appears.
5. Click Kevin Liu, verify that the Student Profile page appears, and then log off.
6. Log on as grubere with a password of password and verify that the Student Profile page appears.
7. Close the application and then close the solution.
Results: After completing this exercise, only valid users will be able to log on to the application and they
will see only data appropriate to their role.
3-52 Developping the Code for a Graphical Applicatioon
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou have learrned how to im
mplement stru
ucts and enum
ms, organize d
data into colle
ections, and
woork with eventts and delegates.
Test Your Know
wledge
Q
Question
Y
You want to ccreate a string
g property naamed CountryyOfOrigin. Yo
ou want to bee able to
re
ead the property value froom any code, but you shouuld only be able to write tto the
p
property from
m within the ccontaining strruct. How sho
ould you decllare the propeerty?
S
Select the corrrect answer.
private
e string CountryOfOrigin { get; set; }
Q
Question
Question
ArrayList
Hashtable
SortedList
NameValueCollection
StringDictionary
Question
You are creating a method to handle an event named OutOfBeans. The delegate for the
event is as follows:
public delegate void OutOfBeansHandler(Coffee coffee, EventArgs args);
Which of the following methods should you use to subscribe to the event?
Module 4
Creating Classes and Implementing Type-Safe Collections
Contents:
Module Overview 4-2
Modu
ule Ove
erview
Claasses enable yyou to create your own cusstom, self-con ntained, and re
eusable types. Interfaces en
nable you
to define a set o
of inputs and outputs that cclasses must implement in order to ensu ure compatibility with
consumers of th he classes. In tthis module, you
y will learn how to use innterfaces and classes to deffine and
cre
eate your own n custom, reussable types. YYou will also le e enumerable, type-safe
earn how to crreate and use
collections of anny type.
Ob
bjectives
Aftter completing this module
e, you will be able to:
Lesson 1
Creatting Cla
asses
IIn Visual C#, yyou can define e your own cu ustom types by
b creating cla asses. As a pro
ogramming coonstruct, the
c
class is central to object-orriented prograamming in Vissual C#. It enaables you to eencapsulate th
he behaviors
a characterristics of any lo
and ogical entity in a reusable aand extensible
e way.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create claasses.
Create ob
bjects by insta
antiating classses.
Explain th
he difference between reference types and value type
es.
Create staatic classes an
nd members.
In Visual C#, a cclass is a programming construct that yo ou can use to d define your own custom tyypes. When
you create a class, you are efffectively creatting a blueprint for the typpe. The class defines the beh haviors and
characteristics, o
or class memb bers, which arre shared by aall instances off the class. Yo
ou represent thhese
beehaviors and ccharacteristics by defining m methods, fieldds, properties, and events w within your claass.
For example, suppose you cre eate a class naamed DrinksMachine. You u would use fields and prop perties to
de
efine the charaacteristics of a drinks machine, such as thhe make, mod del, age, and service
s interva
al of the
maachine. You w
would create m methods to represent the thhings that a drinks machine e can do, suchh as make
an espresso or mmake a cappu uccino. Finally,, you would d
define events to
t represent aactions that mmight
req
quire your atttention, such aas replacing ccoffee beans w
when the macchine has run o out of coffee beans.
De
eclaring a Class
C
De
eclaring a Cla
ass
p
public class DrinksMachi
ine
{
// Methods
s, fields, p
properties, and events g
go here.
}
A
Access modifier Description
p
public The type is available to ccode running in any assemb
bly that refere
ences the
assembly in
n which the cla ass is containe
ed.
i
internal The type is available to aany code within the same assembly, but not
available to
o code in anotther assemblyy. This is the default value iff you do
not specify an access mo odifier.
p
private The type is only available
e to code with
hin the class th
hat contains it. You can
Programming in Visual C# 4-5
Within your class, you can add methods, fields, properties, and events to define the behaviors and
characteristics of your type, as shown in the following example:
In
nstantiatin
ng Classes
A class
c is just a blueprint
b for a type. To usee the behaviorrs and charactteristics that yyou define witthin a class,
you need to cre eate instances of the class. A
An instance off a class is callled an object.
o create a new
To w instance of a class, you usse the new keyword, as sho
own in the folllowing examp
ple:
Insstantiating a Class
D
DrinksMachine
e dm = new D
DrinksMachin
ne();
Wh
hen you instantiate a class in this way, yo
ou are actuallly doing two tthings:
In this case, the compiler doe es not know inn advance the e type of the ddm variable. W When the dm m variable is
initialized as a re
eference to a DrinksMachine object, th he compiler de educes that th he type of dm m is
DrrinksMachine e. Using type iinference in this way causees no change iin how your aapplication run ns; it is
sim
mply a shortcu ut for you to aavoid typing tthe class name e twice. In som
me circumstan nces, type infe
erence can
maake your code e easier to reaad, while in other circumstaances it may m make your cod de more confu using. As a
geeneral rule, consider using ttype inference e when the type of variable e is absolutelyy clear.
This approach to calling members on an instance variable is known as dot notation. You type the variable
name, followed by a period, followed by the member name. The IntelliSense feature in Visual Studio will
prompt you with member names when you type a period after a variable.
4-8 Creating Classes and Implem
menting Type-Safe Collections
C
Ussing Consstructors
Co
onstructors are
e often used tto specify initiial or default vvalues for datta members w
within the new
w object, as
sho
own by the fo
ollowing exammple:
Ad
dding a Consstructor
p
public class DrinksMachi
ine
{
public int
t Age { get;
; set; }
public Dri
inksMachine(
()
{
Age = 0
0;
}
}
A constructor
c thhat takes no pparameters is known as the default consttructor. This co onstructor is ccalled
wh
henever some eone instantiattes your class without provviding any arg guments. If you do not inclu ude a
constructor in yyour class, the Visual C# commpiler will auttomatically ad
dd an empty public
p defaultt
constructor to your
y compiled d class.
In many cases, it is useful for consumers off your class to
o be able to sp
pecify initial vvalues for dataa members
whhen the class is instantiated
d. For examplee, when someo one creates a new instance e of DrinksMa achine, it
miight be useful if they can sppecify the make and model of the machine at the sam me time. Your class can
incclude multiple
e constructorss with differen
nt signatures tthat enable co
onsumers to provide
p differe
ent
combinations of information when they in nstantiate your class.
Consumers can use any of the constructors to create instances of your class, depending on the
information that is available to them at the time. For example:
Calling Constructors
var dm1 = new DrinksMachine(2);
var dm2 = new DrinksMachine("Fourth Coffee", "BeanCrusher 3000");
var dm3 = new DrinksMachine(3, "Fourth Coffee", "BeanToaster Turbo");
4-10 Creatingg Classes and Impleementing Type-Safe Collections
Re
eference T
Types and
d Value Ty
ypes
A struct
s is a valu
ue type. This definition
d appplies to built-in
n struct types,, such as int aand bool, as w
well as to
strructs that you define yourse elf. A value tyype contains itts data directlyy. In other woords, when you interact
witth a value typpe, you are intteracting direcctly with the d ns in memory.. By contrast, a class
data it contain
deefines a referennce type. Whe en you create an object by instantiating a class, you are creating a reference
typpe. The objectt itself is store
ed in memory,, but you inte eract with the object throug gh an object reeference.
Alll the object re
eference does is point to th he object in memory.
Bo
oxing and U
Unboxing
In some scenario os you may need to convert value typess to reference types, and vicce versa. For e example,
some collection classes will only
o accept refference types.. This is less likkely to be an issue with the
e advent of
geeneric collectio
ons. However,, you still need
d to be aware
e of the conce ept, because a fundamental concept
of Visual C# is that you can treat any type as an object.
The process of cconverting a vvalue type to a reference tyype is called b
boxing. To boxx a variable, yo
ou assign it
to an object refe
erence:
Programming in Visual C# 4-11
Boxing
int i = 100;
object o = i;
The boxing process is implicit. When you assign an object reference to a value type, the Visual C#
compiler automatically creates an object to wrap the value and stores it in memory. If you copy the object
reference, the copy will point to the same object wrapper in memory.
The process of converting a reference type to a value type is called unboxing. Unlike the boxing process,
to unbox a value type you must explicitly cast the variable back to its original type:
Unboxing
int j;
j = (int)o;
4-12 Creatingg Classes and Impleementing Type-Safe Collections
Demonstration: Com
mparing R
Reference Types and
d Value Ty
ypes
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. 0483A-SEA-D
Start the 20 DEV11-04 virttual machine.
3. Log on to W
Windows 8 as Student with
h the password Pa$$w0rd.
6. udio, on the F
In Visual Stu File menu, point to New, and then click Project.
7. In the New w Project dialo
og box, in the
e Templates liist, click Visua en in the Project Type
al C#, and the
list, click Co
onsole Appliccation.
8. In the Nam
me text box, tyype ValuesAn
ndReferencess
9. In the Location text boxx, set the locattion to E:\Dem
mocode, and then click OK
K.
0. Within the V
10 ValuesAndRe
eferences namespace, add
d the following
g code:
struct MyStruct
{
public int Content
ts;
}
class MyClass
Programming in Visual C# 4-13
{
public int Contents = 0;
}
12. Within the Program class, within the Main method, add the following code:
13. On the Debug menu, click Start without Debugging. The console window shows the following
output:
In some cases, yyou may wantt to create a class purely to encapsulate some useful ffunctionality, rather
r than
to represent an instance of anything. For e example, supp pose you wantted to create a set of methods that
convert imperiaal weights and d measures to metric weigh hts and measu ures, and vice versa. It would not make
sennse if you had ese methods, because you do not need to store or
d to instantiate a class in orrder to use the
rettrieve any insttance-specificc data. In fact, the concept o
of an instance
e is meaningleess in this case
e.
In scenarios like
e this, you can
n create a statiic class. A stattic class is a class that canno
ot be instantiaated. To
cre
eate a static class, you use the
t static keyyword. Any me embers within n the class muust also use th
he static
keyyword, as shoown in the folllowing examp ple:
Sta
atic Classes
p
public static
c class Conv
versions
{
public sta
atic double PoundsToKilos(double po
ounds)
{
// Conv
vert argumen
nt from poun
nds to kilograms
double kilos = pou
unds * 0.453
36;
return kilos;
}
public sta
atic double KilosToPoun
nds(double ki
ilos)
{
// Conv
vert argumen
nt from kilo
ograms to pou
unds
double pounds = ki
ilos * 2.205
5;
return pounds;
}
}
To
o call a method
d on a static cclass, you call the method o
on the class name itself insttead of on an instance
name, as shownn by the follow
wing example:
alling Method
Ca ds on a Staticc Class
d
double weight
tInKilos = 8
80;
d
double weight
tInPounds = Conversions
s.KilosToPoun
nds(weightIn
nKilos);
Programming in Visual C# 4-15
Static Members
Non-static classes can include static members. This is useful when some behaviors and characteristics
relate to the instance (instance members), while some behaviors and characteristics relate to the type itself
(static members). Methods, fields, properties, and events can all be declared static. Static properties are
often used to return data that is common to all instances, or to keep track of how many instances of a
class have been created. Static methods are often used to provide utilities that relate to the type in some
way, such as comparison functions.
To declare a static member you use the static keyword before the return type of the member, as shown
by the following example:
Regardless of how many instances of your class exist, there is only ever one instance of a static member.
You do not need to instantiate the class in order to use static members. You access static members
through the class name rather than the instance name, as shown by the following example:
Te
esting Classes
Claasses often represent self-ccontained unitts of functionaality. In manyy cases, you wiill want to test the
funnctionality of your classes in isolation be
efore you integrate them w with other classes in your ap pplications.
To
o test functionnality in isolation, you create a unit test. A unit test preesents the cod de under test with
known inputs, p performs an acction on the ccode under te est (for exampple by calling a method), an nd then
verifies that the outputs of th ed. In this wayy, the unit testt represents a contract
he operation aare as expecte
thaat your code must
m fulfill. Hoowever, whenn you change the implemen ntation of a class or metho od, the unit
tesst ensures that your code aalways returns particular ou utputs in respo onse to particular inputs.
For example, coonsider the casse where you create a simp present a custtomer. To help you
ple class to rep
tarrget your marrketing effortss, the Custom
mer class includ
des a GetAge e method thatt returns the ccurrent age
of the customerr in years:
Cla
ass Under Te
est
p
public class Customer
{
public Dat
teTime DateO
OfBirth { ge
et; set; }
public int
t GetAge()
{
TimeSpa
an differenc
ce = DateTim
me.Now.Subtra
act(DateOfBi
irth);
int age
eInYears = (
(int)(differ
rence.Days / 365.25);
// Note
e: convertin
ng a double to an int ro
ounds down t
to the neare
est whole num
mber.
return ageInYears;
;
}
}
Notice that the unit test method is divided into three conceptual phases:
Arrange. In this phase, you create the conditions for the test. You instantiate the class you want to
test, and you configure any input values that the test requires.
Act. In this phase, you perform the action that you want to test.
Assert. In this phase, you verify the results of the action. If the results were not as expected, the test
fails.
The Assert.IsTrue method is part of the Microsoft Unit Test Framework that is included in Visual Studio
2012. This particular method throws an exception if the specified condition does not evaluate to true.
However, the concepts described here are common to all unit testing frameworks.
4-18 Creatingg Classes and Impleementing Type-Safe Collections
Lesson 2
Definiing and
d Imple
ementin
ng Interrfaces
An
n interface is a little bit like a class withou
ut an impleme entation. It sp
pecifies a set o
of characteristtics and
be
ehaviors by de efining signatu ures for methoods, propertie d indexers, witthout specifyiing how
es, events, and
any of these me embers are im mplemented. W When a class implements an n interface, th
he class providdes an
implementation n for each mem mber of the in
nterface. By im
mplementing the interface,, the class is th hereby
gu
uaranteeing th hat it will provvide the functionality speciffied by the intterface.
In this lesson, yo
ou will learn h
how to define and impleme
ent interfaces..
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
Create interrfaces.
Create classses that imple
ement a single
e interface.
I
Introducin
ng Interfa
aces
IIn Visual C#, aan interface sp o characteristics and behaviors; it does this by definin
pecifies a set of ng methods,
p
properties, evvents, and inde exers. The inteerface itself does not speciffy how these members are
i
implemented . Instead, classses can implemment the inte erface and proovide their owwn implementa ations of the
i
interface mem mbers. You can think of an interface as a contract. By implementing g a particular interface, a
c
class guarante ees to consum mers that it will provide spe ecific functionaality through specific members, even
t
though the acctual impleme entation is nott part of the ccontract.
FFor example, suppose that you want to develop
d eme for Fourth Coffee. You might start
a loyalty card sche
b creating an
by n interface named ILoyalty
yCardHolder that defines:
A read-o
only integer property name
ed TotalPointts.
A method
d named Add
dPoints that accepts
a a decimal argumen
nt.
A method
d named Rese
etPoints.
D
Defining an Interface
I
public inte
erface ILoya
altyCardHolder
{
int Tota
alPoints { g
get; }
int AddP
Points(decim
mal transactionValue);
void Res
setPoints();
}
Note: P
Programming convention d
dictates that all interface naames should b
begin with an "I".
Notice that th
N he methods in n the interface
e do not include method bo odies. Similarlly, the properrties in the
i
interface indiccate which accessors to include but do not
n provide an ny implementtation details. The interface e
s
simply states tthat any implementing classs must includ de and providde an impleme entation for th he three
m
members. Thee creator of th
he implementing class can choose how tthe methods aare implemen nted. For
e
example, any implementation of the AddPoints meth hod will accep
pt a decimal argument
a (the
e cash value
o the custom
of mer transactionn) and return an integer (thhe number of points added d). The class developer
4-20 Creating Classes and Implementing Type-Safe Collections
could implement this method in a variety of ways. For example, an implementation of the AddPoints
method could:
Calculate the number of points to add by multiplying the transaction value by a fixed amount.
Calculate the number of points to add by using additional factors, such as the location of the loyalty
cardholder.
The following example shows a class that implements the ILoyaltyCardHolder interface:
Implementing an Interface
public class Customer : ILoyaltyCardHolder
{
private int totalPoints;
public int TotalPoints
{
get { return totalPoints; }
}
public int AddPoints(decimal transactionValue)
{
int points = Decimal.ToInt32(transactionValue);
totalPoints += points;
}
public void ResetPoints()
{
totalPoints = 0;
}
// Other members of the Customer class.
}
The details of the implementation do not matter to calling classes. By implementing the
ILoyaltyCardHolder interface, the implementing class is indicating to consumers that it will take care of
the AddPoints operation. One of the key advantages of interfaces is that they enable you to modularize
your code. You can change the way in which your class implements the interface at any point, without
having to update any consumer classes that rely on an interface implementation.
Programming in
i Visual C# 4-21
1
D
Defining IInterfacess
Y use the in
You nterface keyw
word to declare an interface, as shown b
by the followin
ng example:
D
Declaring an Interface
public inte
erface IBeve
erage
{
// Method
ds, properties, events, and indexer
rs go here.
}
A
Adding Inte
erface Mem
mbers
An interface defines
A d the sig
gnature of me
embers but do oes not includ
de any implem
mentation detaails.
I
Interfaces can
n include methhods, properties, events, an
nd indexers:
To define
e a method, yo
ou specify the
e name of the
e method, the return type, aand any param
meters:
int Get
tServingTemperature(bool
l includesMilk);
To define
e a property, yyou specify the name of the
e property, th
he type of the property, and
d the
property accessors:
bool Is
sFairTrade { get; set; }
To define
e an event, you use the eve
ent keyword, followed
f by th
he event hand
dler delegate, followed by
the namee of the event:
4-22 Creating Classes and Implementing Type-Safe Collections
To define an indexer, you specify the return type and the accessors:
Interface members do not include access modifiers. The purpose of the interface is to define the members
that an implementing class should expose to consumers, so that all interface members are public.
Interfaces cannot include members that relate to the internal functionality of a class, such as fields,
constants, operators, and constructors.
Programming in
i Visual C# 4-23
3
I
Implemen
nting Interfaces
D
Declaring aC
Class that Implements an Interface
public clas
ss Coffee : IBeverage
{
}
I
Implementin
ng an Interfacce
public inteerface IBeve
erage
{
int GetSServingTempe
erature(bool includesMil
lk);
bool IsFFairTrade { get; set; }
}
public classs Coffee : IBeverage
{
private int servinggTempWithoutMilk { get; set; }
private int servinggTempWithMilk { get; set
t; }
public iint GetServingTemperature(bool incl
ludesMilk)
{
if(inncludesMilk)
)
{
r
return servingTempWithMilk;
}
else
{
4-24 Creating Classes and Implementing Type-Safe Collections
return servingTempWithoutMilk;
}
}
public bool IsFairTrade { get; set; }
// Other non-interface members go here.
}
Interface Polymorphism
As it relates to interfaces, polymorphism states that you can represent an instance of a class as an instance
of any interface that the class implements. Interface polymorphism can help to increase the flexibility and
modularity of your code. Suppose you have several classes that implement the IBeverage interface, such
as Coffee, Tea, Juice, and so on. You can write code that works with any of these classes as instances of
IBeverage, without knowing any details of the implementing class. For example, you can build a
collection of IBeverage instances without needing to know the details of every class that implements
IBeverage.
For example, If the Coffee class implements the IBeverage interface, you can represent a new Coffee
object as an instance of Coffee or an instance of IBeverage:
You can use an implicit cast to convert to an interface type, because you know that the class must include
all the interface members.
You must use an explicit cast to convert from an interface type to a derived class type, as the class may
include members that are not defined in the interface.
I
Implemen
nting Multtiple Interrfaces
Implemen
nt the IComp
parable interfaace to enable collection claasses to sort in
nstances of yo
our class.
Implemen
nt your own custom
c interfaace to define tthe functionality of your claass.
D
Declaring aC
Class that Implements Mu
ultiple Interfa
aces
public clas
ss Coffee: IBeverage,
I IInventoryIte
em
{
}
I
Implicit and
d Explicit Im
mplementa
ation
When you cre
W eate a class that implementts an interface e, you can cho oose whether to implementt the
i
interface impllicitly or expliccitly. To imple
ement an inte
erface implicitlly, you implemment each interface
m
member with a signature that matches tthe member definition
d in th
he interface. T
To implementt an interface
e
explicitly, you fully qualify each
e memberr name so that it is clear thaat the membe er belongs to a particular
i
interface.
In most cases, whether you implement an interface implicitly or explicitly is an aesthetic choice. It does not
make a difference in how your class compiles. Some developers prefer explicit interface implementation
because doing so can make the code easier to understand. The only scenario in which you must use
explicit interface implementation is if you are implementing two interfaces that share a member name.
For example, if you implement interfaces named IBeverage and IInventoryItem, and both interfaces
declare a Boolean property named IsAvailable, you would need to implement at least one of the
IsAvailable members explicitly. In this scenario, the compiler would be unable to resolve the IsAvailable
reference without an explicit implementation.
Programming in
i Visual C# 4-27
7
I
Implemen
nting the IComparaable Interfface
T IComparrable Interfacce
The
public inte
erface IComp
parable
{
int Comp
pareTo(Objec
ct obj);
}
As you can se
A ee, the IComp parable interfaace declares a single metho
od named Co
ompareTo.
I
Implementatioons of this meethod must:
Return an
n integer value that indicates whether th he current object instance sshould be placced before, in
n
the same position, or aafter the passe
ed-in object in
nstance.
The following example illustrates what happens if you use the CompareTo method to compare two
integers:
CompareTo Example
int number1 = 5;
int number2 = 100;
int result = number1.CompareTo(number2);
// The value of result is -1, indicating that number1 should precede number2 in the sort
order.
Note: All the built-in value types in the .NET Framework implement the IComparable
interface. For more information about the IComparable interface, seethe IComparable Interface
page at http://go.microsoft.com/fwlink/?LinkID=267801.
When you call the Sort method on an ArrayList instance, the Sort method calls the CompareTo method
of the collection members to determine the correct order for the collection.
When you implement the IComparable interface in your own classes, you determine the criteria by which
objects should be compared. For example, you might decide that coffees should be sorted alphabetically
by variety.
In this example, because the values we want to compare are strings, we can use the String.Compare
method. This method returns -1 if the current string precedes the supplied string in an alphabetical sort
order, 0 if the strings are identical, and 1 if the current string follows the supplied string in an alphabetical
sort order.
Programming in
i Visual C# 4-29
9
I
Implemen
nting the ICompare
er Interfacce
m want to ssort instances of your class using alternaative sort criteria. For
IIn some casess, developers may
e
example, supppose you wan nt to sort a collection of Coffee instances by the valuee of the AveraageRating
p
property rathe ariety properrty. To sort an ArrayList insstance by usin
er than the Va ng custom sorrt criteria, you
u
n
need to do tw
wo things:
1
1. Create a cclass that imp
plements the IIComparer in
nterface to pro
ovide your cusstom sort functionality.
2
2. Call the S
Sort method o on the ArrayL
List instance, aand pass in an
n instance of yyour ICompa
arer
implemen ntation as a parameter.
T IComparrer Interface
The
public inte
erface IComp
parer
{
int Comp
pare(Object x, Object y)
}
As you can se
A ee, the IComp
parer interface
e declares a single method named Comp
pare. Implem
mentations of
t method must:
this m
Return an
n integer value that indicates whether th he current object instance sshould be placced before, in
n
the same position, or aafter the passe
ed-in object in
nstance.
In the above example, because the values we want to compare are doubles, we can make use of the
Double.CompareTo method. This returns -1 if the current double is less than the supplied double, 0 if
the current double is equal to the supplied double, and 1 if the current double is greater than the
supplied double. It is always better to make use of a built-in comparison function, if one exists, rather than
creating your own.
To sort the ArrayList using a custom comparer, you call the Sort method and pass in a new instance of
your IComparer implementation as an argument.
Programming in
i Visual C# 4-31
1
Lesson 3
Implementiing Typ
pe-Safe Collecttions
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Describe generics.
Apply con
nstraints to tyype parameterrs.
Use gene
eric list collections.
Use gene
eric dictionary collections.
Create cu
ustom genericc collections.
Create en
numerable generic collectio
ons.
4-32 Creatingg Classes and Impleementing Type-Safe Collections
In
ntroducing
g Genericss
Creating a Gen
neric Class
p
public class CustomList<
<T>
{
public T t
this[int ind
dex] { get; set; }
public voi
id Add(T ite
em)
{
// Meth
hod logic go
oes here.
}
public voi
id Remove(T item)
{
// Meth
hod logic go
oes here.
}
}
When you instantiate a class, every instance of T within the class is effectively replaced with the type
parameter you supply. For example, if you instantiate the CustomList class with a type parameter of
Coffee:
Ad
dvantagess of Generics
Ty
ype Safety
Coonsider an exa
ample where yyou use an ArrrayList to sto ore a collectio
on of Coffee o objects. You can add
ob
bjects of any tyype to an ArrrayList. Suppo
ose a developer adds an ob bject of type TTea to the collection. The
code will build w
without comp plaint. Howeve er, a runtime e
exception willl occur if the Sort
S method is called,
be
ecause the collection is unable to compare objects of different type es. Furthermorre, when you retrieve an
bject from the collection, yo
ob ou must cast tthe object to the
t correct type. If you atte empt to cast tthe object
to the wrong type, an invalid cast runtime exception will occur.
The following exxample showss the type safe
ety limitationss of the Array
yList approach:
Ty
ype Safety Lim
mitations forr Non-Generiic Collectionss
v
var coffee1 = new Coffee
e();
v
var coffee2 = new Coffee
e();
v
var tea1 = ne
ew Tea();
v
var arrayList
t1 = new Arr
rayList();
a
arrayList1.Ad
dd(coffee1);
;
a
arrayList1.Ad
dd(coffee2);
;
a
arrayList1.Ad
dd(tea1);
/
// The Sort m
method throw
ws a runtime
e exception because
b the collection is not homog
genous.
a
arrayList1.So
ort();
/
// The cast t
throws a run
ntime except
tion because you cannot cast a Tea instance to a Coffee
instance.
C
Coffee coffee
e3 = (Coffee
e)arrayList1
1[2];
As an alternative
e to the Array
yList, suppose e you use a ge
eneric List<T T> to store a ccollection of CCoffee
ob
bjects. When you
y instantiate e the list, you provide a typ
pe argument o of Coffee. In tthis case, your list is
gu
uaranteed to b be homogeno ous, because your
y code will not build if yyou attempt to o add an obje ect of any
oth
her type. The Sort method will work beccause your collection is hom mogenous. Fin nally, the inde
exer returns
ob
bjects of type C
Coffee, rathe
er than System m.Object, so there
t is no risk of invalid caast exceptionss.
No Casting
Casting is a computationally expensive process. When you add items to an ArrayList, your items are
implicitly cast to the System.Object type. When you retrieve items from an ArrayList, you must explicitly
cast them back to their original type. Using generics to add and retrieve items without casting improves
the performance of your application.
Co
onstrainin
ng Genericcs
In some cases, yyou may need d to restrict the types that developers
d cann supply as arrguments whe en they
insstantiate yourr generic class. The nature o pend on the logic you implement in
of these consttraints will dep
your generic cla ass. For exampple, if a collecttion class usess a property named
n Averag geRating to sort
s the
ite
ems in a collecction, you wou uld need to co onstrain the tyype paramete er to classes th
hat include th
he
AvverageRating g property. Suppose the Av verageRating g property is ddefined by the e IBeverage innterface. To
implement this restriction, yo ou would consstrain the type e parameter tto classes thatt implement the
IBeeverage interrface by using g the where kkeyword.
Co
onstraining T
Type Parametters by Interfface
p
public class CustomList<
<T> where T : IBeverage
{
}
Yo
ou can apply the following ssix types of co
onstraint to tyype parameters:
C
Constraint Description
w
where T : <naame of interface> Th
he type argum
ment must be, or implement, the specifie
ed interface.
w
where T : <naame of base cllass> Th
he type argum
ment must be, or derive from
m, the specifie
ed class.
w
where T:U Th
he type argum
ment must be, or derive from
m, the supplie
ed type
arg
gument U.
w
where T : new
w() Th
he type argum
ment must havve a public de
efault construcctor.
w
where T : struct Th
he type argum
ment must be a value type.
w
where T : classs Th
he type argum
ment must be a reference tyype.
Yo
ou can also ap
pply multiple cconstraints to the same classs, as shown by
b the followin
ng example:
Programming in Visual C# 4-37
Ussing Gene
eric List Co
ollections
Onne of the most common an nd important usesu of generics is in collecction classes. Generic
G collections fall
intto two broad categories: ge eneric list collections and g
generic diction nary collectionns. A generic list stores a
collection of objjects of type T.
T
Th
he List<T> Class
The List<T> claass provides a strongly-type
ed alternative
e to the Array e the ArrayList class, the
yList class. Like
Lisst<T> class in
ncludes metho
ods to:
Add an item
m.
Remove an item.
Insert an ite
em at a speciffied index.
ng the defaultt comparer orr a specified comparer.
Sort the items in the collection by usin
}
Console.ReadLine ("Press Enter to continue");
The LinkedList<T> class provides a generic collection in which each item is linked to the previous
item in the collection and the next item in the collection. Each item in the collection is represented by
a LinkedListNode<T> object, which contains a value of type T, a reference to the parent
LinkedList<T> instance, a reference to the previous item in the collection, and a reference to the
next item in the collection.
The Queue<T> class represents a strongly typed first in, last out collection of objects.
The Stack<T> class represents a strongly typed last in, last out collection of objects.
4-40 Creatingg Classes and Impleementing Type-Safe Collections
Ussing Gene
eric Dictio
onary Colle
ections
Dicctionary classe
es store collecctions of key value
v pairs. Th
he value is the
e object you w want to store, and the
keyy is the objectt you use to in
ndex and retrrieve the value e. For example e, you might u use a dictionaary class to
sto
ore coffee recipes, where th he key is the name
n of the co
offee and the e value is the rrecipe for thatt coffee. In
the
e case of gene eric dictionariies, both the kkey and the vaalue are stronngly typed.
Th
he Dictiona
ary<TKey, T
TValue> Cla
ass
The Dictionary<TKey, TValu ue> class provides a generral purpose, sttrongly typed dictionary claass. You can
add duplicate vaalues to the ccollection, butt the keys musst be unique. The class will throw an
ArrgumentExce eption if you attempt
a to ad
dd a key that aalready exists in the diction
nary.
The SortedList generic class uses less memory than the SortedDictionary generic class.
The SortedDictionary class is faster and more efficient at inserting and removing unsorted data.
4-42 Creatingg Classes and Impleementing Type-Safe Collections
Ussing Colle
ection Inte
erfaces
Wh here should yyou start when n you want to create a custtom collection n class? All colllections have
e certain
thiings in common. For example, you will tyypically want to be able to enumerate th he items in thhe collection
byy using a forea ach loop, andd you will need
d methods to o add items, reemove items, and clear the list. The
piccture on the slide
s shows that the .NET Frramework pro ovides a hierarrchical set of iinterfaces that define the
characteristics aand behaviors of collectionss. These interffaces build on
n one anotherr to define pro ogressively
mo ore specific fu
unctionality.
Th
he IEnumerrable and IE
Enumerable
e<T> Interffaces
If yyou want to b
be able to use a foreach looop to enumerrate over the items in your custom geneeric
collection, you m
must impleme ent the IEnummerable<T> interface.
i The IEnumerable e<T> methodd defines a
sin
ngle method n named GetEn numerator(). T This method must return an object of tyype IEnumeraator<T>.
The foreach sta atement reliess on this enum
merator objectt to iterate thrrough the collection.
Th
he ICollectio
on<T> Inte
erface
The ICollection n<T> interface e defines the basic function
nality that is common
c to all generic colle
ections. The
intterface inheritts from IEnum
merable<T>, which means that if you waant to implem ment ICollectiion<T>,
you must also im mplement thee members de efined by IEnuumerable<T> > and IEnume erable.
Programming in Visual C# 4-43
Name Description
Name Description
Name Description
RemoveAt Removes the item at the specified index from the collection.
Name Description
Name Description
Add Adds an item with the specified key and value to the collection.
ContainsKey Indicates whether the collection includes a key-value pair with the specified
key.
Remove Removes the item with the specified key from the collection.
TryGetValue Attempts to set the value of an output parameter to the value associated
with a specified key. If the key exists, the method returns true. If the key
does not exist, the method returns false and the output parameter is
unchanged.
Name Description
Item Gets or sets the value of an item in the collection, based on a specified key. This
property enables you to use indexer notation, for example myDictionary[myKey] =
myValue.
Reference Links: For comprehensive information and examples of all of the generic
interfaces covered in this topic, see the System.Collections.Generic Namespace page at
http://go.microsoft.com/fwlink/?LinkID=267802.
Programming in
i Visual C# 4-45
5
C
Creating E
Enumerab
ble Collecttions
To enumerate
T e over a collecction, you typically use a fo
oreach loop. T
The foreach loop exposes e each item in
t collection in turn, in an
the n order that is appropriate to
t the collectiion. The forea
ach statementt masks some e
o the comple
of exities of enum
meration. For the foreach statement
s to wwork, a generric collection class
c must
i
implement the IEnumerab ble<T> interfaace. This interrface exposes a method, Ge etEnumerato or, which mustt
r
return an IEnuumerator<T> > type.
T IEnume
The erator<T> Interface
T IEnumera
The ator<T> inte
erface defines the functiona
ality that all en
numerators m
must implemen
nt.
T IEnumera
The ator<T> inte
erface defines the following
g methods:
Name De
escription
MoveNext Ad
dvanced the e
enumerator to
o the next item
m in the collection.
Reset Se
ets the enume
erator to its starting positio
on, which is be
efore the first item in the
co
ollection.
T IEnumera
The ator<T> inte
erface defines the following
g properties:
Name Descrription
An enumerato
A or is essentiallly a pointer to
o the items in the collection
n. The starting
g point for the
e pointer is
b
before the firsst item. When n you call the MoveNext method,
m the po
ointer advancces to the nextt element in
t collection. The MoveN
the Next method rreturns true iff the enumeraator was able to advance one position,
o false if it has reached th
or he end of the collection. At any point during the enum meration, the Current
p
property returns the item tto which the enumerator
e is currently pointing.
W
When you cre
eate an enume
erator, you must
m define:
Which ite
em the enume
erator should treat as the fiirst item in the
e collection.
In what o
order the enum
merator shoulld move throu
ugh the itemss in the collecttion.
4-46 Creating Classes and Implementing Type-Safe Collections
The GetEnumerator method returns the default enumerator for your collection class. This is the
enumerator that a foreach loop will use, unless you specify an alternative. However, you can create
additional methods to expose alternative enumerators.
The following example shows a custom collection class that implements a default enumerator, together
with an alternative enumerator that enumerates the collection in reverse order:
The following example shows how you can use a default enumerator or an alternative enumerator to
iterate through a collection:
Enumerating a Collection
CustomCollection<Int32> numbers = new CustomCollection<Int32>();
// Add some items to the collection.
// Use the default enumerator to iterate through the collection:
foreach (int number in numbers)
{
//
}
// Use the alternative enumerator to iterate through the collection:
foreach(int number in numbers.Backwards())
{
//
}
The following example shows how you can use an iterator to implement an enumerator:
Programming in Visual C# 4-47
The example shows a custom generic collection class that uses a List<T> instance to store data. The
List<T> instance is populated by the FillList method. When the GetEnumerator method is called, a
foreach loop enumerates the underlying collection. Within the foreach loop, a yield return statement is
used to return each item in the collection. It is this yield return statement that defines the iterator
essentially, the yield return statement pauses execution to return the current item to the caller before the
next element in the sequence is retrieved. In this way, although the GetEnumerator method does not
appear to return an IEnumerator type, the compiler is able to build an enumerator from the iteration
logic that you provided.
4-48 Creatingg Classes and Impleementing Type-Safe Collections
Demonstration: Add
ding Data Validation and Typ
pe-Safety to the
pplication
Ap n Lab
In this demonstration, you wiill learn aboutt the tasks thaat you will perrform in the laab for this mo
odule.
Programming in
i Visual C# 4-49
9
S
Scenario
Now that the user interface
N e navigation ffeatures are w
working, you ddecide to repla
ace the simple
e structs with
c
classes to makke your appliccation more eefficient and sttraightforward
d.
Teachers who
T o have seen th
he application have expresssed concern th
hat the studen
nts in their claasses are
d
displayed in a random orde er. You decide
e to use the IC
Comparable in
nterface to en
nable them to o be displayed
d
i alphabeticaal order.
in
O
Objectives
A
After completting this lab, you
y will be able to:
Create claasses.
Implemen
nt the IComp
parable interfaace.
Use gene
eric collectionss.
E
Estimated Tim
me: 60 minutes
3A-SEA-DEV11-04, MSL-TM
Virtual Machine: 20483 MG1
User Nam
me: Student
Password
d: Pa$$w0rd
4-50 Creating Classes and Implementing Type-Safe Collections
You will also modify the Logon_Click method to use the VerifyPassword method to verify passwords
when a user logs on.
Finally, you will run the application and verify that it still functions correctly, allowing a student or a
teacher to log on.
3. Use the VerifyPassword method to verify the password when a user logs in
4. Build and run the application, and verify that a teacher or student can still log on
2. Start the 20483A-SEA-DEV11-04 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio and open the GradesPrototype.sln solution from the
E:\Labfiles\Starter\Exercise 1 folder.
4. In the Data folder, in Grade.cs, convert the Grade struct into a class.
5. Define a class constructor that takes the following parameters and uses them to populate the public
properties of the class:
o studentID
o assessmentDate
o subject
o assessment
o comments
6. Define a default class constructor that takes no parameters and assigns the following default values to
the public properties:
o Student ID: 0
o Assessment: A
2. Create a write-only password property that generates a new GUID for the default value.
3. Create a VerifyPassword method that uses the String.Compare method to check that the password
passed to it as a parameter matches the stored
Note: An application should not be able to read passwords; only set them and verify that a
password is correct
4. Define a class constructor that takes the following parameters and uses them to populate the public
properties of the class:
o studentID
o userName
o password
o firstName
o lastName
o teacherID
5. Define a default class constructor that takes no parameters and assigns the following default values to
the public properties:
o Student ID: 0
7. Create a write-only password property that generates a new GUID for a default value and a
VerifyPassword method that uses the String.Compare method to check that the password passed
to it as a parameter matches the stored password.
8. Define a class constructor that takes the following parameters and uses them to populate the public
properties of the class:
o teacherID
o userName
o password
o firstName
o lastName
o className
9. Define a default class constructor that takes no parameters and assigns the following default values to
the public properties:
o TeacherID: 0
X Task 3: Use the VerifyPassword method to verify the password when a user logs in
1. In the Views folder, in the LogonPage.xaml.cs code, modify the code in the Logon_Click method to
call the VerifyPassword method to verify the teachers password.
2. Modify the code to check whether teacher is null before examining the UserName property.
3. In the Student class, modify the code in the Logon_Click method to use the VerifyPassword
method to verify the students password.
4. Modify the code to check whether student is null before examining the UserName property.
X Task 4: Build and run the application, and verify that a teacher or student can still log
on
1. Build the solution and resolve any compilation errors.
2. Log in as vallee with a password of password.
Results: After completing this exercise, the Teacher, Student, and Grade structs will be implemented as
classes and the VerifyPassword method will be called when a user logs on.
Programming in Visual C# 4-53
2. Add validation logic to the Grade class to check the data entered by the user
3. Add a unit test to verify that the validations defined for the Grade class functions as expected.
2. In the Data folder, in the DataSource class, define a generic List collection to hold the names of valid
subjects.
3. In the CreateData method in that class, populate the list with the following subject names:
o Math
o English
o History
o Geography
o Science
X Task 2: Add validation logic to the Grade class to check the data entered by the user
1. In the Data folder, in the Grade.cs code, add validation code to the AssessmentDate property to
ensure that the following requirements have been met:
Check that the date is no later than the current date. If it is, throw an
ArgumentOutOfRangeException exception.
2. Add validation code to the Subject property to ensure that the following requirements are met:
Check that the specified subject is in the list that you have defined.
3. Add validation to the Assessment property to ensure that the following requirements are met:
X Task 3: Add a unit test to verify that the validations defined for the Grade class
functions as expected.
1. Add a Unit Test Project called GradesTest to the solution and reference the GradesPrototype
project from it.
2. In the UnitTest1 class, define the following tests and support methods:
TestValidGrade: to check that valid data passes the validation logic successfully
TestBadDate: to check that dates in the future are not valid
TestBadAssessment: to check that assessment values outside the permitted range are not valid
TestBadSubject: to check that subject names not in the list are not valid
Results: After completing this exercise, the Grade class will contain validation logic.
Programming in Visual C# 4-55
The application currently displays students in no specific order when logged on as a teacher, but you now
want them to be displayed in alphabetical order of last name and first name. To achieve this, you decide
that the Student class should implement the IComparable<> interface to enable comparison of student
data. You can then add code to the CompareTo method in the Student class, enabling students to be
sorted based on their last name and first name.
Currently, Students are stored in a non-type-safe ArrayList collection. You decide to modify this so they
are stored in a type-safe List collection. Finally, you will sort the Students data and then run the
application to verify that the students are retrieved and displayed in alphabetical order of their last name
and first name.
1. Run the application and verify that the students are not displayed in any specific order when logged on
as a teacher
2. Implement the IComparable<Student> interface to enable comparison of students
X Task 1: Run the application and verify that the students are not displayed in any
specific order when logged on as a teacher
1. In Visual Studio, from the E:\Labfiles\Starter\Exercise 3 folder, open the GradesPrototype.sln
solution.
2. Build the solution and resolve any compilation errors.
3. Log in as vallee with a password of password. Verify that the students are not displayed in any
specific order.
4. Close the application.
2. In the CreateData method, modify the creation of the Students collection to create a new generic
List collection.
4-56 Creating Classes and Implementing Type-Safe Collections
X Task 5: Verify that Students are retrieved and displayed in order of their first name
and last name
1. Build the solution and resolve any compilation errors.
4. Verify that the students are displayed in order of ascending last name.
Results: After completing this exercise, the application will display the students in alphabetical order of
last name and then first name.
Programming in Visual C# 4-57
After a student has been added to the database, that student will be able to log on to view their own
grades.
4. Add code to enable a teacher to remove the student from the assigned class
5. Add code to enable a teacher to add a grade to a student
6. Run the application and verify that students can be added to and removed from classes, and that
grades can be added to students
X Task 1: Change the Teachers and Grades collections to be generic List collections
1. In Visual Studio, from the E:\Labfiles\Starter\Exercise 4 folder, open the GradesPrototype.sln
solution.
2. In the Data folder, in the DataSource.cs code, change the Teachers collection to be a generic List
collection.
4. In the CreateData method, modify the creation of the Teachers collection to create a new generic
List collection.
5. In the CreateData method, modify the creation of the Grades collection to create a new generic List
collection.
X Task 2: Add the EnrollInClass and RemoveFromClass methods for the Teacher class
1. In the Data folder, in the Grade.cs code, in the Teacher class, implement the EnrollInClass method
as follows:
If the student is not in another class, set the TeacherID property of the student to the current
TeacherID.
If the Student is in another class, throw an ArgumentException exception to show that the student is
already assigned to a class.
Verify that the Student is actually assigned to the class for the given teacher.
If the student is part of the class, reset the TeacherID property of the student to zero.
If the student is not part of the class, throw an ArgumentException exception to show that the
student is not assigned to this class.
If it does not belong to another student, add the grade to the students record by setting the
StudentID property of the Grade object.
If it does belong to another student, throw an ArgumentException exception to show that the grade
belongs to a different student.
Inside the try block, determine which student the user clicked by using the Tag property of the
studentClicked button.
Find this student in the Students collection and prompt the user to confirm that they wish to add the
student to their class.
If the user confirms this, add the student to the class by calling the EnrollInClass method, and then
refresh the display.
If there are no unassigned students, show the txtMessage box and hide the list control.
If there are unassigned students, hide the txtMessage box and show the list control bound to the list
of unassigned students.
3. In the StudentsPage.xaml.cs code, in the EnrollStudent_Click method, add code to use the
AssignStudentDialog to display the unassigned students. Then refresh the display to show any newly
enrolled students.
X Task 4: Add code to enable a teacher to remove the student from the assigned class
1. In the StudentProfile.xaml.cs code, in the Remove_Click method, write code as follows:
Detect if the user is a teacher. If they are not, exit the method.
Inside the try block, display a message box to prompt the user to confirm that the current student
should be removed from their class.
If the user confirms, call the RemoveFromClass method of the current teacher to remove this
student from their class, and then return to the previous page.
Add a catch block to display a message to the user if an exception occurs.
Programming in Visual C# 4-59
Inside the try block, use the GradeDialog to get the details of the assessment grade and use them to
create a new Grade object.
X Task 6: Run the application and verify that students can be added to and removed
from classes, and that grades can be added to students
1. Build the solution and resolve any compilation errors.
2. Log in as vallee with a password of password.
Password: password
6. For the student Darren Parker, add a new grade by using the following information:
Assessment: B
Comments: Good
8. Log on as the student Darren Parker and verify that the grade information from the previous steps is
displayed in the Report Card.
Note: A username is generated by taking a users last name and the first initial of their first
name. The username for Darren Parker is parkerd.
Results: After completing this exercise, the application will enable teachers to add and remove students
from their classes, and to add grades to students.
4-60 Creating Classes and Implementing Type-Safe Collections
Programming in
i Visual C# 4-61
1
Module Rev
view an
nd Take
eaways
M
Module Rev
view
I this module
In e, you have le
earned how to
o work with classes, interfacces, and generic collectionss in Visual C#..
T
Test Your Kno
owledge
Question
Boolean
Byte
e
Decimal
Int32
Obje
ect
T
Test Your Kno
owledge
Question
Even
nts
Field
ds
4-62 Creating Classes and Implementing Type-Safe Collections
Question
Indexers
Methods
Properties
Question
You want to create a custom generic class. The class will consist of a linear collection of
values, and will enable developers to queue items from either end of the collection.
Which of the following should your class declaration resemble?
Module 5
Creating a Class Hierarchy by Using Inheritance
Contents:
Module Overview 5-2
Modu
ule Ove
erview
The concept of inheritance iss central to obbject-oriented programmin ng in any language. It is alsoo one of
the
e most powerrful tools in yoour developerr toolbox. Esseentially, inheriitance enabless you to creatte new
cla
asses by inheriting characteeristics and be
ehaviors from existing classes. When you u inherit from an existing
cla
ass and add so ome functionaality of your o
own, your classs becomes a more specializzed instance of o the
existing class. Not only does this save you time by reduccing the amount of code yyou need to w write, it also
enables you to create
c hierarcchies of related
d classes that you can thenn use interchangeably, depe ending on
your requirements.
In this module, yyou will learn how to use in
nheritance to create class hierarchies
h and
d to extend .N
NET
Fraamework typees.
Ob
bjectives
Aftter completing this module
e, you will be able to:
e classes and d
Create base derived classe
es by using inh
heritance.
Lesson 1
Creatting Cla
ass Hierarchie
es
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Describe inheritance.
W
What Is Inh
heritance??
Th
he Beverage C
Class
p
public class Beverage
{
protected int serving
gTemperature
e;
public string Name { get; set; }
public boo
ol IsFairTra
ade { get; s
set; }
public int
t GetServing
gTemperature
e()
{
return servingTemp
perature;
}
}
Note: In object-oriented programming, the terms derives and inherits are used
interchangeably. Saying that the Coffee class derives from the Beverage class means the same as
saying the Coffee class inherits from the Beverage class.
As you can see in the previous examples, the syntax for inheriting from a class is similar to the syntax for
implementing an interface. This is because inheriting from a class and implementing an interface are both
examples of inheritance. However, you do not need to duplicate the base class members in the derived
class. By adding the base class to your class declaration, you make all the members of the base class
available to consumers of your derived class.
The following example shows how to use base class members in a derived class:
As shown in the above example, you can call members of a base class in the same way that you call
members of the class itself.
5-6 Creating a Class Hierarchy byy Using Inheritance
Whhen you creatte a class, you should consider whether yyou or other d
developers will need to use e it as a
base for derived
d classes. You have full conttrol over whether, and how
w, your class can be inherite
ed.
Ab
bstract Classses and Members
As part of an ob d design, you may want to ccreate classes that serve so
bject-oriented olely as base classes for
oth
her types. The
e base class m
may contain missing or inco omplete functiionality, and yyou may not wwant to
enable code to instantiate yo
our class directly. In these sccenarios, you can add the aabstract keyw
word to
your class declaration.
De
eclaring an A
Abstract Classs
a
abstract clas
ss Beverage
{
}
The abstract keeyword indicates that the class cannot bee instantiated directly; it exxists solely to d
define or
implement mem mbers for derived classes. Iff you attempt to instantiate
e an abstract class
c you will get an
errror when you build your co
ode.
Ann abstract classs can contain both abstract and non-abstract membe ers. Abstract m
members are aalso
de
eclared with th he abstract ke eyword and aare conceptually similar to iinterface memmbers, in that abstract
meembers define e the signaturre of the mem
mber but do no ot provide any implementaation details. Any
A class
tha provide an implementation
at inherits from the abstracct class must p n for the abstrract members.. Non-
ab
bstract membe ers, however, can be used ddirectly by derived classes.
bstract and N
Ab Non-Abstractt Members
a
abstract clas
ss Beverage
{
// Non-abs
stract membe
ers.
// Derived
d classes ca
an use these
e members wit
thout modify
ying them.
public string Name { get; set; }
public boo
ol IsFairTra
ade { get; s
set; }
// Abstrac
ct members.
Programming in Visual C# 5-7
Note: You can only include abstract members within abstract classes. A non-abstract class
cannot include abstract members.
Sealed Classes
You may want to create classes that cannot be inherited from. You can prevent developers from inheriting
from your classes by marking the class with the sealed keyword.
You can apply the sealed modifier to classes that inherit from other classes and classes that implement
interfaces. You cannot use the sealed modifier and the abstract modifier on the same class, as a sealed
class is the opposite of an abstract classa sealed class cannot be inherited, whereas an abstract class
must be inherited.
Any static class is also a sealed class. You can never inherit from a static class. Similarly, any static members
within non-static classes are not inherited by derived classes.
5-8 Creating a Class Hierarchy byy Using Inheritance
Yo
ou may want tto implement a method in yyour base class, but allow d derived classe
es to replace your
y
me ethod implem mentation with h more specifiic functionalitty. To create a member that developers ccan
ovverride in a de
erived class, yo
ou use the virrtual keywordd.
The following exxample showss how to creatte a virtual method in a cla
ass:
Whhen you creatte a class, you can use acceess modifiers tto control whe
ether the mem mbers of yourr class are
acccessible to de
erived types. Y
You can use th
he following aaccess modifieers for class m
members:
A
Access Modifiier Detaails
p
public The member is avvailable to code running in
n any assemblyy.
p
protected The member is avvailable only within
w the con
ntaining class or in classes d
derived
m the containing class.
from
i
internal The member is avvailable only tto code within
n the current assembly.
p
protected inte
ernal The member is avvailable to any code within n the current aassembly, and
d to types
deriived from the containing cllass in any asssembly.
p
private The member is avvailable only within
w the con
ntaining class.
Programming in Visual C# 5-9
Members of a class are private by default. Private members are not inherited by derived classes. If you
want members that would otherwise be private to be accessible to derived classes, you must prefix the
member with the protected keyword.
5-10 Creatingg a Class Hierarchy by Using Inheritancce
In
nheriting from
f a Basse Class
To
o inherit from another class, you add a co
olon followed
d by the name
e of the base cclass to your cclass
de
eclaration.
De
eclaring a Cla
ass that Inherrits From a B
Base Class
p
public class Coffee : Be
everage
{
}
A class
c can onlyy inherit from one base classs. However, yyour class can implement one or more in
nterfaces in
addition to deriving from a b base type.
Ov
verriding B
Base Class Members
M
In some cases yo
ou may want to change the way a base class memberr works in you
ur derived classs.
Be
ecause GetSerrvingTemperrature is a virttual method, you y can overrride it in a derrived class. To
o override a
virrtual method iin a derived cclass, you create a method w
with the same
e signature annd prefix it witth the
ovverride keyworrd.
You can use the same approach to override properties, indexers, and events. In each case, you can only
override a base class member if the member is marked as virtual in the base class. You cannot override
constructors.
You can also override a base class member by using the new keyword:
When you use the override keyword, your method extends the base class method. By contrast, when you
use the new keyword, your method hides the base class method. This causes subtle but important
differences in how the compiler treats your base class and derived class types.
Reference Links: For a detailed explanation of the differences in behavior between the
override keyword and the new keyword, see Knowing When to Use Override and New Keywords
(C# Programming Guide) at http://go.microsoft.com/fwlink/?LinkID=267803.
By sealing an overridden member, you force any classes that derive from your class to use your
implementation of the base class member, rather than creating their own.
You can only apply the sealed modifier to a member if the member is an override member. Remember
that members are inherently sealed unless they are marked as virtual. In this case, because the base class
5-12 Creating a Class Hierarchy by Using Inheritance
method is marked as virtual, any descendants are able to override the method unless you seal it at some
point in the class hierarchy.
Programming in
i Visual C# 5-13
3
C
Calling Baase Class C
Constructo
ors and Members
M
C
Calling Basse Class Con
nstructors ffrom a Deriived Class
You cannot ovverride constrructors in deriived classes. In
Y nstead, when you create co onstructors in a derived
c
class, your connstructors will automaticallly call the defaault base class constructor before they e
execute any
o the logic th
of hat you have added.
a Howevver, in some ccircumstancess, you might w want your con nstructors to
c an alternaative base classs constructorr. In these case
call es, you can usse the base keeyword in youur constructorr
d
declarations to specify whicch base class constructor yo ou want to caall.
C
Calling Base Class Constrructors
public clas
ss Beverage
{
public B
Beverage()
{
// Im
mplementatio
on details not shown.
}
public B
Beverage(strring name, bool isFairTr
rade, int se
ervingTemp)
{
// Im
mplementatioon details are not shown
n.
}
// Other
r class membbers are not shown.
}
public clas
ss Coffee : Beverage
{
public C
Coffee()
5-14 Creating a Class Hierarchy by Using Inheritance
{
// This constructor implicitly calls the default Beverage constructor.
// The declaration is implicitly equivalent to public Coffee() : base()
// You can include additional code here.
}
public Coffee(string name, bool isFairTrade, int servingTemp, string bean, string
roast)
: base(name, isFairTrade, servingTemp)
{
// This calls the Beverage(string, bool, int) constructor.
// You can include additional code here:
Bean = bean;
Roast = roast;
}
public string Bean { get; set; }
public string Roast { get; set; }
public string CountryOfOrigin { get; set; }
}
As the previous example shows, you must call the base class constructor from your constructor
declaration. You cannot call the base class constructor from within your constructor method body. You
can use the named parameters from your constructor declaration as arguments to the base class
constructor.
Remember that the rules of inheritance do not apply to static classes and members. As such, you cannot
use the base keyword within a static method.
Programming in
i Visual C# 5-15
5
D
Demonstr
ration: Caalling Base
e Class Co
onstructors
IIn this demonnstration, you will step through the execu ution of an ap
pplication. Thee solution includes a class
n
named Coffee that inheritss from a class named Beverage. The Coffee class inclludes two con nstructors
o that implicitly calls the
one e default base class construcctor, and one that explicitlyy calls an alternative base
c
class construcctor. The appliication creates instances off the Coffee class
c by using both of these e
c
constructors. In both cases,, you can obseerve how deriived class connstructors call base class constructors.
Y will also ssee how derivved class consttructors pass argument values to base class constructtors.
You
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483-SEA-D
DEV11-05 virtu
ual machine.
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start men
nu.
5
5. Click Visu
ual Studio 201
12.
6
6. In Visual Studio, on the
e File menu, p n, and then click Project/Solution.
point to Open
7
7. In the Op
pen Project dialog box, bro emocode, clicck BaseConstructors.sln, and
owse to E:\De a then click
Open.
8
8. In Solutio
on Explorer, do
ouble-click Be nd review the contents of tthe class.
everage.cs an
9
9. Note thatt the Beverag
ge class contains a default constructor
c an
nd an alternattive constructtor.
1 In Solutio
10. on Explorer, do
ouble-click Co
offee.cs and review the contents of the class.
1 In Solutio
14. on Explorer, do
ouble-click Prrogram.cs an
nd review the contents of th
he class.
5-16 Creating a Class Hierarchy by Using Inheritance
15. Note that the Program class creates two instances of the Coffee type: one by using the default
constructor, and one by using the alternative constructor.
17. Press F11 twice so that the first line of executable code in the Program class is highlighted.
18. Press F11. Note that the debugger steps into the default constructor for the Coffee class.
19. Press F11. Note that the debugger steps into the default constructor for the Beverage class.
20. Point out that derived class constructors implicitly call the default base class constructor unless you
specify an alternative base class constructor.
21. Press F11 six times, until the debugger returns to the default constructor for the Coffee class.
22. Point out that the base class constructor logic is executed before the derived class constructor logic.
23. Press F11 six times, until the debugger returns to the Program class.
24. Press F11. The second executable line of code in the Program class should be highlighted.
25. Press F11. Note that the debugger steps into the alternative constructor for the Coffee class.
26. Press F11. Note that the debugger steps into the alternative constructor for the Beverage class.
27. Hover over the Beverage constructor parameters, and point out that the Coffee constructor has
passed argument values to this constructor.
28. Press F11 six times, until the debugger returns to the alternative constructor for the Coffee class.
29. Press F11 six times, until the debugger returns to the Program class.
31. When the console window appears, point out that it makes no difference to consumers of the class
whether variables were set by the derived class constructor or the base class constructor.
Lesson 2
Exten
nding .NET Fra
amewo
ork Classses
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create cu
ustom exception classes.
Throw an
nd catch custo
om exceptionss.
In
nheriting from
f .NET
T Framewo
ork Classe
es
There are almosst 15,000 public types in the .NET Framework. Althouggh not all of tthese are extendable
cla
asses, many off them are. W
When you wantt to develop a class, in man e is a built-in .NET
ny cases there
Fraamework classs that can pro
ovide a foundaation for yourr code.
There are two kkey advantage es to creating a class that in
nherits from a .NET Framew
work class, rath
her than
de
eveloping a claass from scrattch:
Reduced development time. By inhe eriting from an existing classs, you reduce
e the amount of logic
that you haave to create yyourself.
Standardizzed functiona ality. Just like implementing an interface e, inheriting frrom a standarrd base
class meanss that your claass will work in n a standardizzed way. You can also repre esent instancees of your
class as insttances of the base
b class, wh
hich makes it easier
e for developers to use e your class allongside
other typess that derive frrom the same e base class.
When you use this approach, consumers of your class have access to all the functionality provided by the
base List<T> class. They also have access to the additional RemoveDuplicates method that you
provided in your derived class.
5-20 Creatingg a Class Hierarchy by Using Inheritancce
Crreating Cu
ustom Excceptions
If you attem
mpt to retrieve
e an indexed item from a ccollection, and
d the index it o
outside the bo
ounds of
the collectio
on, the indexe
er will throw aan IndexOutO
OfRangeExce eption.
Whhen you need d to throw excceptions in your code, you should reuse existing .NET Framework e
exception
typ
pes wherever possible. Howwever, there mmay be circum
mstances when n you want to create your o
own custom
excception typess.
W
When Should
d You Creatte a Custom
m Exception
n Type?
Yo
ou should consider creating
g a custom excception type when:
w
The Message property enables you to provide more information about what happened as a text
string.
The InnerException property enables you to identify another Exception instance that caused the
current instance.
The Source property enables you to specify the item or application that caused the error condition.
The Data property enables you to provide more information about the error condition as key-value
pairs.
When you create a custom exception type, you should make use of these existing properties wherever
possible, rather than creating your own alternative properties. At a high level, the process for creating a
custom exception class is as follows:
Note: When you create a custom exception class, it is a best practice to include the word
Exception at the end of your class name.
5-22 Creatingg a Class Hierarchy by Using Inheritancce
Th
hrowing aand Catching Custo
om Exceptions
To
o catch the excception, you u use a try/catch
h block. Reme ember that yoou should always attempt to o catch the
moost specific exxceptions first,, and the mosst general exception (typicaally System.Ex
xception) lastt.
Ca
atching a Cusstom Exceptio
on
p
public bool PayWithPointts(int costIInPoints, string cardNum
mber)
t
try
{
int totalPoints = Loy
yaltyCard.GeetBalance(cardNumber);
// Throws a LoyaltyCa
ardNotFoundEException if the card nu
umber is inv
valid.
if(totalPo
oints >= cos
stInPoints)
{
Programming in Visual C# 5-23
LoyaltyCard.DeductPoints(costInPoints);
return true;
}
else return false;
}
catch(LoyaltyCardNotFoundException)
{
// Take appropriate action to remedy the invalid card number.
return false;
}
catch(Exception)
{
// Catches other unanticipated exceptions.
return false;
}
5-24 Creatingg a Class Hierarchy by Using Inheritancce
In
nheriting from
f Gene
eric Typess
Coonsider an exa
ample where yyou want to ccreate a custom m list class thaat inherits from List<T>. If you leave
the
e type parame eter of the baase type unspe
ecified, you m
must include th he same type parameter in your class
de
eclaration.
Inh
heriting from
m a Generic B
Base Type Wiithout Speciffying a Type Argument
p
public class CustomList<
<T> : List<T
T>
{ }
Altternatively, yo
ou can specifyy a type argum
ment for the b
base type in yo
our class declaration. When
n you use
thiis approach, any
a referencess to the type pparameter in tthe base type
e are replaced with the type
e you
speecify in your cclass declaration.
heriting from
Inh m a Generic B
Base Type by
y Specifying a Type Argum
ment
p
public class CustomList : List<int>
>
{ }
In the above exaample, when you instantiatte the Custom mList class, yo
ou do not nee
ed to specify a type
parameter. Any base class me ethods or pro
operties that re
eferenced thee type parame
eter are now sstrongly
typ
ped to the Intt32 type. For example, the List.Add metthod will onlyy accept argum
ments of type Int32.
type argument or add a matching type parameter to your class declaration for each type parameter in the
base type.
The following example shows the different ways in which you can inherit from a base type with multiple
type parameters:
Regardless of how manyif anytype parameters the base type includes, you can add additional type
parameters to your derived class declarations.
The following example shows how to add additional type parameters to derived class declarations:
To
o use an exten
nsion method, you must exp
plicitly importt the namespaace that contaains your exte
ension
meethod by using a using dire
ective:
Yo
ou can then caall the extensio
on method ass if it was an in
nstance method on the typ
pe that it extends:
Programming in Visual C# 5-27
Demonstration: Refaactoring C
Common Functionaality into tthe User C
Class Lab
In this demonstration, you wiill learn aboutt the tasks thaat you will perrform in the laab for this mo
odule.
Programming in
i Visual C# 5-29
9
Lab: Refacto
oring Commo
C n Functionalitty into the Use
er
Classs
S
Scenario
You have notiiced that the Student and T
Y Teacher classe
es in the Grad
des application
n contain som
me duplicated
f
functionality. To make the application m
more maintainable, you deccide to refactoor this commo
on
f
functionality tto remove the
e duplication.
You are also cconcerned abo
Y out security. T
Teachers and students all re
equire a passw
word, but it iss important to
o
m
maintain conffidentiality and at the same e time ensure that studentss (who are children) do not have to
r
remember lonng and compllex passwordss. You decide tto implementt different passsword policie es for teacherss
a students; teachers' passswords must be stronger and
and a more diffiicult to guess than student passwords.
O
Objectives
A
After completting this lab, you
y will be able to:
Use inherritance to facttor common ffunctionality in
nto a base cla
ass.
Implemen
nt polymorph
hism by using an abstract method.
m
User Nam
me: Student
Password
d: Pa$$w0rd
5-30 Creating a Class Hierarchy by Using Inheritance
You will modify the definitions of the Student and Teacher classes to inherit from the User class, and
remove the UserName and Password properties and the VerifyPassword method from these classes.
Finally, you will build and run the application without making any other changes to the application, and
then verify that it still works correctly.
2. Modify the Student and Teacher classes to inherit from the User class
2. Start the 20483A-SEA-DEV11-05 virtual machine and log on as Student with the password
Pa$$word.
3. Start Visual Studio and open the GradesPrototype.sln solution from the
E:\Labfiles\Starter\Exercise 1 folder.
4. In the Grade.cs file in the Data folder, create a new abstract class called User.
5. Add the UserName and Password properties to the User class.
Note: Copy the code for the UserName and Password properties and the
VerifyPassword method from either the Student class or the Teacher class. You must also add
the private _password field to the UserName class; this field provides the storage for the
Password property.
X Task 2: Modify the Student and Teacher classes to inherit from the User class
1. In the Grade.cs file, modify the Student class to inherit from the User class. Remove the UserName
and Password properties, and the private _password field. Also remove the VerifyPassword method
from the Student class.
2. Modify the Teacher class to inherit from the User class. Remove the UserName and Password
properties, and the private _password field. Also remove the VerifyPassword method from the
Teacher class.
4. Verify that a list of students for this teacher appears in The School of Fine Arts window.
Programming in Visual C# 5-31
5. Select student Kevin Liu and verify that the report card listing the grades for this student appears.
6. Log off and then log on as liuk (a student) with a password of password.
7. Verify that the report card for Kevin Liu is displayed again.
Results: After completing this exercise, you should have removed the duplicated code from the Student
and Teacher classes, and moved the code to an abstract base class called User.
5-32 Creating a Class Hierarchy by Using Inheritance
Next, you will integrate this feature into the user interface of the application to enable a user to change
their password.
Finally, you will build and run the application to test the password functionality.
2. In the User class, define a public abstract method called SetPassword. This method should take a
string parameter containing the password and return a Boolean value indicating whether the
password has been set successfully.
3. In the User class, modify the set accessor of the Password property to call the SetPassword method
rather than directly writing to the _password field. Throw an ArgumentException exception if the
SetPassword method returns false.
X Task 2: Implement the SetPassword method in the Student and Teacher classes
1. In the User class, make the _password field protected rather than private; it needs to be accessible in
the Student and Teacher classes.
2. In the Student class, implement the SetPassword method. The method should verify that the
password specified as the parameter is at least six characters long. If the password is of sufficient
length, then populate the _password field and return true; otherwise, return false.
3. In the Teacher class, implement the SetPassword method. The method should verify that the
password specified as the parameter is at least eight characters long and contains at least two
numeric characters. If the password is of sufficient complexity, then populate the _password field and
return true; otherwise, return false.
Note: You will need to use the following regular expression to verify the validity of the
password:
Programming in Visual C# 5-33
2. In this method, modify the statement that sets the password for the new student to call the
SetPassword method. If the password is not sufficiently complex and the method returns false,
throw an Exception with a suitable error message.
Note: If you were happy with the default exception thrown by using the Password
property, you could retain the code as is. However, in this case you have decided to throw a
different exception with a more meaningful and less generic error message, so you chose to call
the SetPassword method directly.
4. In the Controls folder, review the ChangePasswordDialog.xaml window. This window contains three
text boxes that prompt the user to provide their old password, enter a new password, and confirm the
new password. When the user clicks OK the new password is set.
Note: You can use the SessionContext.UserRole property to determine if the current user
is a teacher or a student and then use either the CurrentTeacher property or CurrentStudent
property of the SessionContext object to access the user details.
b. Verify that the old password specified in the dialog is correct by using the VerifyPassword
method of the User class. If the password is incorrect, display a message and return from the
method without changing the password.
c. Verify that the new password and confirm password text boxes in the dialog contain the same
value. If they are different, display a message and return from the method without changing the
password.
d. Set the password by using the SetPassword method of the current user. If this method returns
false, display a message and return without changing the password.
X Task 5: Run the application and test the change password functionality
1. Build the solution and resolve any compilation errors.
Note: The passwords for all teachers have changed to password99 to ensure that they
meet the complexity requirements. The password for all students is still password.
4. Change the password for the current user. First try setting it to a password that is insufficiently
complex, and then change it to password101.
5. Log out and then log back in again as vallee, and verify that the password has been changed to
password101.
6. Create a new student and verify that the student password must be at least six characters long. Use
the Enroll Student feature to verify that the student is successfully created.
Results: After completing this exercise, you should have implemented a polymorphic method named
SetPassword that exhibits different behavior for students and teachers. You will also have modified the
application to enable users to change their passwords.
Programming in Visual C# 5-35
2. Review the ClassFullException class in the Services folder. Notice that the class inherits from the
Exception class, but most of the functionality has yet to be defined.
3. Add a private string field called _className and a public virtual read-only string property called
ClassName to the ClassFullException class. This property should return the value in the _className
field. The _className field will hold the name of the class that is full when the exception is raised.
4. Add a default public constructor to the ClassFullException class. This constructor should simply
delegate its responsibilities to the equivalent constructor in the Exception class.
5. Add a public constructor to the ClassFullException class that takes a string parameter containing the
exception message. This constructor should also delegate its functionality to the equivalent
constructor in the Exception class.
6. Add a public constructor to the ClassFullException that takes a string parameter holding the
exception message and an Exception object containing an inner exception. Like the previous
constructors, this constructor should delegate its functionality to the equivalent constructor in the
Exception class.
7. Add a public custom constructor that takes the exception message and the name of the class that is
full as parameters. Invoke the Exception constructor with the exception message, but store the name
of the class in the _className field.
8. Add a public custom constructor that takes the exception message, the name of the class that is full,
and an Exception object containing an inner exception as parameters. Invoke the Exception
constructor with the exception message and the inner exception, but store the name of the class in
the _className field.
2. In the EnrollInClass method of the Teacher class, if the current number of students is already equal
to the value in MAX_CLASS_SIZE, then throw a ClassFullException with a suitable message and the
name of the class that is full (the name of the class is available in the Class property of the Teacher).
3. Students are enrolled in a class by using the AssignStudentDialog window. Open the
AssignStudentDialog.xaml.cs file and review the code in the Student_Click method. This method
5-36 Creating a Class Hierarchy by Using Inheritance
runs when the user selects a student to add to a class. Notice that the try block in this method
includes the following statement:
SessionContext.CurrentTeacher.EnrollInClass(student);
4. Add a catch handler after the try block that catches the ClassFullException. In this catch handler,
display a suitable message that includes the exception message and class name from the exception.
Results: After completing this exercise, you should have created a new custom exception class and used it
to report when too many students are enrolled in a class.
Programming in
i Visual C# 5-37
7
Module Rev
view an
nd Take
eaways
M
Module Rev
view
IIn this modulee, you have leearned how to
o use inheritan
nce and exten
nsion methods to extend th
he
f
functionality o
of existing typ
pes.
T
Test Your Kno
owledge
Question
Absttract methodss.
Prottected method
ds.
Public methods.
Static methods.
Virtu
ual methods.
T
Test Your Kno
owledge
Question
You want too create an exxtension meth hod for the Sttring class. Yo
ou create a sttatic method
within a stattic class. How
w do you indiccate that your method exttends the Striing type?
Question
Module 6
Reading and Writing Local Data
Contents:
Module Overview 6-2
Modu
ule Ove
erview
Reeading and wrriting data are e core requirements for many application ns, such as a ttext file editorr saving a
file
e to the file syystem, or a Wiindows servicee writing erro
or messages to
o a custom log g file. The local file
sysstem providess the perfect e environment for
f an applicaation to read aand write such h data, becausse access is
fasst and the locaation is readily available. Th
he Microsoft .NET
. Framewo ork provides a variety of I/O O classes
thaat simplify the e process of im
mplementing I/O functionaality in your appplications.
In this module, yyou will learn how to read and write datta by using atomic file systeem I/O operattions, how
to serialize and deserialize daata to the file system, and h
how to read and write dataa to the file sysstem by
usiing streams.
Ob
bjectives
Aftter completing this module
e, you will be able to:
Read and w
write data to aand from the ffile system by using file I/O
O.
Lesson 1
Read
ding and
d Writing File
es
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Re
eading an
nd Writing
g Data by Using the
e File Classs
2. Open a stre
eam to the file
e.
3. Buffer the d
data from the file into mem
mory.
4. Release the
e file handle so
o that it can b
be reused.
The static metho ods that the F File class expooses are conve enient becausse they encapssulate intricatte, low-level
nctions. Howe
fun ever their convenience and the fact that they shield th he developer from the underlying
fun
nctionality me eans in some cases they do ont offer the ccontrol or flexxibility that ap
pplications req
quire. For
exaample, the ReeadAllText m method will reaad the entire ccontents of a file into mem mory. For smalll files this
will be fine, but for large filess it can presen
nt scalability isssues, and maay result in an unresponsive e UI in your
ap
pplication.
Re
eading Data
a from Files
The File class prrovides severaal methods that you can usse to read dataa from a file. T
The format off your data
and how your application inttends to proce ess it will influ
uence the metthod that you should use. T
The
folllowing list de
escribes some of these methods:
The ReadA AllText metho u to read the contents of a file into a single string variable. The
od enables you
following co
ode example shows how too read the con
ntents of the settings.txt
s file
e into a string
g named
settings.
string fileP
Path = "C:\\fo
ourthCoffee\\s
settings.txt";
string se
ettings = File.ReadAllText(filePath
h);
ilePath = "C
string fi C:\\fourthCofffee\\settings
s.txt";
string[] settingsLin
neByLine = File.ReadAllL Lines(filePa
ath);
Programming in Visual C# 6-5
The ReadAllBytes method enables you to read the contents of a file as binary data and store the
data in a byte array. The following code example shows how to read the contents of the settings.txt
file into a byte array named rawSettings.
Each of these methods enables you to read the contents of a file into memory. You could use the
ReadAllText method if you wanted to cache the entire file in memory in a single operation. Alternatively,
if you wanted to process a file line-by-line, you could use the ReadAllLines method to read each line into
an array.
If the specified file does not exist, the Writexxx methods create a new file with the new data. If the file
does exist, the Writexxx methods overwrite the existing file with the new data.
If the specified file does not exist, the Appendxxx methods also create a new file with the new data.
However, if the file does exist, the new data is written to the end of the existing file.
The WriteAllText method enables you to write the contents of a string variable to a file. If the file
exists, its contents will be overwritten. The following code example shows how to write the contents
of a string named settings to a new file named settings.txt.
The WriteAllLines method enables you to write the contents of a string array to a file. Each entry in
the string array represents a new line in the file. The following code example shows how to write the
contents of a string array named hosts to a new file named hosts.txt.
The WriteAllBytes method enables you to write the contents of a byte array to a binary file. The
following code example shows how to write the contents of a byte array named rawSettings to a
new file named settings.txt.
The AppendAllText method enables you to write the contents of a string variable to the end of an
existing file. The following code example shows how to write the contents of a string variable named
settings to the end of the existing settings.txt file.
The AppendAllLines method enables you to write the contents of a string array to the end of an
existing file. The following code example shows how to write the contents of a string array named
newHosts to the existing hosts.txt file.
Each of these methods enables you to write data to a file. If you want to add data to an existing file that
may already exist, then you should use an Appendxxx method. If you want to overwrite an existing file,
then you should use a Writexxx method. Then, depending on how you want the information is stored
(whether as binary data, a textual blob in a string, or an array of strings representing each individual line)
use the xxxAllBytes, xxxAllText, or xxxAllLines method.
Programmingg in Visual C# 6-7
7
M
Manipulat
ting Files
F Manipu
File ulation by using
u the F
File Class
The File class provides static methods th
T hat you can usse to perform basic file manipulation. Th
he following
l describes ssome of these
list e methods:
The Existts method enaables you to ccheck whether a file exists o on the file system. The follo
owing code
example shows how to o check wheth her the setting
gs.txt file existts.
The GetCreationTime method enables you to read the date time stamp that describes when a file
was created, from the metadata associated with the file. The following code example shows how you
can determine when the settings.txt file was created.
There are many other operations and metadata associated with files that you can utilize in your
applications. The FileInfo class provides access to these through a number of instance members.
After you have created an instance of the FileInfo class, you can use the properties and methods that it
exposes to interact with the file. The following list describes some of these properties and methods:
The CopyTo method enables you to copy an existing file to a different directory on the file system.
The following code example shows how to copy the settings.txt file from the C:\fourthCoffee\
directory to the C:\temp\ directory.
Note: The overwrite parameter passed to the CopyTo method call indicates that the copy
process should overwrite an existing file if it exists at the destination path. If you pass false to the
CopyTo method call, and the file already exists, the CLR will throw a System.IO.IOException.
The Delete method enables you to delete a file. The following code example shows how to delete the
settings.txt file.
The DirectoryName property enables you to get the directory path to the file. The following code
example shows how to get the path to the settings.txt file.
The Exists method enables you to determine if the file exists within the file system. The following
code example shows how to check whether the settings.txt file exists.
The Extension property enables you to get the file extension of a file. The following code example
shows how to get the extension of a path returned from a method call.
The Length property enables you to get the length of the file in bytes. The following code example
shows how to get the length of the settings.txt file.
M
Manipulati ng Directo
ories
It iis a common requirement forf applications to interact and manipulaate the file system directorry structure,
whhether to checck that a direcctory exists be
efore writing a file or to rem
move directorries when runn
ning a
sysstem cleanup process. The .NET Framew work class libra
ary provides thhe Directory and DirectorryInfo
cla
asses for such operations.
Manipulating
g Directorie
es by using
g the Directtory Class
Sim
milar to the Fiile class, the Directory
D classs provides staatic methods tthat enable yo
ou to interactt with
dirrectories, with
hout instantiatting a directory-related objject in your co
ode. The following list desccribes some
of these static mmethods:
The CreateDirectory me
ethod enabless you to create a new direcctory on the file system. The
e following
example shows how to create the C:\ffourthCoffee\ttempData dire
ectory.
string di
irectoryPath
h = "C:\\fourthCoffee\\t
tempData";
Directory
y.CreateDire
ectory(directoryPath);
string di
irectoryPath
h = "C:\\fourthCoffee\\t
tempData";
bool recu
ursivelyDele
eteSubContent = true;
Directory
y.Delete(dir
rectoryPath, recursively
yDeleteSubCo
ontent);
Note: The
e recursivelyDDeleteSubCo ontent parame eter passed in
nto the Deletee method calll
inddicates whether the delete process should delete any content that may exist in tthe directory. If
you pass false into the Delette method calll, and the dire
ectory is not e
empty, the CLLR will throw a
Syystem.IO.IOEx xception.
string di
irectoryPath
h = "C:\\fourthCoffee\\t
tempData";
bool temp
pDataDirecto
oryExists = Directory.Ex
xists(direct
toryPath);
Programming in Visual C# 6-11
The GetDirectories method enables you to get a list of all subdirectories within a specific directory
on the file system. The following code example shows how to get a list of all the sub directories in the
C:\fourthCoffee\tempData directory.
The GetFiles method enables you to get a list of all the files within a specific directory on the file
system. The following example shows how to get a list of all the files in the C:\fourthCoffee\tempData
directory.
The DirectoryInfo class provides instance members that enable you to access directory metadata and
manipulate the directory structure.
When you have created an instance of the DirectoryInfo class, you can then use its properties and
methods to interact with the directory. The following list describes some of these properties and methods:
The Create method enables you to create a new directory on the file system. The following example
shows how to create the C:\fourthCoffee\tempData directory.
The Delete method enables you to delete a directory at a specific path. The following code example
shows how to delete the C:\fourthCoffee\tempData directory, and all its contents.
The Exists property enables you to determine if a directory exists on the file system. The following
code example shows how to determine if the C:\fourthCoffee\tempData directory exists.
The FullName property enables you to get the full path to the directory. The following example
shows how to get the full path to the tempData directory.
The GetDirectories method enables you to get a list of all subdirectories within a specific directory
on the file system. In contrast to the static File.GetDirectories method, this instance method returns
an array of type DirectoryInfo, which enables you to use each of the instance properties for each
subdirectory. The following code example shows how to get all of the sub directories in the
C:\fourthCoffee\tempData directory.
The GetFiles method enables you to get a list of all the files within a specific directory on the file
system. In contrast to the static File.GetFiles method, this instance method returns an array of type
FileInfo, which enables you to use each of the instance properties for each file. The following
example shows how to get all of the files in the C:\fourthCoffee\tempData directory.
M
Manipulat
ting File aand Directtory Pathss
C
Creating a Te
emporary Dirrectory the H
Hard Way
string temp
pDirectoryPa
ath = "C:\\fourthCoffee\
\\tempData";
if (!Direct
tory.Exists(
(tempDirectoryPath))
Directo
ory.CreateDirectory(tempDirectoryPa
ath);
However, with
H h the above approach, you are making m many assumpttions, includin ng whether yo
our
a
application haas the necessaary privileges to perform I/O
O at the root of the C drive
e, and whethe
er the C drive
a
actually existss.
G
Getting the P
Path to the W
Windows Tem
mporary Directory
string temp
pDirectoryPa
ath = Path.GetTempPath()
);
The HasEExtension me ethod enables you to determine if the paath your appliication is proccessing has an
n
extension
n. This provide es a convenien
nt way for you
u to determin
ne if you are p
processing a file or a
directory.. The following example shows how to ccheck whetherr the path hass an extension n.
The GetExtension method enables you to get the extension from a file name. This method is
particularly useful when you want to ascertain what type of file your application is processing. The
following code example shows how to check whether the settingsPath variable contains a path that
ends with the .txt extension.
The GetTempFileName enables you to create a new temp file in your local Windows temporary
directory in a single atomic operation folder. This method then returns the absolute path to that file,
ready for further processing. The following code shows how to invoke the GetTempFileName
method.
Additional Reading: For more information about the Path class, see the Path Class page
at http://go.microsoft.com/fwlink/?LinkID=267805.
Programming in
i Visual C# 6-15
5
D
Demonstr
ration: Manipulatin
ng Files, D
Directoriess, and Paths
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA-DEV11-06 virrtual machine..
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Open File
e Explorer and
d browse to th
he E:\Democo
ode\Data\Lo
ogs folder.
6
6. In the E:\Democode\D
Data\Logs folder, double-click each of the
e text files, an
nd view the co
ontents in
Notepad..
7
7. Close NottePad.
8
8. Switch to the Windowss 8 Start wind
dow.
9
9. Click Visu
ual Studio 201
12.
1 In Visual Studio, on the
10. e File menu, p
point to Open
n, and then click Project/Solution.
1 In the Op
11. pen Project dia
alog box, browwse to E:\Dem er\FourthCofffee.LogProcessor folder,
mocode\Starte
click FourrthCoffee.LogProcessor.sln,, and then clicck Open.
1 In Visual Studio, on the
12. e View menu,, click Task Liist.
if (!Dir
rectory.Exis
sts(logDirectoryRoot))
6-16 Reading and Writing Local Data
16. In the Task List window, double-click the TODO: 02: Get all log file paths. task.
17. In the code editor, click in the blank line below the comment, and then type the following code:
18. In the Task List window, double-click the TODO: 03: Check for existing combined log file and delete if
it already exists. task.
19. In the code editor, click in the blank line below the comment, and then type the following code:
if (File.Exists(combinedLogPath))
File.Delete(combinedLogPath);
20. In the Task List window, double-click the TODO: 04: Write the heading to the combined log file. task.
21. In the code editor, click in the blank line below the comment, and then type the following code:
File.AppendAllLines(combinedLogPath, heading);
22. In the Task List window, double-click the TODO: 05: Get the log file name without the file extension.
task.
23. In the code editor, click in the blank line below the comment, and then type the following code:
var logName =
Path.GetFileNameWithoutExtension(logPath);
24. In the Task List window, double-click the TODO: Task 06: Read the contents of the existing log file.
task.
25. In the code editor, click in the blank line below the comment, and then type the following code:
26. In the Task List window, double-click the TODO: Task 07: Write the log file contents to the combined
log file. task.
27. In the code editor, click in the blank line below the comment, and then type the following code:
File.AppendAllLines(combinedLogPath, logContent);
30. In the Command Prompt window, when prompted to press any key to continue, press Enter.
32. Double-click CombinedLog.txt, verify that the file contains a heading, and then verify the contents
of each log file.
33. Close Notepad, close File Explorer, and then close Visual Studio.
Programming in
i Visual C# 6-17
7
Lesson 2
Seria
alizing a
and Deserializing Datta
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
W
What Is Serrialization?
Se
erializable F
Formats
The requiremennts of your sysstem, and how
w you intend to
t transport th
he data, will in
nfluence the serialization
s
forrmat you choo
ose. The following table de
escribes some of the comm
mon formats avvailable.
FFormat Descripttion
B
Binary Serializing data into tthe machine-readable binaary format enaables you to p preserve the
fidelity and state of aan object betwween differentt instances of your applicattion. Binary
ation is also fa
serializa ast and lightw
weight, becausse the binary fformat does n
not require the e
processing and storage of unnecessary formattiing constructss.
Binary sserialization iss commonly used when perrsisting and trransporting ob bjects betweeen
applicattions running on the same platform.
Binary EExample
010002552552552551
100000001220
000727311010570105108101
183101114105
597108
105122101114443286
610111411510
051111106149464846484648
844326711710
081161
171141016111010111
171161149710
084432801179810810599751
101121841111
107101
110611101171081085
510003873110
010570105108101831011141
105971081051
122101
114468310111411810
059910167111
111010210510311711497116
610511111030
000106
711111010210510378
897109101166
689711697989711510172111
111511678971
109101
196511211210810599
997116105111
111068971169780971161041
111200063000
020701
111171141161046711
111021021011
101956810110297117108116
664000281009
971169
798971151015048574
461021111171
114116104991111021021011
101469911110
096500
032675892102111117
711411610499
911110210210110192971121
112108105999
971161
051111101009711697
79211
X
XML Serializing data into tthe XML form mat enables yo ou to utilize an
n open standa ard that can be
b
processed by any app plication, regaardless of plattform. In conttrast to binaryy, XML does not
preserve e type fidelityy; it only lets you
y serialize ppublic membe ers that your tyype exposes.
Programming in Visual C# 6-19
Format Description
The XML format is more verbose than binary, as the serialized data is formatted with XML
constructs. This makes the XML format less efficient and more processor intensive during
the serializing, deserializing, and transporting processes.
XML serialization is commonly used to serialize data that can be transported via the SOAP
protocol to and from web services.
XML Example
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP- ENV=http://schemas.xmlsoap.org/soap/envelope/
xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<a1:ServiceConfiguration id="ref-1"
xmlns:a1="http://schemas.microsoft.com/clr/nsassem/
FourthCoffeeSerializer/%2C%20Version%3D1.0.0.0%2C%20
Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
<ConfigName id="ref-3">
FourthCoffee_Default
</ConfigName>
<DatabaseHostName id="ref-4">
database209.fourthcoffee.com
</DatabaseHostName>
<ApplicationDataPath id="ref-5">
C:\fourthcoffee\applicationdata\
</ApplicationDataPath>
</a1:ServiceConfiguration>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
JSON Serializing data into the JSON format enables you to utilize a lightweight, data-
interchange format that is based on a subset of the JavaScript programming language.
JSON is a simple text format that is human readable and also easy to parse by machine,
irrespective of platform.
JSON is commonly used to transport data between Asynchronous JavaScript and XML
(AJAX) calls because unlike XML, you are not limited to just communicating within the
same domain.
JSON Example
{
"ConfigName":"FourthCoffee_Default",
"DatabaseHostName":"database209.fourthcoffee.com",
"ApplicationDataPath":"C:\\fourthcoffee\\applicationdata\\"
}
Alternatively, if you want to serialize your data to a format that the .NET Framework does not natively
support, you can implement your own custom serializer class.
6-20 Readingg and Writing Local Data
Crreating a S
Serializable Type
The .NET Frame ework provide es many classees that are serrializable. If yo
ou want to cre
eate your ownn types that
are
e serializable, you need to e ensure that th
he type definittion incudes tthe necessary configuration n and
fun
nctionality forr the serilalize
er to consume e. The .NET Fraamework provvides the Systtem and
Sy
ystem.Runtim me.Serializatio on namespaces, which provide classes to alization support.
o enable seria
To
o create a seriaalizable type, perform the ffollowing step
ps:
1. Define a de
efault construcctor.
public cl
lass Service
eConfiguratio
on
{
public
c ServiceCon
nfiguration()
{
...
.
}
}
2. Decorate th
he class with the
t Serializab
ble attribute p
provided in the System nam
mespace.
[Serializ
zable]
public cl
lass Service
eConfiguratio
on
{
...
}
[Serializzable]
public cllass Service
eConfiguratio
on : ISerial
lizable
{
...
publicc void GetOb
bjectData(SerializationI
Info info, S
StreamingContext context
t)
{
...
.
}
}
Programming in Visual C# 6-21
[Serializable]
public class ServiceConfiguration : ISerializable
{
...
public ServiceConfiguration(SerializationInfo info, StreamingContext ctxt)
{
...
}
}
5. Define the public members that you want to serialize. You can instruct the serializer to ignore private
fields by decorating them with the NonSerialized attribute.
...
[NonSerialized]
private Guid _internalId;
public string ConfigName { get; set; }
public string DatabaseHostName { get; set; }
public string ApplicationDataPath { get; set; }
...
The following code example shows the complete ServiceConfiguration class, which is serializable by any
of the .NET Framework IFormatter implementations.
Serializable Type
[Serializable]
public class ServiceConfiguration : ISerializable
{
[NonSerialized]
private Guid _internalId;
public string ConfigName { get; set; }
public string DatabaseHostName { get; set; }
public string ApplicationDataPath { get; set; }
public ServiceConfiguration()
{
}
public ServiceConfiguration(SerializationInfo info, StreamingContext ctxt)
{
this.ConfigName
= info.GetValue("ConfigName", typeof(string)).ToString();
this.DatabaseHostName
= info.GetValue("DatabaseHostName", typeof(string)).ToString();
this.ApplicationDataPath
= info.GetValue("ApplicationDataPath", typeof(string)).ToString();
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("ConfigName", this.ConfigName);
info.AddValue("DatabaseHostName", this.DatabaseHostName);
info.AddValue("ApplicationDataPath", this.ApplicationDataPath);
}
}
6-22 Readingg and Writing Local Data
Se
erializing O
Objects ass Binary
Note: The e BinaryFormmatter and SooapFormatterr classes imple ement the IFo
ormatter
intterface. You caan also implement the IForrmatter interrface to create
e your own cu
ustom serialize
er.
Se
erialize an Object
O by Using
U the BinaryForma
atter Class
To
o serialize an object
o by using the BinaryF
Formatter claass, perform the following steps:
s
2. nstance of the
Create an in e BinaryForm
matter that yo
ou want to use
e to serialize yyour type.
3. Create a strream that you
u will use as a buffer to storre the serialize
ed data.
The following co
ode example shows how to
o use the Bina
aryFormatterr class to seria
alize an objectt as binary.
naryFormatter Serialize E
Bin Example
/
// Create the
e object you
u want to se
erialize.
S
ServiceConfig
guration con
nfig = ServiceConfigurat
tion.Default
t;
/
// Create the
e formatter you want to
o use to seri
ialize the o
object.
I
IFormatter fo
ormatter = n
new BinaryFo
ormatter();
/
// Create the
e stream tha
at the seria
alized data will
w be buff
fered to.
F
FileStream bu
uffer = File
e.Create("C:\\fourthcoff
fee\\config.
.txt");
/
// Invoke the
e Serialize method.
f
formatter.Serialize(buff
fer, config);
/
// Close the stream.
b
buffer.Close();
This example, se
erializes the ServiceConfig guration object, and writess the serialized d data to a filee. It is
important to noote that serialiization doesnt just imply w
writing data to
o a file. Serializzation is the p
process of
Programming in Visual C# 6-23
transforming a type into another format, which you can then write to a file or database, or send over
HTTP to a web service.
3. Invoke the BinaryFormatter.Deserialize method, passing in stream that contains the serialized data.
4. Cast the result of the BinaryFormatter.Deserialize method call into the type of object that you are
expecting.
The following code example shows how to use the BinaryFormatter class to deserialize binary data to an
object.
The above example reads the serialized binary data from a file, and then deserializes the binary into a
ServiceConfiguration object. The process is the same for serializing and deserializing objects by using
any formatters that implement the IFormatter interface. This includes the SoapFormatter class, and any
custom formatters that you may implement.
6-24 Readingg and Writing Local Data
Se
erializing O
Objects ass XML
Se
erialize an Object
O by Using
U the So
oapFormattter Class
The process for serializing daata as XML is ssimilar to the process of serrializing to bin
nary, with the
e exception
tha
at you use the
e SoapForma atter class.
The following co
ode example shows how to
o use the Soap
pFormatter cclass to serializze an object aas XML.
So
oapFormatterr Serialize Example
/
// Create the
e object you
u want to se
erialize.
S
ServiceConfig
guration con
nfig = ServiceConfigurat
tion.Default
t;
/
// Create the
e formatter you want to
o use to seri
ialize the o
object.
I
IFormatter fo
ormatter = n
new SoapForm
matter();
/
// Create the
e stream tha
at the seria
alized data will
w be buff
fered too.
F
FileStream bu
uffer = File
e.Create("C:\\fourthcoff
fee\\config.
.xml");
/
// Invoke the
e Serialize method.
f
formatter.Serialize(buff
fer, config);
/
// Close the stream.
b
buffer.Close();
De
eserialize an Object by
y Using the
e SoapForm
matter Classs
The process for deserializing data from XM
ML to an objecct is identical to the processs of deserializzing binary
data, with the exception that you use the SoapFormatt
S ter class.
The following co
ode example shows how to
o use the Soap
pFormatter cclass to deseriialize XML datta to an
ob
bject.
So
oapFormatterr Deserialize Example
/
// Create the
e formatter you want to
o use to seri
ialize the o
object.
I
IFormatter fo
ormatter = n
new SoapForm
matter();
/
// Create the
e stream tha
at the seria
alized data will
w be buff
fered too.
F
FileStream bu
uffer = File
e.OpenRead("C:\\fourthco
offee\\confi
ig.xml");
/
// Invoke the
e Deserializ
ze method.
S
ServiceConfig
guration con
nfig = forma
atter.Deseria
alize(buffer
r) as Servic
ceConfigurati
ion;
Programming in Visual C# 6-25
Se
erializing O
Objects ass JSON
Se
erialize an Object
O by Using
U the DataContrac
D ctJsonSerializer Class
To
o serialize an object
o by using the DataCo
ontractJsonSe
erializer classs, perform the
e following ste
eps:
1. Obtain a reference to the
e object that yyou want to serialize.
s
2. nstance of the
Create an in e DataContra actJsonSerialiizer class thatt you want to use to serializze your
type. The co
onstructor also requires you to pass in a Type object, representing the type of o object you
want to serialize.
The following co
ode example shows how to
o use the Data
aContractJso
onSerializer class
c to serializze an
ob
bject as JSON.
Da
ataContractJssonSerializerr Serialize Exa
ample
/
// Create the
e object you
u want to se
erialize.
S
ServiceConfig
guration con
nfig = ServiceConfigurat
tion.Default
t;
/
// Create a D
DataContract
tJsonSerializer object that
t you wil
ll use to se
erialize the
/
// object to JSON.
D
DataContractJ
JsonSerializ
zer jsonSerializer
= new Data
aContractJso
onSerializer
r(config.GetT
Type());
/
// Create the
e stream tha
at the seria
alized data will
w be buff
fered too.
F
FileStream bu
uffer = File
e.Create("C:\\fourthcoff
fee\\config.
.txt");
/
// Invoke the
e WriteObjec
ct method.
jsonSerialize
er.WriteObje
ect(buffer, config);
/
// Close the stream.
b
buffer.Close();
Programming in Visual C# 6-27
1. Create an instance of the DataContractJsonSerializer class that you want to use to serialize your
type. The constructor also requires you to pass in a Type object, representing the type of object you
want to deserialize.
2. Create a stream that will read the serialized JSON into memory.
3. Invoke the DataContractJsonSerializer.ReadObject method, passing in the stream that contains the
serialized data.
4. Cast the result of the DataContractJsonSerializer.ReadObject method call into the type of object
you are expecting.
The following code example shows how to use the DataContractJsonSerializer class to deserialize JSON
data to an object.
Crreating a C
Custom Serializer
Yo
ou may want tto serialize datta into a form
mat other than n binary, XML,, or JSON. The
e .NET Framew work
pro
ovides the IFo
ormatter inteerface in the SSystem.Runtime.Serializattion namespa ace, so you can create
your own formaatter. Your cusstom formatte er will then fo
ollow the same
e pattern as th
he BinaryForrmatter and
So
oapFormatterr classes.
To
o create your o
own formatter, perform the
e following ste
eps:
The following co
ode example shows a custo
om formatter that can seriaalize and dese
erialize objectss to the .ini
forrmat.
Cu
ustom IniForm
matter
u
using System;
u
using System.Collections
s.Generic;
u
using System.IO;
u
using System.Reflection;
;
u
using System.Runtime.Ser
rialization;
n
namespace Fou
urthCoffee.S
Serializer
{
class IniFormatter : IFormatter
{
static readonly ch
har[] _delimm = new char[] { '=' };
public ISurrogateS
Selector SurrrogateSelect
tor { get; s
set; }
public Serializati
ionBinder Binder { get; set; }
public StreamingCo
ontext Conteext { get; se
et; }
public IniFormatte
er()
{
this
s.Context
= new Stream
mingContext((StreamingCon
ntextStates.
.All);
}
public object Dese
erialize(Strream serializ
zationStream
m)
{
Stre
eamReader bu
uffer
= new Stream
mReader(serializationStream);
// G
Get the type
e from the sserialized da
ata.
Programming in Visual C# 6-29
D
Demonstr
ration: Se
erializing to
t XML
D
Demonstra
ation Steps
1
1. Switch to the Windowss 8 Start wind
dow.
2
2. Click Visu
ual Studio 201
12.
3
3. In Visual Studio, on the
e File menu, p n, and then click Project/Solution.
point to Open
4
4. In the Op
pen Project dia
alog box, browwse to E:\Dem mocode\Starte
er\FourthCofffee.ExceptionLLogger, click
FourthCooffee.Exception
nLogger.sln, aand then clickk Open.
5
5. In Visual Studio, on the
e View menu,, click Task Liist.
6
6. In the Tassk List windo
ow, in the Cate
egories list, click Commen
nts.
7
7. Double-cclick the TODO
O: 01: Decoratte the type wiith the Serializzable attribute
e. task.
8
8. In the cod
de editor, click in the blankk line below th
he comment, and then type
e the followin
ng code:
[Seriali
izable]
9
9. In the Tassk List window
w, double-click the TODO: 0
02: Implemen
nt the ISerializzable interface
e. task.
1 In the cod
10. de editor, click in the blankk line below th
he comment, and then type
e the followin
ng code:
: ISeria
alizable
info.Add
dValue("Titl
le", this.Title);
info.Add
dValue("Deta
ails", this.Details);
14. In the code editor, click in the blank line below the comment, and then type the following code:
public ExceptionEntry(
SerializationInfo info,
StreamingContext context)
{
this.Title = info.GetString("Title");
this.Details = info.GetString("Details");
}
15. In the Task List window, double-click the TODO: 04: Create a SoapFormatter object and serialize the
entry object. task.
16. In the code editor, click in the blank line below the comment, and then type the following code:
17. In the Task List window, double-click the TODO: 05: Create a SoapFormatter object and deserialize
the stream to the entry object. task.
18. In the code editor, click in the blank line below the comment, and then type the following code:
21. In the Exception Logger window, create a new exception entry by using the following information,
and then click Save:
22. In the Save Successful message box, click OK. The exception entry has now been serialized.
25. In the E:\Democode\Data\Exceptions folder, double-click the Exception_<date and time>.txt file.
29. Close the application, close Visual Studio, and then close File Explorer.
Programming in
i Visual C# 6-33
3
Lesson 3
Perfo
orming I/O by
y Using Stream
ms
When you wo
W ork with data, whether the data
d is stored in a file on th
he file system or on a web sserver
a
accessible ove
er HTTP, the ddata sometime es becomes to oo large to load into memo ory and transm mit in a single
e
a
atomic operattion. For exam
mple, imagine trying to loadd a 200-gigab byte video file
e from the file
e system into
m
memory in a single
s operatiion. Not only would the opperation take a long time, b but it would also consume
a large amoun nt of memoryy.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
W
What are Sttreams?
The .NET Frame ework enabless you to use sttreams. A stream is a seque ence of bytes, which could come from
a ffile on the file system, a nettwork connection, or memo ory. Streams eenable you too read from orr write to a
data source in small, manage eable data pacckets. Typically, streams pro
ovide the follo
owing operatiions:
Reading chunks of data into
i a type, su
uch as a byte array.
Querying th
he current position in the stream and mo
odifying a spe
ecific selection
n of bytes at tthe current
position.
Sttreaming in
n the .NET Framework
F k
The .NET Frameework provide
es several streaam classes thaat enable you to work with a variety of data
d and
data sources. W
When choosing
g which stream m classes to use, you need to consider th
he following:
What type o
of data you are reading or writing, for exxample, binarry or alphanum
meric.
Where the d
data is stored, for example, on the local file system, in
n memory, or on a web servver over a
network.
The .NET Frame ework class lib brary provides several classees in the Systeem.IO namesspace that you u can use to
reaad and write ffiles by using streams. At thhe highest level of abstractiion, the Strea
am class definnes the
common functio onality that alll streams provide. The classs provides a ggeneric view oof a sequencee of bytes,
tog he operations and properties that all stre
gether with th eams provide.. Internally, a Stream objecct maintains
appointer that reefers to the cu
urrent locationn in the data source. When n you first con
nstruct a Strea
am object
ovver a data source, this pointter is positione
ed immediate ely before the first byte. As you read andd write data,
thee Stream classs advances th his pointer to the end of the e data that is read or writte
en.
Yo
ou cannot use the Stream cclass directly. Instead, you instantiate spe of this class that are
ecializations o
opptimized to pe
erform stream
m-based I/O fo or specific type es of data sou
urces. For exam
mple, the File eStream
cla
ass implementts a stream that uses a diskk file as the daata source, and
d the MemorryStream classs
implements a sttream that usees a block of mmemory as th he data source e.
Programming in
i Visual C# 6-35
5
T
Types of S
Streams in
n the .NET
T Framewo
ork
MemoryStre
eam Enables yyou to establissh a stream too a location in memory. The
e
MemoryS Stream class handles operaations such ass acquiring the in-memory
storage, aand provides access
a to the memory locattion through a raw sequence
of bytes.
StreamRead
der Enables youu to read textu
ual data from
m an underlying data source
e stream, such
h as
a FileStream, MemoryS Stream, or NeetworkStream m object.
BinaryReade
er Enables you
u to read bina
ary data from an underlying
g data source stream, such as
6-36 Reading and Writing Local Data
BinaryWriter Enables you to write binary data to an underlying data source stream, such as a
FileStream, MemoryStream, or NetworkStream object.
Programming in
i Visual C# 6-37
7
R
Reading aand Writin
ng Binary Data by U
Using Stre
eams
M
Many applicattions store daata in raw binaary form for a number of re
easons, such aas the followin
ng:
Writing b
binary data is fast.
f
I
Initializing a BinaryReade
er and Binary
yWriter Obje
ect
string file
ePath = "C:\
\\fourthcoffee\\applicat
tiondata\\se
ettings.txt";
FileStream file = new FileStream(filePath);
...
BinaryReade
er reader = new BinaryReader(file);
;
...
BinaryWrite
er writer = new BinaryWriter(file);
;
After you havve created a BinaryReader object, you can use its members to read
A d the binary d
data. The
f
following list d me of the key members:
describes som
The Base
eStream property enables yyou to access the underlyin
ng stream thatt the BinaryR
Reader object
uses.
The Close
e method enaables you to cclose the BinaryReader objject and the underlying
u stre
eam.
The Read
d method enables you to re
ead the numb
ber of remaining bytes in th
he stream from
m a specific
index.
The ReaddByte method
d enables you to read the n
next byte from
m the stream, and advance the stream to
o
the next b
byte.
6-38 Reading and Writing Local Data
The ReadBytes method enables you to read a specified number of bytes into a byte array.
Similarly, the BinaryWriter object exposes various members to enable you to write data to an underlying
stream. The following list describes some of the key members.
The BaseStream property enables you to access the underlying stream that the BinaryWiter object
uses.
The Close method enables you to close the BinaryWiter object and the underlying stream.
The Flush method enables you to explicitly flush any data in the current buffer to the underlying
stream.
The Seek method enables you to set your position in the current stream, thus writing to a specific
byte.
The Write method enables you to write your data to the stream, and advance the stream. The Write
method provides several overloads that enable you to write all primitive data types to a stream.
BinaryReader Example
// Source file path.
string sourceFilePath =
"C:\\fourthcoffee\\applicationdata\\settings.txt ";
// Create a FileStream object so that you can interact with the file
// system.
FileStream sourceFile = new FileStream(
sourceFilePath, // Pass in the source file path.
FileMode.Open, // Open an existing file.
FileAccess.Read);// Read an existing file.
// Create a BinaryWriter object passing in the FileStream object.
BinaryReader reader = new BinaryReader(sourceFile);
// Store the current position of the stream.
int position = 0;
// Store the length of the stream.
int length = (int)reader.BaseStream.Length;
// Create an array to store each byte from the file.
byte[] dataCollection = new byte[length];
int returnedByte;
while ((returnedByte = reader.Read()) != -1)
{
// Set the value at the next index.
dataCollection[position] = (byte)returnedByte;
// Advance our position variable.
position += sizeof(byte);
}
// Close the streams to release any file handles.
reader.Close();
sourceFile.Close();
BinaryWriter Example
string destinationFilePath = "C:\\fourthcoffee\\applicationdata\\settings.txt";
// Collection of bytes.
byte[] dataCollection = { 1, 4, 6, 7, 12, 33, 26, 98, 82, 101 };
Programming in Visual C# 6-39
// Create a FileStream object so that you can interact with the file
// system.
FileStream destFile = new FileStream(
destinationFilePath, // Pass in the destination path.
FileMode.Create, // Always create new file.
FileAccess.Write); // Only perform writing.
// Create a BinaryWriter object passing in the FileStream object.
BinaryWriter writer = new BinaryWriter(destFile);
// Write each byte to stream.
foreach (byte data in dataCollection)
{
writer.Write(data);
}
// Close both streams to flush the data to the file.
writer.Close();
destFile.Close();
6-40 Readingg and Writing Local Data
Re
eading an
nd Writing
g Text Datta by Using Streamss
The Close m
method enablles you to closse the Stream
mReader obje
ect and the un
nderlying strea
am.
The EndOfS
Stream prope
erty enables yyou to determ
mine whether yyou have reacched the end of the
stream.
The Peek m
method enable er in the stream, but does n
es you to get the next available characte not
consume it..
The Read m method enables you to get and consume e the next avaailable charactter in the stream. This
method retturns an int vaariable that re hich you may need to
epresents the binary of the character, wh
explicitly co
onvert.
The ReadBlock method enables you to
t read an entire block of ccharacters from a specific in
ndex from
the stream.
Programming in Visual C# 6-41
The ReadLine method enables you to read an entire line of characters from the stream.
The ReadToEnd method enables you to read all characters from the current position in the stream.
Similarly, the StreamWriter object exposes various members to enable you to write data to an underlying
stream. The following list describes some of the key members:
The AutoFlush property enables you to instruct the StreamWriter object to flush data to the
underlying stream after every write call.
The Close method enables you to close the StreamWriter object and the underlying stream.
The Flush method enables you to explicitly flush any data in the current buffer to the underlying
stream.
The NewLine property enables you to get or set the characters that are used for new line breaks.
The Write method enables you to write your data to the stream, and to advance the stream.
The WriteLine method enables you to write your data to the stream followed by a new line break,
and then advance the stream.
These members provide many options to suit many different requirements. If you do not want to store the
entire file in memory in a single chunk, you can use a combination of the Peek and Read methods to
read each character, one at a time. Similarly, if you want to write lines of text to a file one at time, you can
use the WriteLine method.
StreamReader Example
string sourceFilePath =
@"C:\\fourthcoffee\\applicationdata\\settings.txt ";
// Create a FileStream object so that you can interact with the file
// system.
FileStream sourceFile = new FileStream(
sourceFilePath, // Pass in the source file path.
FileMode.Open, // Open an existing file.
FileAccess.Read);// Read an existing file.
StreamReader reader = new StreamReader(sourceFile);
StringBuilder fileContents = new StringBuilder();
// Check to see if the end of the file
// has been reached.
while (reader.Peek() != -1)
{
// Read the next character.
fileContents.Append((char)reader.Read());
}
// Store the file contents in a new string variable.
string data = fileContents.ToString();
// Always close the underlying streams release any file handles.
reader.Close();
sourceFile.Close();
StreamWriter Example
string destinationFilePath =
@"C:\\fourthcoffee\\applicationdata\\settings.txt ";
string data = "Hello, this will be written in plain text";
// Create a FileStream object so that you can interact with the file
// system.
FileStream destFile = new FileStream(
destinationFilePath, // Pass in the destination path.
FileMode.Create, // Always create new file.
FileAccess.Write); // Only perform writing.
// Create a new StreamWriter object.
StreamWriter writer = new StreamWriter(destFile);
// Write the string to the file.
writer.WriteLine(data);
// Always close the underlying streams to flush the data to the file
// and release any file handles.
writer.Close();
destFile.Close();
Programming in
i Visual C# 6-43
3
D
Demonstr
ration: Ge
enerating the Grade
es Report Lab
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
6-44 Readingg and Writing Local Data
Lab: G
Generatting the
e Grade
es Repo
ort
Sccenario
Yo
ou have been asked to upgrade the Grad des Prototype application to o enable userrs to save a stuudents
gra
ades as an XMML file on the local disk. The
e user should be able to cliick a new button on the
Stu
udentProfile vview that asks the user wheere they wouldd like to save the file, displaays a preview of the data
to the user, and asks the userr to confirm th
hat they wish to save the file to disk. If th
hey do, the ap
pplication
sho
ould save the grade data in n XML formatt in the locatio
on that the usser specified.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
Password: Pa$$w0rd
P
Programming in Visual C# 6-45
You will use the SaveFileDialog object to ask the user for the file name and location where they want to
save the file. They will only be able to save the file in XML format, so you will need to limit the file types
displayed in the dialog box. You will extract the grade data from the application data source and store it
in a list of Grade objects.
You will then write the FormatAsXMLStream method. This method will use an XmlWriter object to
create an XML document and populate it with grade information from the list of Grade objects.
Finally, you will debug the application and view the data held in the memory stream.
X Task 1: Prompt the user for a filename and retrieve the grade data
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. Start the 20483A-SEA-DEV11-06 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio and from the E:\Labfiles\Starter\Exercise 1 folder, open the
GradesPrototype.sln solution.
4. In the Views folder, open the StudentProfile.xaml user interface, and note that it has been updated
to include a Save Report button that users will click to generate and save the Grades Report.
6. Save the return value from the dialog box in a nullable Boolean variable.
7. Check if the return value from the SaveFileDialog contains data. If it does, do the following:
a. Get the grades for the currently selected student and store them in a generic list.
b. Call the FormatAsXMLStream method, passing the list of grades to it, and store the returned
data in a MemoryStream object.
2. Add code to save the XML document to a MemoryStream object by using an XmlWriter object.
3. Add code to create the root node of the XML document in the following format:
4. Add code to enumerate the grades for the student and add them as child elements of the root node,
using the following format:
6-46 Reading and Writing Local Data
5. Add code to finish the XML document with the appropriate end elements.
6. Add code to flush the XmlWriter object and then close it to ensure that all the data is written to the
MemoryStream object.
7. Add code to reset the MemoryStream object so that it can be read from the start, and then return it
to the calling method.
8. Delete the line of code that throws a NotImplementedException exception.
2. In the SaveReport_Click method, add a breakpoint to the closing brace of the if block.
3. Debug the application.
5. View Kevin Lius report, and then click Save Report to generate the XML document.
6. Add code to save the file in the default location.
Note: You will write the code to actually save the report to disk in Exercise 3 of this lab.
7. When you enter Break Mode, use the Immediate Window to view the contents of the
MemoryStream object by using the following code:
?(new StreamReader(ms)).ReadToEnd()
Results: After completing this exercise, users will be able to specify the location for the Grades Report file.
Programming in Visual C# 6-47
First, you will add code to the SaveReport_Click method to display the XML document to the user in a
message box.
To display the document, you need to build a string representation of the XML document that is stored in
the MemoryStream object.
Finally, you will verify that your code functions as expected by running the application and previewing the
contents of a report.
2. In StudentProfile.xaml.cs, in the SaveReport_Click method, add code to the end of the if block
that calls the FormatXMLData method, passing the MemoryStream object that you created in the
previous task, and storing the return value in a string variable.
3. Add code to preview the string version of the report data in a message box with a caption of Preview
Report, an OK button, and an information image.
3. Add code to read the XML data one node at a time, construct a string representation of the node,
and append it to the StringBuilder. The possible nodes that can be encountered are
XmlDeclaration, Element, and EndElement. Each element may have one or more attributes.
4. Add code to reset the MemoryStream object and return the string containing the formatted data to
the calling method.
5. Delete the line of code that throws a NotImplementedException exception.
4. View Kevin Lius report, and then click Save Report to generate the XML document.
Note: You will write the code to actually save the report to disk in the next exercise of this
lab.
6. Review the XML data displayed in the message box and close the application.
Results: After completing this exercise, users will be able to preview a report before saving it.
Programming in Visual C# 6-49
You will begin by modifying the existing preview dialog box to ask the user if they wish to save the file. If
they wish to save the file, you will use a FileStream object to copy the data from the MemoryStream to a
physical file.
Then you will run the application, generate and save a report, and then verify that the report has been
saved in the correct location in the correct format.
4. If the user clicks Yes to save the report, open the file that the user specified and create a FileStream
object to write data to this file.
5. Write the data from the MemoryStream object to the file.
X Task 2: Run the application and verify that the XML document is saved correctly
1. Build the solution and resolve any compilation errors.
4. View Kevin Lius report card and then click Save Report to generate the XML document.
5. Specify to save the file in the Documents folder by using the default name.
6. Review the XML data displayed in the message box, and then confirm that you want to save the file.
8. Open the saved report in Internet Explorer and verify that it contains the expected grade data.
9. In Visual Studio, close the solution.
Results: After completing this exercise, users will be able to save student reports to the local hard disk in
XML format.
6-50 Readingg and Writing Local Data
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou have learrned how to w work with the file system byy using a nummber of classess in the
Sysstem.IO nameespace, and ho ow to serialize
e application data to differrent formats.
Question: You Y are a devveloper workin ng on the Fou urth Coffee WWindows Presentation
Foundation n (WPF) client application. Y
You have been n asked to sto
ore some settiings in a plain
n
text file in tthe users tem
mporary folderr on the file syystem. Briefly explain which
h classes and
methods yo ou could use tto achieve this.
Question: YouY are a devveloper workin ng for Fourth Coffee. A bug g has been raised and you
have been asked
a to invesstigate. To help reproduce the error, you u have decide ed to add somme
logic to perrsist the state of the applicaation to disk, w
when the app plication encounters the
error. All the types in thee application aare serializable, and it woulld be advantaageous if the
persisted sttate was humaan readable. What
W approacch will you takke?
Test Your Know
wledge
Q
Question
YYou are a deve eloper workinng for Fourthh Coffee. You have been assked to write some
ccode to proceess a 100 GB vvideo file. You
ur code needs to transfer tthe file from one
loocation on diisk, to anothe
er location onn disk, withou
ut reading thee entire file in
nto
mmemory. Whicch classes wo ould you use to
t read and w write the file?
S
Select the corrrect answer.
The M
MemoryStream
m, BinaryReade
er and BinaryW
Writer classess.
Question
Module 7
Accessing a Database
Contents:
Module Overview 7-2
Modu
ule Ove
erview
Ma ons require acccess to data tthat is stored in a database. Microsoft Visual Studio 2012
any applicatio
and the Microsooft .NET Framework provide tools and fu unctionality th
hat you can usse to easily acccess, query,
and update dataa.
In this module, yyou will learn how to creatte and use enttity data models (EDMs) an
nd how to que
ery many
typ
pes of data byy using Langu uage-Integrateed Query (LIN
NQ).
Ob
bjectives
Aftter completing this module
e, you will be able to:
Create, use,, and customize an EDM.
Lesson 1
Creatting an
nd Using
g Entity
y Data Modelss
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Use the A
ADO.NET Entitty Data Mode
el Tools.
Customizze generated cclasses.
Read and
d modify data by using the Entity Framew
work.
7-4 Accessingg a Database
In
ntroductio
on to the A
ADO.NET Entity Fraamework
Hisstorically whe
en you write code to accesss data that is sstored in a dattabase, you have to undersstand the
strructure of the data in the database and h how it all interrelates. Often
n it is stored in a normalize
ed fashion,
whhere tables doo not logicallyy map to the real-life
r objectts that they re
epresent. The ADO.NET Enttity
Fraamework enables you to de evelop applicaations that target a concep ptual model in nstead of the normalized
database structu ure in the storrage layer.
Update appplications to ta
arget a differe
ent storage m
model without rewriting or rredistributing all of your
data access code.
Additiona al Reading: FFor more inforrmation about the ADO.NEET Entity Frammework, see th
he
AD
DO.NET Entityy Framework p page at http:///go.microsoftt.com/fwlink/??LinkID=2678
806.
Programming with Visual C# 7-5
7-6 Accessingg a Database
Ussing the A
ADO.NET Entity Datta Model Tools
Vissual Studio 20
012 provides tthe Entity Datta Model Toolls that you cann use to creatte and update
e EDMs in
your applicationns. It supportss both database-first design
n and code-firrst design:
Database-fifirst design. In database-firstt design, you design and crreate your database before e you
generate yo our model. Th his is common nly used when you are deve eloping appliccations againsst an
existing datta source; how wever, this can
n limit the flexxibility of the application in
n the long term
m.
Code-first d
design. In code
e-first design, you design the entities forr your applicaation and thenn create the
database sttructure arounnd these entities. Developers prefer this method because it enabless you to
design yourr application around
a the bu
usiness functio
onality that yoou require. Ho owever, in reaality, you
often have to work with an existing daata source.
W
Wizard Descripttion
E
Entity Data M
Model Wizard Enabless you to generate a new co
onceptual mod del from an exxisting data
source by using the d
database-firstt design meth
hod.
U
Update Mode
el Wizard Enabless you to update an existing
g conceptual m model with ch
hanges that
are madde to the dataa source on which
w it is base
ed.
G
Generate Dataabase Wizard Enabless you to generate a database from a connceptual model that you
have de esigned in the
e Entity Data M
Model Design
ner by using th
he code-
first dessign method.
Wh hen you creatte a model byy using the Entity Data Mod del Wizard, the model openns in the Desig
gner pane,
dissplaying the e
entities that th
he wizard has generated an nd the relation en them. You can use
nships betwee
thiis pane to add
d, modify, and d delete entities and relatio
onships.
Additional Reading: For more information about the Entity Data Model Tools, see the
ADO.NET Entity Data Model Tools page at http://go.microsoft.com/fwlink/?LinkID=267807.
7-8 Accessingg a Database
Demonstration: Crea
ating an E
Entity Data Model
In this demonstration, you wiill use the Entity Data Wizard to generatte an EDM forr an existing d
database.
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. 0483A-SEA-D
Start the 20 DEV11-07 virttual machine.
3. Log on to W
Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
7. In the Open
n File dialog b
box, browse to
o the E:\Demo ocode\Databaase folder, clicck
AttachFourtthCoffeeDatabaseScript.sqll, and then click Open.
8. On the SQL
L menu, pointt to Transact--SQL Editor, aand then clickk Execute.
9. In the Conn
nect to Serve
er dialog box, in the Serverr name box, type (localdb))\v11.0, and tthen click
Connect.
he query time
Note: If th Connect to Server dialog box, click OK,, and then in
es out, in the C
e Connect to
the g box, click Connect.
o Server dialog
10
0. When the query
q has com
mpleted, on th
he File menu, click Close.
11. On the File menu, point to New, and then click Pro
oject.
w Project dialo
12. In the New nd Templatess, click Visual C#, and then in the Template list,
og box, expan
click Conso
ole Applicatio
on.
Programming with Visual C# 7-9
13. In the Name box, type FourthCoffee.Employees, in the Location box, type
E:\Democode\Demo1\Starter, and then click OK.
14. In Solution Explorer, right-click FourthCoffee.Employees, point to Add, and then click New Item.
15. In the Add New Item FourthCoffee.Employees dialog box, click ADO.NET Entity Data Model, in the
Name box, type FourthCoffeeEmployeesModel, and then click Add.
16. In the Entity Data Model Wizard, on the Choose Model Contents page, click Generate from
database, and then click Next.
17. On the Choose Your Data Connection page, click New Connection.
18. In the Choose Data Source dialog box, in the Data source list, click Microsoft SQL Server, and then
click Continue.
19. In the Connection Properties dialog box, in the Server name box, type (localdb)\v11.0, in the Select or
enter a database name list, click FourthCoffee, and then click OK.
20. In the Entity Data Model Wizard, on the Choose Your Data Connection page, click Next.
21. On the Choose Your Database Objects and Settings page, expand Tables, expand dbo, select
Branches, Employees, and JobTitles, and then click Finish.
22. In the Security Warning dialog box, select Do not show this message again, and then click OK.
24. Review the three entities that have been generated and the associations between them.
25. Right-click the designer surface, and then click Mapping Details.
27. In the Mapping Details pane, review the mappings between the entity and the data source.
29. In the code editor, review the code in the FourthCoffeeEntities partial class.
32. Leave the solution open so that you can refer to it in the following topics.
7-10 Accessinng a Database
Cu
ustomizin
ng Generatted Classe
es
Whhen you use tthe Entity Dataa Model Wizaard to create a model, it automatically ge enerates classses that
expose the entitties in the mo odel to your application cod
de. These classses contain properties thatt provide
acccess to the prroperties in the entities.
ode example shows an Employee class tthat the Entityy Data Model Wizard gene
The following co erated.
Wizard-Genera
ated Classes
n
namespace Fou
urthCoffee.E
Employees
{
using Sys
stem;
using Sys
stem.Collect
tions.Generic;
public pa
artial class
s Employee
{
publi
ic int Emplo
oyeeID { get
t; set; }
publi
ic string Fi
irstName { g
get; set; }
publi
ic string La
astName { ge
et; set; }
publi
ic Nullable<
<System.Date
eTime> DateOf
fBirth { get
t; set; }
publi
ic Nullable<
<int> Branch
h { get; set; }
publi
ic Nullable<
<int> JobTit
tle { get; se
et; }
publi
ic virtual B
Branch Branc
ch1 {get; set
t; }
publi
ic virtual J
JobTitle Job
bTitle1 {get; set; }
}
}
Yo
ou may find th hat you want to
t add custom m business log gic to the entiity classes; howwever, if at an
ny time in
thee future you rrun the Updatte Model Wiza ard, the classe
es will be regeenerated and your code will be
ovverwritten. However, the geenerated classes are defined d as partial claasses; thereforre, you can exxtend them
to add custom ffunctionality tto the classes.
The following co
ode example shows how yo
ou can add bu
usiness logic tto a generated
d class by usin
ng a partial
cla
ass.
Ad
dding Busine
ess Logic in a Partial Classs
p
public partia
al class Emp
ployee
Programming with Visual C# 7-11
{
public int GetAge()
{
DateTime DOB = (DateTime)_DateOfBirth;
TimeSpan difference = DateTime.Now.Subtract(DOB);
int ageInYears = (int)(difference.Days / 365.25);
return ageInYears;
}
}
Additional Reading: For more information about partial classes, see Partial Classes and
Methods (C# Programming Guide) at http://go.microsoft.com/fwlink/?LinkID=267808.
7-12 Accessinng a Database
Re
eading an
nd Modify
ying Data by Using tthe Entity
y Framewo
ork
The automatically generated code files forr a model also o contains a partial class thaat inherits from the
Sy
ystem.Data.En ntity.DbConttext class. The e DbContext class provides facilities for querying and d working
efault constructor which iniitializes the class by using tthe
witth entity data as objects. It contains a de
connection strinng that the wizard generate es in the application configguration file. T
This defines th
he data
connection and model definition to use. The DbContex xt class also co
ontains a DbS Set property tthat
exposes a DbSe et(TEntity) claass for each entity in your m
model. The Db bSet(TEntity)) class represe ents a
typ
ped entity set that you can use to read, create,
c updatee, and delete data.
The following co
ode example shows the claass for the Fou
urthCoffeeEnttities model.
Fo
ourthCoffeeEntities Class
p
public partia
al class Fou
urthCoffeeEn
ntities : DbC
Context
{
public Fo
ourthCoffeeE
Entities() : base("name=
=FourthCoffe
eeEntities")
{
}
public Db
bSet<Branch>
> Branches { get; set; }
public Db
bSet<Employe
ee> Employee
es { get; set
t; }
public Db
bSet<JobTitl
le> JobTitle
es { get; set
t; }
}
To
o use the typed d entity set, yyou create an instance of th
he DbContextt class and the
en access the properties
byy using the staandard dot no otation.
The following co
ode example shows how to
o read and up
pdate data by using the Db
bSet(TEntity) class.
eading Data
Re
F
FourthCoffeeE
Entities DBC
Context = ne
ew FourthCoff
feeEntities(
();
/
// Print a li
ist of emplo
oyees.
f
foreach (FourthCoffee.Em
mployees.Emp
ployee emp in
n DBContext.
.Employees)
{
Console.W
WriteLine("{
{0} {1}", em
mp.FirstName, emp.LastNa
ame);
}
Programming with Visual C# 7-13
The DbSet(TEntity) class implements the IEnumerable interface which provides a number of extension
methods that enable you to easily locate specific data in the source. For example, the First extension
method locates the first match for the specified condition, such as a last name of Prescott.
The following code example shows how to use the First extension method to locate an employee and
then how to update the data by using standard dot notation.
Additional Reading: For more information about the DbSet(Entity) class, see the
DbSet(Entity) Class page at http://go.microsoft.com/fwlink/?LinkID=267809.
For more information about the Enumerable methods, see the Enumerable Methods page at
http://go.microsoft.com/fwlink/?LinkID=2678010.
After you change the data in the model, you must explicitly apply those changes to the data in the data
source. You can do this by calling the SaveChanges method of the ObjectContext object.
The following code example shows how to use the SaveChanges method.
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. 0483A-SEA-D
Start the 20 DEV11-07 virttual machine.
3. Log on to W
Windows as Student with
h the passworrd Pa$$w0rd..
Lesson 2
Query
ying Da
ata by U
Using LINQ
As an alternative
e to using thee Entity Frame
ework for queerying data, yo
ou can use LIN NQ. This also supports
s
compile-time syyntax-checking and type-ch ense in Visual Studio.
hecking and aalso uses Micrrosoft IntelliSe
LIN
NQ defines a rrange of standdard query opperators that enable you too retrieve exacctly the data tthat you
req
quire in a declarative way.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
Query data.
onymous types.
Query data by using ano
Force queryy execution.
Programming witth Visual C# 7-17
7
Q
Querying Data
f
from <variab
ble names> in <data sourcee>
s
select <variab
ble names>
However, you
H u can customizze this syntax in many wayss to retrieve e
exactly the datta that you re
equire in the
f
format that yo
ou want. The following cod de examples aall use LINQ to
o Entities to query data in aan EDM;
h
however, the syntax of the query itself d
does not changge if you use a different typ
pe of data souurce.
S
Selecting D
Data
The following code example shows how to use a simp
T ple select clau
use to return all
a of the dataa in a single
e
entity.
U
Using a selecct Clause
IQueryable<
<Employee> emps
e = from e in DBConte
ext.Employee
es
select e;
F
Filtering Da
ata by Row
w
The following code example shows how to use the where keyword
T d to filter the returned dataa by row to
c
contain employees witth a last name
only e e of Prescott.
U
Using a wherre Clause
string _Las
stName = "Pr
rescott";
IQueryable<
<Employee> emps
e = from e in DBConte
ext.Employee
es
whe
ere e.LastName == _LastN
Name
select e;
7-18 Accessing a Database
D
Demonstr
ration: Qu
uerying D
Data
I this demon
In nstration, you will use LINQ
Q to Entities to
o query data.
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA
A-DEV11-07 vvirtual machine.
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Visual Studio, on the
e File menu, p n, and then click Project/Solution.
point to Open
7
7. In the Oppen Project dialog box, bro
owse to the E::\Democode\\Demo3\Fou
urthCoffee.Em
mployees
folder, click FourthCo
offee.Employ yees.sln, and tthen click Ope
en.
8
8. In Solutio
on Explorer, exxpand Fourth hen double-click Program.cs.
hCoffee.Emplloyees, and th
9
9. Review th
he LINQ code in each of the
e methods.
1 In the con
12. nsole window
w, review the o
output of the QueryingDatta method, an
nd then press Enter.
b. FilterringDataByColumn
1 Press Ente
14. er to close the
e application.
1 In Visual Studio, on the
15. e File menu, cclick Close So
olution.
7-20 Accessing a Database
Programming witth Visual C# 7-21
1
Q
Querying Data by Using
U Ano
onymous T
Types
F
Filtering Da
ata by Colu
umn
The following code example shows how to use the va
T ar data type and the new keyword
k in the
e select
c
clause to filterr the returned
d data by colu
umn.
U
Using an Ano
onymous Typ
pe to Return a Subset of C
Columns
var names = from e in DBContext.Employees
select n
new { e.Firs
stName, e.LastName };
A
Anonymous tyypes enable you
y to perform
m more comp
plex queries in
n LINQ.
G
Grouping D
Data
The following code example shows how to use a grou
T up clause to g
group the retu
urned employyees by their
j title ID.
job
U
Using a grou
up Clause
var emps = from e in DBContext.Em
D ployees
gro
oup e by e.JobTitle into
o eGroup
select new { Job = eGroup.
.Key, Names = eGroup };
A
Aggregatin
ng Data
The following code example shows how to use a grou
T up clause with
h an aggregatte function to
o count the
n
number of em
mployees with
h each job title
e.
7-22 Accessing a Database
Navigating Data
The following code example shows how to use navigation properties to retrieve data from the Employees
entity and the related JobTitles entity.
D
Demonstr
ration: Qu
uerying D
Data by Ussing Anony
ymous Ty
ypes
I this demon
In nstration, you will use LINQ
Q to Entities to
o query data b
by using anonymous types.
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA
A-DEV11-07 vvirtual machine.
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Visual Studio, on the
e File menu, p n, and then click Project/Solution.
point to Open
7
7. In the Oppen Project dialog box, bro
owse to the E::\Democode\\Demo4\Fou
urthCoffee.Em
mployees
folder, click FourthCo
offee.Employ yees.sln, and tthen click Ope
en.
8
8. In Solutio
on Explorer, exxpand Fourth hen double-click Program.cs.
hCoffee.Emplloyees, and th
9
9. Review th
he LINQ code in each of the
e methods.
1 In the con
12. nsole window output of the UsingAnonymousTypes m
w, review the o method, and tthen press
Enter.
1 Repeat sttep 12 for each of the follow
13. wing methods:
a. Grou
upingData
b. AggrregatingData
c. Navig
gatingData
7-24 Accessing a Database
F
Forcing Q
Query Execcution
By default, wh
B hen you define a LINQ query that return ns a sequence of values, it iss not run until you actuallyy
t to use som
try me of the returned data. This feature is known as deferrred query exeecution and ensures that
y can create a query to rretrieve data in a multiple-u
you user scenario and know tha at whenever itt is executed
y will receivve the latest in
you nformation.
I the followin
In ng code exam
mple, the querry is not actuaally executed u
until the start of the foreacch block.
D
Deferred Que
ery Execution
n
IQueryable<
<Employee> emps
e = from e in DBConte
ext.Employee
es
select e;
foreach (va
ar emp in em
mps)
{
Console
e.WriteLine(
("{0} {1}", emp.FirstNam
me, emp.Last
tName);
}
Conversely, w
C when you defin ne a LINQ que ery that return
ns a singleton
n value, for exaample, an Av
verage,
C
Count, or Ma ax function, th
he query is run
n immediatelyy. This is know
wn as immedia ate query execcution and is
n
necessary in the singleton result
r scenario
o because thee query must produce
p a seq
quence to calcculate the
s
singleton resuult.
You can overrride the defau
Y ult deferred qu or queries thatt do not produce a
uery execution behavior fo
s
singleton resu one of the following metho
ult by calling o ods on the query:
ToArray
ToDiction
nary
ToList
I the followin
In ng code exam
mple, the querry is executed immediately after it is defiined.
7-26 Accessing a Database
D
Demonstr
ration: Re
etrieving and
a Modiffying Grad
de Data Laab
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
7-28 Accessinng a Database
Lab: R
Retrieving and
d Modiffying Grade Da
ata
Sccenario
Yo
ou have been asked to upgrade the proto otype applicaation to use an
n existing SQLL Server datab
base. You
beegin by workin
ng with a dataabase that is stored
s on your local machinne and decide ntity Data
e to use the En
Mo odel Wizard to generate an n EDM to acce ess the data. Y
You will need to update thee data access code for
thee Grades sectiion of the app
plication, to display grades that are assig
gned to a stud
dent and to en nable users
to assign new grades. You alsso decide to incorporate vaalidation logicc into the EDMM to ensure th hat
stu
udents cannott be assigned to a full class and that the data that use n they assign new grades
ers enter when
conforms to thee required valuues.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
A-SEA-DEV11-07, MSL-TMG
Virtual Macchine : 20483A G1
User Name: Student
Password: Pa$$w0rd
P
Programming with Visual C# 7-29
Exercise 1: Creating an Entity Data Model from The School of Fine Arts
Database
Scenario
In this exercise, you will use the Entity Data Model Wizard to generate an EDM from the SchoolGradesDB
SQL Server database and then review the model and the code that the wizard generates.
1. Build and generate an EDM by using a table from the SchoolGradesDB database
X Task 1: Build and generate an EDM by using a table from the SchoolGradesDB
database
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. Start the 20483A-SEA-DEV11-07 virtual machine and log on as Student with the password
Pa$$w0rd.
1. Start Visual Studio, and from the E:\Labfiles\Starter\Exercise 1 folder, open the GradesPrototype.sln
solution.
3. Add a new ADO.NET Entity Data Model named GradesModel to the Grades.DataModel project.
4. Generate the model from the SchoolGradesDB database on the (localdb)\v11.0 server and include
the following tables:
Grades
Students
Subjects
Teachers
Users
5. If the Security Warning dialog box appears, click Do not show this message again, and then click
OK.
6. Build the solution.
4. In the GradesModel.Context.tt folder, in GradesModel.Context.cs file, review the code for the
SchoolGradesDBEntities DbContext object.
5. In the GradesModel.tt folder, in the Grade.cs file, review the properties of the Grade entity.
Results: After completing this exercise, the prototype application should include an EDM that you can use
to access The School of Fine Arts database.
7-30 Accessing a Database
Programming with Visual C# 7-31
Finally, you will run the application and verify that the grade display and grade-adding functionality works
as expected.
3. Display the GradeDialog view and use the input to add a new grade
3. In the Views folder, in StudentProfile.xaml.cs, in the Refresh method, add code to the end of the
method to:
a. Iterate through the grades in the session context object and, if they belong to the current
student, add them to a new list of grades.
b. Use data binding to display the list of grades in the studentGrades ItemsControl control.
7. Click Kevin Liu, and then verify that his grades appear in the list.
8. Note that the subject column uses the subject ID rather than the subject name, and then close the
application.
a. Convert the subject ID that is passed into the method into the subject name.
2. Return the subject name or, if there is no subject name matching the subject ID, the string N/A.
X Task 3: Display the GradeDialog view and use the input to add a new grade
1. In StudentProfile.xaml.cs, in the AddGrade_Click method, add code to:
a. Create and display a new instance of the GradeDialog view.
b. If the user clicks OK in the GradeDialog view, retrieve the data they have entered and use it to
create a new Grade object.
7-32 Accessing a Database
c. Save the grade and refresh the display so that the new grade appears.
4. Click Kevin Liu, and verify that the list of grades now displays the subject name, not the subject ID.
5. Add a new grade for Kevin Liu using the following information:
Subject: Geography
Assessment: A+
Comments: Well done!
6. Verify that the new grade is added to the list, and then close the application.
Results: After completing this exercise, users will be see the grades for the current student and add new
grades.
Programming with Visual C# 7-33
First, you will add code to check whether a class is full before enrolling a student and throw an exception
if it is.
Then you will add validation code to check that a user enters a valid date and assessment grade when
adding a grade to a student.
Finally, you will run the application and verify that the data validation works as expected.
4. Modify the class declaration to make it a public partial class named Teacher.
5. Add a private integer constant named MAX_CLASS_SIZE with a value of 8 to the Teacher class.
6. Add an EnrollInClass method that takes a Student object as a parameter and returns void.
Note: You can execute a Count query of the students in a particular class by selecting only
those students with a TeacherUserId property equal to the contents of the UserId variable.
9. If the student who is passed to the method is not already enrolled in a class, set the TeacherID
property of the Student object to the UserID of the current teacher.
10. Otherwise, throw a new ArgumentException exception.
11. In the Views folder, in the AssignStudentDialog.xaml.cs, locate the Student_Click method.
12. Towards the end of the method, before the call to the Refresh method, add code to:
a. Call the EnrollInClass method to assign the student to this teachers class, passing the student as
a parameter.
X Task 2: Add validation logic for the Assessment and AssessmentDate properties
1. Add a new class named customGrade.cs to the Grades.DataModel project.
2. Modify the class declaration to make it a public partial class named Grade.
7-34 Accessing a Database
3. Add a ValidateAssessmentDate method that takes a DateTime object as a parameter and returns a
boolean.
a. If the DateTime object passed to the method is later than the current date, throw a new
ArgumentOutOfRangeException exception.
b. Otherwise, return true.
Use a regular expression to check that the string passed to the method is in the range of A+ to E-
.
6. If the string passed is not in the valid range, throw a new ArgumentOutOfRangeException
exception.
c. Call the ValidateAssessmentGrade method, passing the text in the assessmentGrade text box
control.
4. Attempt to enroll a new student into the class, and then verify that an error message is displayed
explaining that the class is already full.
5. Click Kevin Lui, and then add a new grade for him by using the following information:
Subject: Math
Assessment: F+
6. Verify that an error message is displayed explaining that the assessment date must be on or before
the current date.
Programming with Visual C# 7-35
Date: 8/19/2012
Subject: Math
Assessment: F+
8. Verify that an error message is displayed explaining that the assessment grade must be in the range
A+ to E-.
Subject: Math
Assessment: A+
Comments: Well done!
10. Verify that the new grade is added to the list, and then close the application.
Results: After completing this exercise, the application will raise and handle exceptions when invalid data
is entered.
7-36 Accessinng a Database
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou learned how
h to create and use EDM
Ms and how to
o query many types of data by using
LIN
NQ.
Question: What
W advantaages does LINQ provide ovver traditional ways of queryying data?
Q
Question
S
Select the corrrect answer.
Module 8
Accessing Remote Data
Contents:
Module Overview 8-2
Modu
ule Ove
erview
Sysstems often consist of man ny componentts and services; some might be hosted w within your orgganizations
inffrastructure, w
whereas others could be ho osted in data ccenters anywh
here in the wo
orld. The abilitty for
ap
pplications to b quirement in modern applications.
be able to interact with succh services is a common req
In this module, yyou will learn how to use the request an nd response cllasses in the System.Net
S n
namespace
to directly maniipulate remote data source es. You will alsso learn how tto use Windowws Commun nication
Foundation (WC CF) Data Serviices to exposee and consum me an entity daata model (ED DM) over the web.
w
Ob
bjectives
Aftter completing this module
e, you will be able to:
Access data
a by using WC
CF Data Servicces.
Programmingg in Visual C# 8-3
3
Lesson 1
Acce
essing Data
D Accross the Web
Data is often e
D exposed overr the web throough web servvices or other application p
programming interfaces
(
(APIs). To be aable to consume such data sources in yoour application, you need a way to send and receive
m
messages so tthat you can e
establish a con
nnection and ultimately send and receivve data.
IIn this lesson, you will learnn how to conssume remote data sources such as web sservices and FFile Transfer
P
Protocol will include how to create a request, sup
(FTP)) sites, which w pply credentia
als for authenttication,
p
package data into the requ uest, and proccess data that is returned in
n the response
e.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Provide ccredentials or a security tokken to enable the remote data source to perform auth
hentication.
Send and
d receive data..
8-4 Accessingg Remote Data
Ov
verview o
of Web Co
onnectivity
y in the .N
NET Frame
ework
2. Send a requ uest message to the remote e data source. This message may also include any datta that the
remote data source requuires to satisfyy the request, such as the id
dentifier for th
he sales record
d you want
to retrieve.
Note: Nott all communications have to include bo oth a request aand response message.
Deepending on tthe nature of the applicatio on, it might on
nly be applicaable to send oone message.
For example, if yyour applicatiion wants to let a web service know thatt it has finishe
ed processing a
tassk, you only need to send a request. Thiss is known as a one-way op peration.
W Connecctivity in the
Web e .NET Fram
mework
The .NET Frame ework provide es the System.Net namespace, which co ontains several request and response
cla
asses that enable you to tarrget different data sources. The following
g table describes some of tthese
req
quest and response classes.
C
Class Descriptiion
W
WebRequest An abstrract class that provides the base infrastru
ucture for anyy request to
a Uniformm Resource Id dentifier (URI)).
Programming in Visual C# 8-5
Class Description
WebResponse An abstract class that provides the base infrastructure to process any
response from a URI.
HttpWebRequest A derivative of the WebRequest class that provides functionality for any
HTTP web request.
FtpWebRequest A derivative of the WebRequest class that provides functionality for any
FTP request.
Depending on whether you want to send a request to a web service by using HTTP or you want to
download a file from an FTP site, the .NET Framework provides the necessary classes for you to consume
these remote data sources in your applications.
Additional Reading: For more information about the System.Net namespace, see the
System.Net Namespace page at http://go.microsoft.com/fwlink/?LinkID=267811.
8-6 Accessingg Remote Data
A remote
r data ssource can expose any type e of data. For example, a web service can n expose binaary streams,
scaalar values, orr custom objects. The choicce of the type of data that yyou expose is determined bby the
reqquirements off your applicaation, but how
w you expose it d by the data contracts that you
i is controlled
de
efine in your w web services.
If yyou want to eexpose a custo om object from m a web serviice, you must provide metaadata that desscribes the
strructure of the object. The se erialization prrocess uses th
his metadata to convert you
ur object into a
tra
ansportable fo ormat, such ass XML or JavaScript Object Notation (JSO ON). This metaadata provide
es
insstructions to tthe serializer tthat enable yo ou to control wwhich types aand members are serialized.
Da
ata Contraccts in the .N
NET Framew
work
The .NET Frame
ework provide
es the System.Runtime.Serrialization na amespace, which includes the
Da
ataContract aand DataMemmber attribute butes to define serializable types and
es. You can usse these attrib
meembers.
The following co
ode example shows how to
o define a seriializable type by using the DataContracct and
Da
ataMember attributes.
a
De
efining a Datta Contract
[
[DataContract
t()]
p
public class SalesPerson
n
{
[DataMembe
er()]
public string FirstNa
ame { get; s
set; }
[DataMembe
er()]
public string Surname
e { get; set
t; }
[DataMembe
er()]
public string Area { get; set; }
[DataMembe
er()]
public string EmailAd
ddress { get
t; set; }
}
Additiona al Reading: FFor more inforrmation about the DataContract and DataMember
atttributes, see th
he DataContrractAttribute C
Class page at
htttp://go.microssoft.com/fwlinnk/?LinkID=26 67812.
Programming in Visual C# 8-7
8-8 Accessingg Remote Data
Th
he HttpWeb
bRequest a
and HttpWe
ebResponse
e Classes
The following stteps describe how to send an HTTP requ
uest to a web service and process the ressponse by
usiing the HttpW
WebRequest and HttpWe ebResponse cclasses:
1. Get a URI to
o the web servvice to which you want to send a requesst. The followiing code exammple shows
an HTTP UR RI that addressses the GetSa
alesPerson m
method in the Fourth Coffee e Sales Service
e.
2. Create a req
quest object tto configure the request an
nd access the response. The
e following co
ode
example shows how to create an Http pWebRequesst object.
var reque
est = WebReq
quest.Create(uri) as Htt
tpWebRequest
t;
Note: Reg
gardless of the
e type of requ
uest object yo
ou require, you
u always use tthe static
Create method that the Web bRequest basse class exposes and then ccast to the typ
pe of request
you require.
3. ponse from th
Get the resp he request obj
bject. The follo
owing code exxample showss how to get the
response fro
om an HttpWWebRequest object.
o
var respo
onse = reque
est.GetResponse() as Htt
tpWebRespons
se;
Note: Sim
milar to creatin
ng a request object,
o you cre
eate a response object by invoking the
Ge
etResponse m method on the e WebRequest object, and d you then casst to the type of response
you require.
Programming in Visual C# 8-9
4. Access and process the response by using the various members that the WebResponse object
provides. The following code example shows how to use and view the status of the response by using
the StatusCode property.
If the remote data source uses a different protocol, such as FTP, you can apply the same pattern but use
the FtpWebRequest and FtpWebResponse classes instead.
Similarly, if you try to access a secure web service with the wrong credentials or security token, the
GetResponse method call will throw a WebException exception with the following message:
Au
uthenticatting a We
eb Requesst
Re
emote data soources are ofte en protected to
t prevent unauthorized ussers from usin ng the service and
gaining access tto data. Expossing an unprootected data soource over the web can leaad to unauthoorized users
sennding requestts and increassing the load on
o the data so ource. There aare many wayys in which you can
seccure remote d
data sources. One
O approach h is to authenticate each usser who attem
mpts to conneect to the
rem
mote data sou urce.
Ty
ype of Auth
hentication
The following taable describess some of the common authentication te
echniques thaat you can use
e to secure
rem
mote data sou urces.
A
Authentication mechanism
m De
escription
B
Basic En
nables users too authenticatee by using a u
user name and d password.
Baasic authenticaation does no
ot encrypt the credentials w
while in
traansit, which means
m that unaauthorized ussers may access the
creedentials.
D
Digest En
nables users too authenticatee by using a u
user name and d password,
bu
ut unlike basicc authenticatio
on, the credentials are encrypted.
W
Windows En
nables clients to authenticate by using thheir Windows domain
creedentials. Win
ndows authen ntication uses either hashing or a
Keerberos token to securely authenticate users. Window ws
au
uthentication is typically use e a single sign-on (SSO)
ed to provide
exxperience in o
organizations.
C
Certificate En
nables only clients that havee the correct certificate installed to
au
uthenticate wiith the service
e.
The nature of th
he service andd where it is hosted are like
ely to influence an organiza ations choice of
authentication mmechanism. For example, a service that is i exposed ovver an organizzations intranet might
use
e Windows au uthentication so that users can authenticcate by using their Active D Directory Do omain
Services (AD DSS) credentials. Using Window ws authenticaation in this sccenario will prrovide the use
ers with an
SSO experience and not requ uire them to reemember cred dentials for eaach service thhey consume.
Programming in Visual C# 8-11
The .NET Framework provides a number of classes that you can use to authenticate with a secure remote
data source.
The NetworkCredential class implements the ICredentials interface and enables you to encapsulate
a user name and password. The following code example shows how to instantiate a
NetworkCredential object and pass values for the user name and password to the class constructor.
The CredentialCache class provides a number of members that enable you to get credentials in the
form of an ICredentials object. These members include the DefaultCredentials property, which
returns an ICredentials object containing the credentials that the user is currently logged on with.
The following code example shows how to use the DefaultCredentials property to get the current
users credentials.
Authenticating users by using basic or Windows authentication is common, but it does require users to
remember and provide credentials. Alternatively, you may choose to authenticate clients by using an X509
certificate.
Additional Reading: For more information about the NetworkCredential class, see the
NetworkCredential Class page at http://go.microsoft.com/fwlink/?LinkID=267813.
The following code example shows how you can create an HttpWebRequest object and add an X509
certificate to the request object by using the ClientCertificates property.
When the remote data source receives the request, it must extract and process the X509 certificate. If the
X509 certificate is invalid, the remote data source can return a suitable response, such as a "The remote
server returned an error: 401 unauthorized" message.
8-12 Accessing Remote Data
Note: The GetCertificate method of the web service that is shown in the previous example
returns an X509Certficate2 object. This type provides programmatic access to the properties of
the X509 certificate.
Programming in
i Visual C# 8-13
3
S
Sending aand Receiv
ving Data
Method. This propertyy enables you to set the typpe of method that the Web bRequest objject will use
to send th
he request. Fo
or example, if you are uploaading a file byy using the FttpWebReque est class, you
use the STOR method..
ContentL
Length. This p
property enab
bles you to sett the number of bytes that the request w
will send.
The WebResp
T ponse class provides the GetResponseS
Stream metho
od, which enaables you to acccess and
s
stream data frrom the respo
onse.
S
Sending Da
ata to a Rem
mote Data Source
Whether you are sending d
W data to a web service or up
ploading a file to an FTP site
e, the processs for creating
t request re
the emains the sam
me:
1
1. Get the U
URI to the rem
mote data sourrce and the daata you want to send.
2
2. Create the request object.
3
3. Configure e the request object, which
h includes settting the reque
est method an
nd the length of the data
that the rrequest will se
end.
4
4. Stream th
he data to the
e request obje
ect.
8-14 Accessing Remote Data
The following code example shows how to use a POST operation to send a JSON string to a web service
by using the HttpWebRequest class.
The following code example shows how to upload a file to an FTP site by using the FtpWebRequest class.
When you have acquired the response stream, you must then verify that the data is in the correct format.
For example, if the response that is returned is in the JSON format, you can use the
DataContractJsonSerializer class to serialize the raw JSON data into an object that you can consume in
your code. Alternatively, if the data is in the XML format, you can use the SoapFormatter class to
deserialize the data or Language-Integrated Query (LINQ) to XML to manually parse the XML.
Additional Reading: For more information about LINQ to XML, see the LINQ to XML page
at http://go.microsoft.com/fwlink/?LinkID=267814.
Programming in Visual C# 8-15
8-16 Accessinng Remote Data
Demonstration: Con
nsuming a Web Serv
vice
De
emonstration Steps
1. Start the 20
0483A-SEA-DEEV11-08 virtual machine.
2. Log on to W
Windows 8 as Student with
h the password Pa$$w0rd.
8. In the code
e editor, review
w the signaturre of the GetS
SalesPerson operation,
o hich accepts an email
wh
address in tthe form of a JSON string and
a returns a SalesPerson object.
12. In the Task List window, in the Categories list, click Comments.
13. Double-click the TODO: 01: Bring the System.Net namespace into scope. task.
14. In the code editor, click in the blank line below the comment, and then type the following code:
using System.Net;
15. In the Task List window, double-click the TODO: 02: Declare a global object to encapsulate an HTTP
request. task.
16. In the code editor, click in the blank line below the comment, and then type the following code:
HttpWebRequest _request;
17. In the Task List window, double-click the TODO: 03: Instantiate the _request object. task.
18. In the code editor, click in the blank line below the comment, and then type the following code:
this._request = WebRequest.Create(
this._serviceUri.AbsoluteUri) as
HttpWebRequest;
19. In the Task List window, double-click the TODO: 04: Configure the request to send JSON data. task.
20. In the code editor, click in the blank line below the comment, and then type the following code:
this._request.Method = "POST";
this._request.ContentType = "application/json";
this._request.ContentLength = rawData.Length;
21. In the Task List window, double-click the TODO: 05: Write data to the request stream. task.
22. In the code editor, click in the blank line below the comment, and then type the following code:
23. In the Task List window, double-click the TODO: 06: Create an HttpWebResponse object. task.
24. In the code editor, click in the blank line below the comment, and then type the following code:
25. In the Task List window, double-click the TODO: 07: Check to see if the response contains any data.
task.
26. In the code editor, click in the blank line below the comment, and then type the following code:
if (response.ContentLength == 0)
return null;
27. In the Task List window, double-click the TODO: 08: Read and process the response data. task.
28. In the code editor, click in the blank line below the comment, and then type the following code:
30. In Solution Explorer, right-click Fourth Coffee Contact Finder, and then click Set as StartUp
Project.
32. In the Fourth Coffee Contract Finder application, in the Search box, type jesper@fourthcoffee.com,
and then click GO.
33. In the Search Successful dialog box, click OK.
34. Verify that the details for Jesper Herp are displayed.
Lesson 2
Acce
essing Data
D in the Clo
oud
n how to creatte a WCF Dataa Service and how to define which entitiies and
IIn this lesson, you will learn
o
operations yo
ou want to exp ow to create a client library and how to cconsume the
pose. You will also learn ho
e
entities operations that you have exxposed.
and o
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Describe the purpose o
of a WCF Data
a Service.
Define a W
WCF Data Serrvice.
W
What Is WC
CF Data Se
ervices?
WC CF Data Servicces enables yo ou to create aand access datta services ovver the web. Yo ou expose your data as
ressources that aapplications caan access by uusing a URI. These resource es are exposed d as sets of en
ntities that
are
e related by associations, thhe same concepts as in an EDM. Howeve er, you can exxpose data froom many
typ
pes of storage e, including daatabases and Common Lan nguage Runtim me (CLR) classses.
WCCF Data Servicces uses URIs to address daata and simplee, well-knownn formats to re
epresent that data, such
as XML and Atoom. This resultts in data bein
ng served as a REST-style re
esource collecction.
REEST has becom me a popular mmodel for imp plementing web services th hat need to acccess data (oth her models,
succh as those baased on the W
WebRequest//WebResponse model desscribed in the previous lesso on, are
mo ore suited to invoking
i remo ote methods). REST describbes a statelesss, hierarchical scheme for reepresenting
ressources and bbusiness objeccts over a netw
work. Resourcces are accesseed through URIs that identify the data
to retrieve. For example,
e Fourth Coffee mig ght choose too make the daata for all of itts sales people
e available
thrrough the folllowing URI:
htttp://FourthCo
offee.com/Sale
esService.svc/SSalesPersons
Sim
milarly, the de
etails of produ
ucts that it sells might be avvailable throu
ugh the follow
wing URI:
htttp://FourthCo
offee.com/Sale
esService.svc/Products
The details for a specific prod
duct could be retrieved by including the product ID in
n the URI:
htttp://FourthCo
offee.com/Sale
esService.svc/Products/25
The REST model performs HT TTP GET queriies to retrieve data, but the
e REST model also supportss insert,
up
pdate, and delete operation
ns by using HT
TTP PUT, POST, and DELETE requests.
Programming in Visual C# 8-21
The REST model enables a web service to extend URIs to support filtering, sorting, and paging of data. For
example, the following URI sends a request that fetches the first 10 sales people only:
http://FourthCoffee.com/SalesService.svc/SalesPersons?top=10
The list of filters and other functionality depends on how the web service is implemented, but features
such as these are available with WCF Data Services. Additionally, WCF Data Services enables you to extend
your web services by writing service operations as methods that perform business logic at the server.
These methods are then accessible as URIs in a similar manner to resources. You can also define
interceptors, which are called when you query, insert, update, or delete data and can validate or modify
the data, enforce security, or reject the change.
Additional Reading: For more information about WCF Data Services, see the WCF Data
Services page at http://go.microsoft.com/fwlink/?LinkID=267815.
8-22 Accessinng Remote Data
Note: WCCF Data Servicces can also exxpose non-relational data, but this requires building
customized classses. WCF Data Services ope erates most naturally with tthe model thaat the ADO.NET
Entity Framework presents.
A WCF
W Data Serrvice is based on the System m.Data.Serviices.DataServ vice generic class.
c This class expects a
typpe parameter that is a colle
ection containning at least one property tthat implemen nts the IQuery yable
ntext class for an entity set that is defined by using the Entity Framework. The
intterface, such aas the DbCon
DaataService typ pe implementts the basic fu
unctionality to
o expose the entities
e in this collection as a series of
REEST resources.
The following co
ode example shows the definition of a W
WCF Data Servvice based on a DbContex
xt class
called FourthCo
offee that is ge
enerated by u O.NET Entity Framework.
using the ADO
Yo
ou can implem ment methodss in a WCF Data Service thaat specify the e entities to exp
pose from the
e underlying
ED
DM and that configure the ssize of datase
ets that the daata service pre
esents. You can also overrid
de methods
tha
at are inherite
ed from the D mize the way in which the service operate
DataService cllass to custom es.
Byy default, WCFF Data Servicees uses a simple addressing scheme that exposes the e entity sets that are
deefined within tthe specified EEDM. When yyou consume a WCF Data SService, you ad ddress these eentity
ressources as an entity set that contains instances of an e entity type. Fo
or example, su
uppose that th he
folllowing URI (sshown in the pprevious topicc) returns all of
o the SalesPe erson entities that were defined in the
ED
DM that was used to construct a WCF Daata Service:
htttp://FourthCo
offee.com/Sale
esService.svc/SSalesPersons
Programming in Visual C# 8-23
The "/SalesPersons" element of the URI points to the SalesPersons entity set, which is the container for
SalesPerson instances.
Additional Reading: For more information about defining a WCF Data Service, see the
Exposing Your Data as a Service (WCF Data Services) page at
http://go.microsoft.com/fwlink/?LinkID=267816.
8-24 Accessinng Remote Data
The following co
ode example shows how to
o allow accesss to all resourcces that the WCF
W Data Servvice
exposes.
Da
ata Service Access to all E
Entities
p
public class FourthCoffe
eeDataServic
ce : DataServ
vice<FourthC
Coffee>
{
public st
tatic void I
InitializeSe
ervice(DataSe
erviceConfig
guration con
nfig)
{
confi
ig.SetEntity
ySetAccessRu
ule("*", Enti
itySetRights
s.All);
}
}
The parameters to the SetEntitySetAccessRule method d are the nam me of a resource and the acccess rights
to grant over thhat resource. Y
You can speciffy a resource explicitly, or yyou can use wildcard
w characters. The *
value that is sho
own in the codde example iss a shorthand way of speciffying all resou urces that the WCF Data
Service publishees. The EntitySetRights.Alll value grantss unrestricted access to thesse resources.
E
Exposing Web Metthods by U
Using WCF Data Services
T (where T represents an entity type in the service). An operation can return a single instance of an
entity. The following code example shows an operation that retrieves a sales person record that has a
specific email address. Notice that you should also annotate an operation that returns a scalar value
with the SingleResult attribute.
A primitive value. The following code example shows an operation that retrieves a count of all of the
sales people and returns the count value as an int.
Additional Reading: For more information about service operations, see the Service
Operations (WCF Data Services) page at http://go.microsoft.com/fwlink/?LinkID=267818.
8-28 Accessinng Remote Data
Re
eferencing
g a WCF D
Data Sourcce
The client library for a WCF D Data Service consists of a class that is derrived from the
e DataService eContext
typ
pe that exposes one or more DataServicceQuery obje ects as properties. The name of this classs is usually
the
e same as the e name of the DbContext o object that is used
u by the EDM on which h the WCF Datta Service is
based. For exam mple, the FourrthCoffeeDattaService WC CF Data Service uses a DbCo ontext objectt called
Fo
ourthCoffeeEntities to con nnect to the underlying EDM, so the nam me of the DataServiceConttext type
tha
at is generateed for the clien
nt library is alsso FourthCofffeeEntities.
The DataServicceContext class performs a similar role to the DbContext class in tthe Entity Fram mework. A
clie
ent applicatioon connects to o the data sou
urce through a DataService eContext objject and fetches the data
forr the entities tthat the data service exposes by using th
he DataServicceQuery prop perties. Each
DaataServiceQu uery property is a generic ccollection obje m one of the underlying
ect that presents data from
entities that proovides the datta for the WCFF Data Servicee.
The client library also providees definitions of the types tthat each DattaServiceQue ery collection contains. A
ent applicatio
clie on can performm LINQ querie es against the
e DataService eQuery collection propertie es, and the
clie
ent library con
nstructs the appropriate HT TTP request to o fetch the co
orresponding data. The WC CF Data
Service fetches tthe matching data and pop pulates the Da ataServiceQu uery collection. The client aapplication
can then iteratee through this collection and retrieve thee data for each h item.
Yo
ou can generate the client library for a W
WCF Data Servvice by using tthe Add Serviice Reference e dialog
bo
ox in Visual Stu
udio or by usiing the WCF DData Service client
c utility, D
DataSvcUtil, fro
om the comm
mand line.
Ad
dding a Serrvice Refere
ence
Yo
ou can use the e Add Service e Reference dialog
d box in a client appliccation. This dialog box enab bles you to
speecify the URL of the WCF D Data Service to
o connect to. The dialog bo ox sends a me etadata queryy to the
speecified URL, and it uses the
e response to generate the appropriate D DataServiceC Context class that
contains the Da ataServiceQuery properties and the classses for each o of the entitiess that the WCFF Data
Service exposes. The returned d metadata is stored in the client projectt as an .edmx file. This is noot the same
as an .edmx file that is generaated by using
g the ADO.NET T Entity Data Model Design ner (it has a different
forrmat), but you he XML editor or any text editor.
u can view this metadata file by using th
Programming in Visual C# 8-29
1. If the data service is not part of the solution and is not already running, start the data service and
note its URI.
2. In Solution Explorer, right-click the client project, and then select Add Service Reference.
5. Click OK.
After you have referenced the WCF Data Service, you can then consume the entities and service
operations that it exposes.
Additional Reading: For more information about creating a service reference by using the
command line, see the WCF Data Service Client Utility (DataSvcUtil.exe) page at
http://go.microsoft.com/fwlink/?LinkID=267819.
8-30 Accessinng Remote Data
Re
etrieving aand Updaating Dataa in a WCFF Data Serrvice
Re
etrieving Data
To
o retrieve dataa from a WCF Data Service by using the client
c library, perform the ffollowing step
ps:
1. Create an in
nstance of thee type that is derived
d from the DataServ viceContext cclass in the client library,
and then coonnect to the WCF Data Se ervice. The con
nstructor for tthis class expe
ects a Uri obje
ect that
contains the
e address of tthe service.
The following co
ode example connects to the FourthCofffeeDataServicce WCF Data SService by using the
Fo
ourthCoffeeEntities type in
n the client libbrary (this is th
he class that is derived from
m DataServicceContext).
The parameter to
t the constru
uctor is the adddress of the sservice. The co ode then queries the SalessPersons
Da
ataServiceQu uery property to fetch all saales people an nd reads the e email address for each reco
ord.
Qu
uerying the FourthCoffee
F eDataService WCF Data Se
ervice
F
FourthCoffeeE
Entities con
ntext = new FourthCoffee
eEntities (n
new Uri
("http://
/FourthCoffe
ee.com/Fourt
thCoffeeDataS
Service.svc"
"));
f
foreach (Sale
esPerson per
rson in cont
text.SalesPersons)
{
var email
l = product.
.EmailAddres
ss;
}
Yo
ou can also mo odify data by invoking any custom servicce operationss that you mayy have expose ed in the
WC CF Data Servicce. You can in
nvoke service operations byy using the Ex xecute metho od of the
DaataServiceContext class. The value that the Execute method returrns is an enum merable collecction. If the
serrvice operatio
on returns a single, scalar vaalue, you shou
uld extract tha
at value from the collection
n by using
ammethod such as First.
Programming in Visual C# 8-31
The following code example shows how to invoke the SalesPersonByArea service operation and iterate
the results.
Modifying Data
After you have retrieved data, you can modify the entities as you would when working with an EDM and
then save your changes back to the WCF Data Service.
The DataServiceContext class provides the following methods that enable you to work with the entities
in your EDM.
AddToXXXX. These methods enable you to add a new entity to the entity collection. The following
code example shows how to use the AddToSalesPersons method to add a new SalesPerson entity.
DeleteObject. This method enables you to remove an existing object from the entity collection. The
following code example shows how to use the DeleteObject method to delete a sales person with
the email address roya@fourthcoffee.com.
UpdateObject. This method enables you to update an existing object in the entity collection. The
following code example shows how to use the UpdateObject method to change the area to which a
sales person belongs.
context.UpdateObject(salesPerson);
context.SaveChanges();
Using the eager loading strategy that the Expand method implements causes the data for the specified
related entities to be retrieved as part of the same request that fetches the primary data for the query.
This approach is useful if you know that you will always need this related data, but it can be wasteful of
bandwidth for the cases where you do not actually use these entities.
The following code example shows how to use the Expand method to fetch the sales associated with each
SalesPerson object.
As an alternative, you can use explicit loading. This strategy sends an additional query to the WCF Data
Service that is requesting the related data for a specific object, but it has the advantage that it does not
waste bandwidth by automatically fetching data that is not used.
You can implement explicit loading by using the LoadProperty method of the DataServiceContext
object. You call the LoadProperty method each time you require data that is related to a particular entity;
you specify the entity and the name of the DataServiceQuery collection property that holds the related
data.
The following code example shows how to use the LoadProperty method to fetch the sales that are
associated with each SalesPerson object.
Additional Reading: For more information about modifying entities, see the How to:
Add, Modify, and Delete Entities (WCF Data Services) page at
http://go.microsoft.com/fwlink/?LinkID=267820.
Programming in
i Visual C# 8-33
3
D
Demonstr
ration: Re
etrieving and
a Modiffying Grad
de Data in
n the Clou
ud Lab
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
8-34 Accessinng Remote Data
Lab: R
Retrieving and
d Modiffying Grade Da
ata in tthe Clou
ud
Sccenario
Cu
urrently, the application retrieves data fro
om a local database. Howe ever, you havee decided to store
s the
data in the cloud and must configure the application
a so
o that it can re
etrieve data across the web
b.
ou must create
Yo e a WCF Data Service for thhe SchoolGrades database
e that will be integrated into
o the
ap
pplication to e
enable access tto the data.
Fin
nally, you have
e been asked to write code
e that displayss student imag
ges by retrievving them from
m across
the
e web.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
CF Data Service.
Create a WC
Password: Pa$$w0rd
P
Programming in Visual C# 8-35
First, you will add a new ASP.NET Web Application project to the solution and configure it for the client
application.
You will then expose the entities in the EDM from a data service in the new project.
Next, you will specify the data context for the data service and configure access rights to the entities that
it exposes.
You will then add an operation to the data service that returns all of the students in a specified class.
Finally, you will test the WCF Data Service to ensure that it functions correctly.
2. Start the 20483A-SEA-DEV11-08 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio, and then open the GradesPrototype.sln solution from the
E:\Labfiles\Starter\Exercise 1 folder.
4. Add a Visual C# ASP.NET Empty Web Application project called Grades.Web to the solution.
d. Add the Grades.Web project to the list of startup projects for the solution.
e. Save all of the files.
2. Add a new WCF Data Service named GradesWebDataService to the Services folder.
3. Add a reference to the Grades.DataModel project in the Grades.Web project.
Note: The data service in the Grades.Web project needs to connect to the same data
source that the data model uses.
X Task 3: Specify the GradesDBEntities data context for the data service
1. In the code in the Grades.WebDataService.svc file, add a using directive to bring the
Grades.DataModel namespace into scope.
Note: The GradesDBEntities class provides the object context for the EDM. The
GradesWebDataService data service will retrieve data by using this object context and expose the
various entities by using REST URIs.
3. In the InitializeService method, set the access rules for each of the following entities to
EntitySetRights.All:
Grades
Teachers
Students
Subjects
Users
2. In this operation, use a LINQ query against the CurrentDataSource object to retrieve and return all
of the students in the class.
3. In the InitializeService method, set the access rule for the StudentsInClass operation to
ServiceOperationRights.AllRead.
3. Verify that Internet Explorer displays an XML description of the entities that the data service exposes.
Results: After completing this exercise, you should have added a WCF Data Service to the application to
provide remote access to the SchoolGrades database.
Programming in Visual C# 8-37
First, you will add a service reference in the GradesPrototype project that references the running WCF
Data Service.
You will then modify the code that accesses the local EDM to use the WCF Data Service instead.
Next, you will modify the code that saves changes back to the database to do so through the data service.
Finally, you will test the application to verify that it runs the same as if the data was being called locally.
1. Add a service reference for the WCF Data Service to the GradesPrototype application
2. Modify the code that accesses the EDM to use the WCF Data Service
3. Modify the code that saves changes back to the database to use the WCF Data Service
4. Build and test the application to verify that the application still functions correctly
X Task 1: Add a service reference for the WCF Data Service to the GradesPrototype
application
1. In Visual Studio, open the GradesPrototype.sln solution from the E:\Labfiles\Starter\Exercise 2 folder.
4. Update the namespace declaration in the Reference.cs file for the service reference to
Grades.DataModel. The Reference.cs file is generated in the Service
References\Grades.DataModel\Reference.datasvcmap folder in Solution Explorer. You need to enable
Solution Explorer to show all files to see this folder.
Note: The Add Service Reference Wizard prepends the namespace that you specify with
the namespace of the project, so the result in this case is GradesPrototype.Grades.DataModel.
The existing code in the GradesPrototype project expects the various entity classes to be located
in the Grades.DataModel namespace. You can either update every reference throughout the
project, or you can change the namespace of the data service; this lab opts for the latter
approach.
There is one drawback with this approach; if you regenerate the data service reference (this will
be necessary if, for example, you modify the WCF data service and add a new entity class), you
will have to edit the Reference.cs file and update the namespace again because any manual
changes you make to this file will be lost.
6. Copy the following code files from the Grades.DataModel project to the GradesPrototype\DataModel
folder:
a. Classes.cs
b. customGrade.cs
c. customTeacher.cs
8-38 Accessing Remote Data
Note: The Classes.cs, Grade.cs, and Teacher.cs files contain custom functionality for the
Grade and Teacher classes that you implemented in an earlier lab. WCF Data Services does not
propagate any custom functionality that is defined for a data model, so you must manually copy
these files to the Grades.DataModel project. You will also have to make some small changes to
this code to access data through the WCF Data Service rather than by referencing the entities
themselves. You will do this in the next task.
X Task 2: Modify the code that accesses the EDM to use the WCF Data Service
1. In the Grades.Web project, in the Services folder, in SessionContext.cs, modify the DBContext
declaration to pass a new Uri object pointing to
http://localhost:1650/Services/GradesWebDataService.svc to the SchoolGradesDBEntities
constructor.
Note: The DBContext object provides the object context for accessing the data source.
Previously this object context retrieved data directly from a local EDM. Now the data service
provides this object context, and the constructor requires the URL of the data service.
static SessionContext()
{
DBContext.MergeOption = System.Data.Services.Client.MergeOption.PreserveChanges;
}
This constructor ensures that any changes made by the user are not lost if multiple users try and make
simultaneous changes
4. Modify the code in the foreach loop that populates the list ItemsControl with the details of the
students for the current teacher.
The user and grades data for a student are held in separate entities and they are not fetched
automatically by WCF Data Services (this is to save network resources by not retrieving data
unnecessarily). The code that populates the list of students should retrieve that the related data in the
User and Grades properties for each student by using the LoadProperty method of the data context
(available in SessionContext.DBContext).
5. In LogonPage.xaml.cs, in the Logon_Click method, modify the statement that loads teacher data to
also load the user and student data for that teacher. As an alternative to using the LoadProperty
method of the data context, use the Expand method when the data is fetched by using the LINQ
query.
6. In LogonPage.xaml.cs, in the Logon_Click method, modify the statement that loads student data to
also load the user and grades data.
7. In the GradesPrototype solution, in the customTeacher.cs file, add a using directive to bring the
GradesPrototype.Services namespace into scope.
8. In the EnrollInClass method, modify the from statement to reference the Students collection in the
SessionContext.DBContext object.
9. In the AssignStudentDialog dialog, in the Refresh method, modify the code that finds unassigned
students to reference the SessionContext.DBContext.Students collection rather than
SessionContext.DBContext.Students.Local. This change is necessary because the data model
Programming in Visual C# 8-39
implemented by the data service does not provide the Local property. You should also use the
Expand method to retrieve the User and Grades information for the students.
10. In the StudentProfile view, in the AddGrade_Click method, find the code that uses the Add method
of the Grades collection to add a grade to a student. Modify this code to use the AddToGrades
method of the DBContext class. This change is necessary because the Grades collection
implemented by WCF Data Services does not provide the Add method.
11. In the SaveReport_Click method, modify the LINQ query that retrieves the grades for the report to
also fetch the Subject details. Use the Expand method.
12. In the StudentsPage view, in the NewStudent_Click method, find the code that uses the Add
method of the Students collection to add a new student. Modify this code to use the
AddToStudents method of the DBContext class.
X Task 3: Modify the code that saves changes back to the database to use the WCF
Data Service
1. In the code for the AssignStudentDialog view, in the Student_Click method, add code to specify
that the selected student has been changed before the call to the SessionContext.Save method.
Note: WCF Data Services requires that you explicitly mark an entity as updated, otherwise
any changes will not be saved.
2. In the StudentProfile view, in the Remove_Click method, add code to specify that the current
student has been changed before the call to the SessionContext.Save method.
3. In the Controls folder, in ChangePasswordDialog.xaml.cs, in the ok_Click method, add code to
specify that the current user has been changed before the call to the SessionContext.Save method.
X Task 4: Build and test the application to verify that the application still functions
correctly
1. Build the solution, and then resolve any compilation errors.
2. Log on as vallee with a password of password99.
3. Perform the following tasks to verify that the application still updates the data correctly:
c. Change the password to password88, and then verify that you can log on with the new
password.
d. Log on as grubere with a password of password.
e. Verify that his student profile appears, and then log off.
Results: After completing this exercise, you should have updated the Grades Prototype application to use
the WCF Data Service.
8-40 Accessing Remote Data
Finally, you will run the application to verify that the images appear.
2. Add an Image control to the StudentsPage view and bind it to the ImageName property
3. Add an Image control to the StudentProfile view and bind it to the ImageName property
4. Add an Image control to the AssignStudentDialog control and bind it to the ImageName property
5. Build and test the application, verifying that students photographs appear in the list of students for the
teacher
3. In the ImageNameConverter class, define a string constant named webFolder that contains the
string http://localhost:1650/Images/Portraits/.
5. In the Convert method, add code to check whether the value that is passed to the method contains a
string, and if so, append it to the webFolder string and return the result. If the value passed to the
method is null, return string.Empty. There is no need to add any code to the ConvertBack method.
X Task 2: Add an Image control to the StudentsPage view and bind it to the
ImageName property
1. In the XAML markup for the StudentsPage view, add a reference to the clr-
namespace:GradesPrototype.Views namespace. Assign this to xmlns:local. This is the namespace
that contains the ImageNameConverter class.
X Task 3: Add an Image control to the StudentProfile view and bind it to the
ImageName property
1. In the XAML markup for the StudentProfile view, add an instance of the ImageNameConverter class
as a resource to the view. Use the app namespace (this namespace has already been defined at the
top of the XAML markup).
2. At the top of the StackPanel control, add an Image control. Use the ImageNameConverter to
convert the value in the ImageName property into a URL and display the image retrieved from this
URL. Set the height of the Image control to 150.
X Task 4: Add an Image control to the AssignStudentDialog control and bind it to the
ImageName property
1. In the XAML markup for the AssignStudentDialog control, add a reference to the clr-
namespace:GradesPrototype.Views namespace. Assign this to xmlns:local.
3. At the top of the StackPanel control. As before, use the ImageNameConverter to convert the value
in the ImageName property into a URL and display the image retrieved from this URL. Set the height
of the Image control to 100.
X Task 5: Build and test the application, verifying that students photographs appear in
the list of students for the teacher
1. Build the solution, and then resolve any compilation errors.
2. Log on as vallee with a password of password88.
4. View George Lis profile and verify that his image appears.
6. Enroll George Li in the class, and then verify that the Assign Student dialog box now includes
images, and new student icons in the main application window include images.
7. Close the application.
Results: After completing this exercise, the students list, student profile, and unassigned student dialog
box will display the images of students that were retrieved across the web.
8-42 Accessinng Remote Data
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou have learrned how to u
use the requesst and response classes in the System.Net
namespace to m manipulate rem mote data sou use WCF Data Services to expose and
urces directly and how to u
consume an enttity data model over the we eb.
Q
Question
W
Which of the ffollowing corrrectly describ
bes how to acccess data tha
at is provided
d in an
H
HTTP response?
S
Select the corrrect answer.
Invoke
e the GetResp
ponseStream sstatic method on the HttpW
WebResponse class.
Invoke
e the GetRequ
uestStream insstance metho
od on the Http
pWebResponsse object.
Invoke
e the GetResp
ponseStream instance meth
hod on the HtttpWebRespon
nse object.
Invoke
e the GetResp
ponseStream instance meth
hod on the HtttpWebRequesst object.
Q
Question
W
When you creeate a WCF Da ata Service to
o provide rem
mote access too an EDM, hoow do you
specify which entity sets th
he data servicce should mak
ke available to
t client appliications?
S
Select the corrrect answer.
Do no
othing. All entiity sets in the EDM are auto
omatically ava
ailable to clien
nt
Programming in Visual C# 8-43
Question
applications.
Create a certificate for each client that can connect to the service. Configure the
service to only allow authenticated clients to connect and retrieve data.
Configure the service to enable HTTP GET requests for each entity set.
9-1
Module 9
Designing the User Interface for a Graphical Application
Contents:
Module Overview 9-2
Modu
ule Ove
erview
An
n effective andd easy-to-use user interfacee (UI) is essential for graphical applicatio
ons. In this mo
odule, you
will learn how to
o use Extensibble Application Markup Lan nguage (XAML) and Windo ows Presentatiion
Foundation (WP PF) to create e
engaging UIs.
Ob
bjectives
e, you will be able to:
Aftter completing this module
Bind a XAM
ML control to d
data.
Apply styless to a XAML UI.
U
Programmingg in Visual C# 9-3
3
Lesson 1
Using
g XAML to De
esign a User In
nterface
e
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create co
ontrols and set properties in
n XAML.
In
ntroducing
g XAML
XAAML enables yyou to define UI elements b by using a decclarative, XMLL-based syntaxx. When you u use XAML
in a WPF applicaation, you use e XML elemennts and attribu utes to represent controls aand their propperties. You
can use a varietyy of tools to ccreate XAML ffiles, such as Visual
V Studio, the Microsoftt Expression
suite, and
texxt editors. Wh
hen you build a WPF appliccation, the buiild engine con nverts the decclarative markkup in your
XAAML file into classes
c and ob bjects.
De
efining a Button in XAML
L
<
<Window x:Cla
ass="MyNames
space.MainWindow"
xmlns="h
http://schem
mas.microsoft
t.com/winfx/
/2006/xaml/p
presentation"
xmlns:x=
="http://sch
hemas.microso
oft.com/winf
fx/2006/xaml"
Title="O
Order Your C
Coffee Here" Height="350
0" Width="52
25">
<Grid>
<Button
n Content="G
Get Me a Cof
ffee!" />
</Grid>
<
</Window>
XAAML uses a hie erarchical app proach to define a UI. The m most common n top-level ele
ement in a WP PF XAML
file
e is the Windo ow element. The T Window element can include severral attributes. In the previou us example,
thee Window ele ement identiffies various XM ML namespace es that make built-in contrrols available ffor use. It
deefines a title, w
which is displaayed in the titlle bar of the aapplication, an
nd defines thee initial height and width
of the window.
A Window
W elem
ment can conttain a single cchild element that defines tthe content off the UI. In moost
ap
pplications, a U
UI requires mo ore than a single control, so
o WPF defines container coontrols that yoou can use
to combine other lower-levell controls toge ether and lay them out. The most comm monly used co ontainer
control is the Grrid control, an
nd when you add a new W Window to a WWPF project in n Visual Studio o, the
Window templaate automaticcally adds a G Grid control to
o the Windoww.
The Grid contro ol can containn multiple child controls thaat it lays out in
n a grid style. In the examp ple shown
ab
bove, the Grid d control contaains a single B
Button contro ol. The Grid control definess a default layyout that
consists of a single row and a single colum mn, but you ca an customize tthis layout byy defining add ditional
row
ws and colum mns as attributtes of the Grid
d. This mechanism enables you to define e cells in the G
Grid, and
you can then place controls in specific cells. You can alsso nest a grid control inside e a cell if you need to
pro
ovide finer coontrol over thee layout of certain parts of a window.
Programming in Visual C# 9-5
Additional Reading: For more information about XAML, see the XAML Overview (WPF)
page at http://go.microsoft.com/fwlink/?LinkID=267821.
9-6 Designingg the User Interfacee for a Graphical Appplication
Co
ommon C
Controls
The .NET Frameework providees a comprehe ensive collection of controlss that you cann use to imple
ement a UI.
Yo
ou can find the
e complete se
et in the Toolb window. You can also
box that is avaailable when yyou design a w
de
efine your ownn custom userr controls, as d
described in this lesson. The following taable summarizzes some of
the
e most comm monly used conntrols:
C
Control De
escription
B
Button Displays a button that a userr can click to perform an acction.
C
CheckBox En
nables a user to indicate wh
hether an item
m should be selected
s (checcked) or not
(b
blank).
C
ComboBox Displays a drop
p-down list off items from w
which the userr can make a selection.
s
L
Label Displays a piece
e of static texxt.
L
ListBox Displays a scrollable list of items from which the user can make a selection.
R
RadioButton En
nables the use
er to select fro
om a range off mutually excclusive option
ns.
T
TabControl O
Organizes the controls
c in a U
UI into a set o
of tabbed pages.
T
TextBlock Displays a read
d-only block o
of text.
T
TextBox En
nables the use
er to enter and edit text.
Programmingg in Visual C# 9-7
7
S
Setting Co
ontrol Pro
operties
U
Using Attribu
utes to Set Control Prope
erties
<Button Con
ntent="Get Me
M a Coffee!"
Margin="
"150, 130, 150, 130"
Backgrou
und="Yellow"
Foregrou
und="Blue" />
U
Using Properrty Element S
Syntax to Sett Control Pro
operties
<Button Con
ntent="Get Me
M a Coffee!"
Margin="
"150, 130, 150, 130">
<Button.
.Background>
>
<Line
earGradientB
Brush StartPoint="0.5, 0
0.5" EndPoin
nt="1.5, 1.5" >
<G
GradientStop
p Color="AliceBlue" Offs
set="0" />
<G
GradientStop
p Color="Aqua" Offset="0
0.5" />
</Lin
nearGradient
tBrush>
</Button
n.Background
d>
<Button.
.Foreground>
>
<Soli
idColorBrush
h Color="Black" />
</Button
n.Foreground
d>
9-8 Designing the User Interface for a Graphical Application
</Button>
Many WPF controls include a Content property. The previous examples used an attribute to set the
Content property of a button to a simple text value. However, the content of a control is rarely limited to
text. Instead of specifying the Content property as an attribute, you can add the desired content between
the opening and closing tags of the control. For example, you might want to replace the contents of the
Button element with a picture of a cup of coffee.
The following example shows how to add content to a WPF control:
H
Handling Events
Note: V Visual Studio includes manyy features thatt make it easyy to create handlers for eveents.
FFor example, if you double e-click a Butto
on control at design
d time, V Visual Studio w
will automaticcally
c
create an event handler stu ub method in the code-beh hind file. It alsso automatically binds the Click
C
e
event of the button
b to the event handler method.
2
2. Set the Click attribute of the button
n to the name
e of an event h
handler metho
od. This meth
hod runs
when thee Click event ooccurs.
H
Handling Eve
ents in XAML
L
<Button x:N
Name="btnMak
keCoffee"
Margin="
"150, 130, 150, 130"
Content=
="Make Me a Coffee!"
Click="b
btnMakeCoffee_Click" />
<Label x:Na
ame="lblResu
ult"
Content=""
"
9-10 Designing the User Interface for a Graphical Application
In the code-behind file, you can add logic to the btnMakeCoffee_Click method to define what should
happen when a user clicks the button.
The following example shows how to create an event handler method for a WPF control:
Note: WPF uses the concept of routed events. When an event is raised, WPF will attempt
to run the corresponding event handler for the control that has the focus. If there is no event
handler available, then WPF will examine the parent of the control that has the focus, and if it has
a handler for the event it will run. If the parent has no suitable event handler, WPF examines the
parent of the parent, and so on right up to the top-level window. This process is known as
bubbling, and it enables a container control to implement default event-handling logic for any
events that are not handled by its children.
When a control handles an event, the event is still bubbled to the parent in case the parent needs
to perform any additional processing. An event handler is passed information about the event in
the RoutedEventArgs parameter. An event handler can use the properties in this parameter to
determine the source of the event (the control that had the focus when the event was raised).
The RoutedEventArgs parameter also includes a Boolean property called Handled. An event
handler can set this property to true to indicate that the event has been processed. When the
event bubbles, the value of this property can be used to prevent the event from being handled
by a parent control.
Additional Reading: For more information about how routed events work in WPF, see the
Routed Events Overview page at http://go.microsoft.com/fwlink/?LinkID=267821.
Programming in
i Visual C# 9-11
1
U
Using Lay
yout Contrrols
SSupport for reelative positio nciples of WPF. The idea is that your app
oning is one off the core prin plication
s
should renderr correctly reggardless of how the user po ositions or resizes the appliccation windoww. WPF
i
includes severral layout, or container,
c con
ntrols that enaable you to poosition and sizze your child controls in
d
different wayss. The followin ng table show
ws the most co ommon layout controls:
Control Description
U
Using a Grid Layout
<Grid>
<Grid.RoowDefinition
ns>
<RowD
Definition M
MinHeight="100" MaxHeigh
ht="200" />
<RowD
Definition H
Height="Auto" />
</Grid.RRowDefinitio
ons>
<Grid.CoolumnDefinit
tions>
<Colu
umnDefinitio
on Width="3*" />
9-12 Designing the User Interface for a Graphical Application
In the previous example, notice that you use RowDefinition and ColumnDefinition elements to define
rows and columns respectively. For each row or column, you can specify a minimum and maximum height
or width, or a fixed height or width. You can specify heights and widths in three ways:
As numerical units. For example, Width="200" represents 200 units (where 1 unit equals 1/96th of an
inch).
As Auto. For example, Width="Auto" will set the column to the minimum width required to render
all the child controls in the column.
As a star value. For example, Width="*" will make the column use up any available space after fixed-
width columns and auto-width columns are allocated. If you create two columns with widths of 3*
and 7*, the available space will be divided between the columns in the ratio 3:7.
To put a child control in a particular row or column, you add the Grid.Row and Grid.Column attributes
to the child control element. Note that these properties are defined by the parent Grid element, rather
than the child Label element. Properties such as Grid.Row and Grid.Column are known as attached
propertiesthey are defined by a parent element to be specified by its child elements. Attached
properties enable child elements to tell a parent element how they should be rendered.
D
Demonstr
ration: Ussing Desig
gn View to
o Create a XAML UII
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA
A-DEV11-09 vvirtual machine.
3
3. Log on to a Student with the passwo
o Windows 8 as ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Visual Studio, on the
e File menu, p
point to New,, and then clicck Project.
7
7. In the Ne ew Project dia
alog box, in th
he Templatess list, click Vissual C#, and tthen in the Prroject Type
list, click WPF
W Applica ation.
8
8. In the Na
ame box, type
e DesignView
w.
9
9. In the Loccation text bo
ox, set the loccation to E:\D
Democode, an
nd then click O
OK.
1 In the XA
10. AML pane, in the
t Window e
element, chan
nge the value of the Title aattribute to Orrder Your
Coffee H
Here.
1 Add the ffollowing marrkup between the opening and closing Grid
11. G tags:
<Grid.R
RowDefinitions>
9-14 Designing the User Interface for a Graphical Application
12. Open the Toolbox pane, expand Common WPF Controls, and then double-click Button.
13. On the design surface, drag the button towards the top of the screen until a message displays Press
Tab to place inside row 0. Press Tab, and then release the button.
14. In the XAML pane, in the Button element, change the value of the Content attribute to Make Me a
Coffee!
17. In the Properties window, ensure the button is selected, and then in the Name box, type
btnGetCoffee.
19. On the design surface, drag the label to anywhere in the lower row of the Grid.
20. In the XAML pane, in the Label element, change the value of the Content attribute to an empty
string.
22. In the Properties window, ensure the label is selected, and then in the Name text box, type
lblResult.
24. Notice that Visual Studio automatically creates an event handler method and switches to the code-
behind page.
29. Close the Order Your Coffee Here window, and then close Visual Studio.
Programming in
i Visual C# 9-15
5
C
Creating U
User Conttrols
When you wo
W ork with WPF, you can creatte your own sself-contained d, reusable use er controls in XAML. User
c
controls are soometimes called composite e controls, because they are a composite e of other conntrols. For
e
example, if yo
ou use the sam
me combinatio on of a text box and a buttton multiple times in a UI, iit might be
m
more conveniient to create and use a useer control that consists of tthe text box and the button n.
A
Alternatively, you might creeate a user co
ontrol to enab
ble multiple de evelopers to sshare the samme custom
c
control acrosss multiple asse
emblies.
LLike a regularr XAML windo
ow, user contro onding code-behind file. In
ols consist of a XAML file aand a correspo n
t XAML file, the principal difference is that the top--level elementt is a UserCon
the ntrol elementt rather than
a Window ele ement.
T following example sho
The ows a user con
ntrol that enab
bles people to
o select and o
order beverage
es:
C
Creating a Usser Control in
n XAML
<UserControol x:Class="
"DesignView.CoffeeSelecttor"
xmlns="htttp://schemas.microsoft.
.com/winfx/2
2006/xaml/presentation"
xmlns:x=""http://schemas.microsof
ft.com/winfx
x/2006/xaml"
xmlns:mc=="http://schemas.openxml
lformats.org
g/markup-compatibility/22006"
xmlns:d=""http://schemas.microsof
ft.com/expre
ession/blend/2008"
mc:Ignoraable="d"
d:DesignHHeight="300" d:DesignWid
dth="200">
<Grid>
<Grrid.RowDefinnitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="1*"/>
</GGrid.RowDefinitions>
<SttackPanel Grrid.Row="0">
<Label Conntent="Do you want coffe
ee or tea?"/
/>
<RadioButtton x:Name="radCoffee" C
Content="Cof
ffee" HorizontalAlignmennt="Left"
VerrticalAlignment="Top" Ma
argin="5,5,5
5,5" GroupName="Beveragee"
IsCChecked="True" Checked="
"radCoffee_C
Checked" />
<RadioButtton x:Name="radTea" Cont
tent="Tea" HorizontalAl
H ignment="Lef
ft"
VeerticalAlignment="Top" M
Margin="5,5,5,5" GroupName="Beveragge"
Chhecked="radTea_Checked"/
/>
</SStackPanel>
<SttackPanel Grrid.Row="1">
<Label Conntent="Do you want milk?
?"/>
9-16 Designing the User Interface for a Graphical Application
As the previous example shows, creating the XAML for a user control is very similar to creating the XAML
for a window. In the code-behind file for the user control, you can create event handler methods in the
same way that you would for regular XAML windows. When you edit the code-behind file, you should
also:
Define any required public properties. Creating public properties enables the consumers of your user
control to get or set property values, either in XAML or in code.
Define any required public events. Raising events enables consumers of your user control to respond
in the same way that they would respond to other control events, such as the Click event of a button.
The following example shows the code-behind class for a user control:
In the previous code example, the user control raises an OrderPlaced event when the user clicks the
Place Order button. Applications that include the user control can subscribe to this event and take
appropriate action.
To use your user control in a WPF application, you need to do two things:
1. Add a namespace prefix for your user control namespace and assembly to the Window element. This
should take the following form:
Note: If your application and your user control are in the same assembly, you can omit the
assembly name from the namespace prefix declaration.
2. Add the control to your application in the same way that you would add a built-in control, with the
namespace prefix you defined.
When you have added the user control, you can handle events and get or set property values in the same
way that you would for a built-in control. In the previous example, the OrderPlaced event of the
CoffeeSelector control is wired up to the coffeeSelector1_OrderPlaced method.
The following example shows how to interact with a user control in a code-behind class:
In the previous code example, the coffeeSelector1_OrderPlaced method handles the OrderPlaced event
of the CoffeeSelector control. The method then retrieves the order details from the control and writes
them to a label.
Programming in
i Visual C# 9-19
9
Lesson 2
Binding Con
ntrols tto Data
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
In
ntroductio
on to Dataa Binding
g source. This is the source of your data, and is typically a property of a custom .NET object.
The binding
For example, you might bind a contro ol to the Coun
ntryOfOrigin property of a Coffee objecct.
The Path property of the Binding object is set to Bean. This indicates that you want to bind to the
Bean property of the coffee1 object.
As a result of this expression, the TextBlock will always display the value of the Bean property of the
coffee1 object. If the value of the Bean property changes, the TextBlock will update automatically. In
terms of the concepts described at the start of this topic:
The binding source is the Bean property of the coffee1 object.
TwoWay Updates the target property when the source property changes, and
updates the source property when the target property changes.
OneWay Updates the target property when the source property changes.
OneTime Updates the target property only when the application starts or when the
DataContext property of the target is changed.
OneWayToSource Updates the source property when the target property changes.
The following example shows how to configure a text box to use two-way data binding:
Additional Reading: For more information about the concepts of data binding, see the
Data Binding Overview page at http://go.microsoft.com/fwlink/?LinkID=267830.
9-22 Designing the User Interfacce for a Graphical Application
Biinding Co
ontrols to Data in XA
AML
Yo
ou can bind coontrols to dataa in various w
ways. If your so
ource data willl not change during the exxecution of
your application
n, you can creeate a static reesource to rep
present your data in XAML. A static resou urce
enables you to create
c instancces of classes. For example, if your assem
mbly contains a class named d Coffee,
you can define a static resourrce to create ana instance off Coffee and set propertiess on it. To create a static
ressource, you m
must:
Add an elem
ment to the R operty of a container contro
Resources pro e top-level Window.
ol, such as the
The following example shows how to bind an individual item to a static resource:
More commonly, you will want to bind multiple UI elements to different properties of a data source. In
this case, you can set the DataContext property on a container object, such as a Grid or a StackPanel.
Setting a DataContext property is similar to providing a partial data binding expression. It specifies the
source object, but does not identify specific properties. Any child controls within the container object will
inherit this data context, unless you override it. This means that when you create data binding expressions
for child controls, you can omit the source and simply specify the path to the property of interest.
The following example shows how to set a data context for a set of child controls:
While you could specify a full data binding expression for each individual UI element, specifying a
DataContext property typically makes your XAML easier to write, easier to read, and easier to maintain.
9-24 Designing the User Interfacce for a Graphical Application
Biinding Co
ontrols to Data in Co
ode
In real-world appplications, it is
i unlikely thaat your source
e data will be static.
s It is far more likely th
hat you will
rettrieve data at runtime fromm a database or o a web service. In these sccenarios, you cannot use a static
ressource to reprresent your da ata. Instead, yyou must use ccode to specify the data so ource for any UI bindings
at runtime.
Creating a Data
a Binding in Code
p
private void mainWindow_
_Loaded(objeect sender, RoutedEventA
R Args e)
{
// Create a Coffee in
nstance to uuse as a data
a source.
Coffee cof
ffee1 = new Coffee();
coffee1.Na
ame = "Fourt
th Coffee Quuencher";
coffee1.Be
ean = "Arabi
ica";
coffee1.Co
ountryOfOrig
gin = "Venezzuela";
coffee1.St
trength = 3;
;
// Create a Binding o
object that references tthe Coffee i
instance.
Binding co
offeeBinding
g = new Bindding();
coffeeBind
ding.Source = coffee1;
coffeeBind
ding.Path = new ProperttyPath("Name");
// Add the
e binding to
o the Text pproperty of t
the TextBloc
ck.
textblock1
1.SetBinding
g(TextBlock.TextPropertyy, coffeeBin
nding);
}
Sp
pecifying Bind
ding Paths in
n XAML
<
<StackPanel x
x:Name="stac
ckCoffee">
<TextBlock
k Text="{Bin
nding Path=N
Name}" />
<TextBlock
k Text="{Bin
nding Path=B
Bean}" />
<TextBlock
k Text="{Bin
nding Path=C
CountryOfOrig
gin}" />
<TextBlock
k Text="{Bin
nding Path=S
Strength}" />
>
Programming in Visual C# 9-25
</StackPanel>
In this example, you have set the binding path for each individual text block in XAML. To complete the
binding, all you need to do is to set the DataContext property of the parent StackPanel object to the
Coffee instance that you want to display.
Biinding Co
ontrols to C
Collection
ns
To
o bind a collecction to an Ite
emsControl in
nstance, you n
need to:
ou can bind an
Yo n ItemsContrrol instance to o any collectio
on that implem
ments the IEn
numerable intterface.
Yo
ou can set the ItemsSource e and Display yMemberPath h properties in XAML or in code. One co
ommon
ap
pproach is to d
define the DissplayMemberrPath propertty (or a data ttemplate) in XXAML, and theen to set
the
e ItemsSourcce programma atically at runtime.
The following co
ode example shows how to
o set the Disp
playMemberP
Path propertyy in XAML:
Se
etting the DissplayMemberrPath Properrty
<
<ListBox x:Na
ame="lstCoff
fees" Displa
ayMemberPath=
="Name" />
Ha
aving set the D
DisplayMemb berPath prop
perty in XAMLL, you can now
w set the Item
msSource property in
code to compleete the data biinding.
The following exxample showss how to set the ItemsSource property in code:
Se msSource Property
etting the Item
/
// Create som
me Coffee in
nstances.
v
var coffee1 = new Coffee
e("Fourth Co
offee Quenche
er");
v
var coffee2 = new Coffee
e("Espresso Number Four");
v
var coffee3 = new Coffee
e("Fourth Re
efresher");
v
var coffee3 = new Coffee
e("Fourth Fr
renetic");
/
// Add the it
tems to an o
observable c
collection.
v
var coffees = new Observ
vableCollect
tion<Coffee>();
c
coffees.Add(c
coffee1);
c
coffees.Add(c
coffee2);
Programming in Visual C# 9-27
coffees.Add(coffee3);
coffees.Add(coffee4);
// Set the ItemsSource property of the ListBox to the coffees collection.
lstCoffees.ItemsSource = coffees;
Whhen you use ccontrols that d derive from thhe ItemsConttrol or Conten ntControl control, you can n create a
da
ata template to o specify howw your items are rendered. FFor example, ssuppose you w want to use a ListBox
control to displaay a collection
n of Coffee innstances. Each
h Coffee instance includes several prope erties to
rep
present the na ame of the co e of coffee beaan, the country of origin, and the streng
offee, the type gth of the
coffee. The dataa template spe ecifies how eaach Coffee instance shouldd be rendered, by mapping properties
of the Coffee in
nstance to child controls wiithin the data template. Cre eating a data template give es you
pre
ecise control oover how you ur items are re
endered and sstyled.
Creating a Data
a Template
<
<ListBox x:Na
ame="lstCofffees" Width=="200">
<ListBox.I
ItemTemplatee>
<DataTe
emplate>
<Gri
id>
<
<Grid.RowDeffinitions>
<RowDefinnition Heighht="2*" />
<RowDefinnition Heighht="*" />
<RowDefinnition Heighht="*" />
<RowDefinnition Heighht="*" />
<
</Grid.RowDeefinitions>
<
<TextBlock TText="{Binding Path=Namee}" Grid.Row
w="0"
Font
tSize="22" BBackground="B
Black" Foreg
ground="Whit
te" />
<
<TextBlock TText="{Binding Path=Beann}" Grid.Row
w="1" />
<
<TextBlock TText="{Binding Path=CounntryOfOrigin
n}" Grid.Row
w="2" />
<
<TextBlock TText="{Binding Path=Streength}" Grid
d.Row="3" />
>
</Grid>
</DataT
Template>
</ListBox.ItemTemplatte>
<
</ListBox>
Additional Reading: For more information about data templates in WPF, see the Data
Templating Overview page at http://go.microsoft.com/fwlink/?LinkID=267833.
9-30 Designing the User Interfacce for a Graphical Application
Lesson 3
Styling
g a UI
In this lesson, yo
ou will learn h
how to use styyles and animaations.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
Define style
es that apply tto multiple co
ontrols.
C
Creating R
Reusable Resourcess in XAMLL
You can d
define a resou
urce once and
d use it in multiple places.
You can e
edit a resource without editing every ele
ement that use
es the resourcce.
Your XAM
ML files are shorter and easier to read.
Note: Every WPF app plication has aan App.xaml ffile. It is a XAM
ML file that can contain gloobal
rresources used by all windo
ows and contrrols in a WPF application. Itt is also the en ntry point for the
a
application, and defines wh
hich window sshould appear when an app plication startts.
Resources are
R e stored in a d
dictionary colle
ection of type
e ResourceDictionary. Wh hen you create
e a reusable
r
resource, you must give it a unique key by providing a value for th
he x:Key attrib
bute.
C
Creating and
d Using Resou
urces
<Window x:CClass="DataBBinding.MainW
Window"
xmlns=
="http://schemas.microsooft.com/winf
fx/2006/xaml/presentatio
on"
xmlns:x="http://schemas.microosoft.com/winfx/2006/xaml"
Title=
="Reusable Resources" Heeight="350" Width="525">
<Window..Resources>
<Sol
lidColorBrussh x:Key="MyBrush" Color
r="Coral" />
>
</Windoww.Resources>>
</Window>
9-32 Designing the User Interface for a Graphical Application
To reference a resource, you use the format {StaticResource [resource key]}. You can use the resource in
any property that accepts values of the same type as the resource, provided that the resource is in scope.
For example, if you create a brush as a resource, you can reference the brush in any property that accepts
brush types, such as Foreground, Background, or Fill.
The following example shows how to reference a reusable resource in multiple places:
If you need to create several reusable resources, it can be useful to create your resources in a separate
resource dictionary file. A resource dictionary is a XAML file with a top-level element of
ResourceDictionary. You can add reusable resources within the ResourceDictionary element in the
same way that you would add them to a Window.Resources element.
Note: You can create a WPF Resource Dictionary from the Add New Item menu in Visual
Studio.
In most cases, you make a resource dictionary available for use in your application by referencing it in the
application-scoped App.xaml file. The following example shows how to reference a resource dictionary in
the App.xaml file:
D
Defining S
Styles as Resources
R
IIn many casess, you will wan nt to apply the same prope erty values to multiple conttrols of the sam me type
w
within an appplication. For e
example, if a p
page containss five textboxe es, you will proobably want e each textbox
t have the saame foreground color, backkground color, font size, an
to nd so on. To m make this consistency
e
easier to manage, you can create Style e elements as reesources in XAAML. Style ele ements enable you to
a
apply a collecction of propeerty values to ssome or all co
ontrols of a paarticular type.. To create a sstyle, perform
t following steps:
the
1
1. Add a Sty
yle element to
o a resource ccollection with
hin your appliication (for exxample, the
Window..Resources co ollection or a resource dictionary).
2
2. Use the T
TargetType atttribute of thee Style eleme
ent to specify tthe type of co
ontrol you want the style
to target (for example,, TextBox or Button).
3
3. Use the x
x:Key attributee of the Style
e element to enable
e controls to specify th his style. Alterrnatively, you
can omit the x:Key atttribute and yoour style will aapply to all controls of the sspecified type e.
4
4. Within th
he Style eleme
ent, use Sette
er elements to
o apply specifiic values to sp
pecific propertties.
C
Creating Stylles
<Window.Res
sources>
<Style TargetType=="TextBlock" x:Key="Bloc
ckStyle1">
<Se
etter Properrty="FontSize" Value="20
0" />
<Se
etter Properrty="Background" Value="
"Black" />
<Se
etter Properrty="Foreground">
<Setter.Va
alue>
<Linea
arGradientBrush StartPoi
int="0.5,0" EndPoint="0.5,1">
<L
LinearGradientBrush.Grad
dientStops>
<GradientStop Offset=
="0.0" Colorr="Orange" />
<GradientStop Offset=
="1.0" Colorr="Red" />
</
/LinearGradientBrush.Gra
adientStops>>
</Line
earGradientBrush>
</Setter.V
Value>
</S
Setter>
</Style
e>
</Window.Re
esources>
9-34 Designing the User Interface for a Graphical Application
To apply this style to a TextBlock control, you need to set the Style attribute of the TextBlock to the
x:Key value of the style resource.
Applying a Style
<TextBlock Text="Drink More Coffee" Style="{StaticResource BlockStyle1}" />
Additional Reading: For more information about defining styles, see the Styling and
Templating page at http://go.microsoft.com/fwlink/?LinkID=267834.
Programming in
i Visual C# 9-35
5
U
Using Pro
operty Trig
ggers
U
Using a Prop
perty Trigger
<Window.Res
sources>
<Style TargetType=="Button">
<St
tyle.Triggerrs>
<Trigger P
Property="IsMouseOver" V
Value="True"
">
<Sette
er Property="FontWeight"
" Value="Bold" />
</Trigger>
>
</S
Style.Triggeers>
</Style
e>
</Window.Re
esources>
9-36 Designing the User Interfacce for a Graphical Application
Crreating Dy
ynamic Trransforma
ations
Sophisticated grraphical applications often use animatio ons to make thhe user experiience more enngaging.
Annimations are sometimes ussed to make ttransitions bettween states less abrupt. Foor example, if you want
to enlarge or ro
otate a picture
e, increasing th gressively over a short
he size or chaanging the orientation prog
tim
me period can witching from one size or o
n look better tthan simply sw orientation to another.
To
o create and apply an animaation effect in
n XAML, you n
need to do three things:
1. Create an aanimation.
WPPF includes vaarious classes that you can use to create animations in n XAML. The m most common nly used
animation element is Double eAnimation. T The DoubleA Animation ele ement specifie
es how a valuee should
change over tim
me, by specifyiing the initial value, the final value, and the duration over which th
he value
sho
ould change.
2. Create a sto
oryboard.
o apply an anim
To mation to an object, you need to wrap yyour animatioon in a Storyb
board element. The
Sto erty you wantt to animate. It does this
oryboard element enabless you to speciffy the object aand the prope
byy providing the
e TargetNamme and TargetProperty atttached properties, which yo ou can set on child
animation elements.
3. gger.
Create a trig
Yo
ou can add an EventTrigge er element containing yourr storyboards and animations to the Trig ggers
collection of a Style
S element, or you can add ers collection of an individual control.
a it directly to the Trigge
Additional Reading: For more information about animations, see the Animation Overview
page at http://go.microsoft.com/fwlink/?LinkID=267835.
9-38 Designing the User Interfacce for a Graphical Application
In this demonstration, you wiill learn aboutt the tasks thaat you will perrform in the laab for this mo
odule.
Programming in
i Visual C# 9-39
9
Lab: Custommizing S
Student Photo
ographs and S
Styling tthe
Appllication
n
S
Scenario
Now that you
N u and The Schoool of Fine Arrts are happy with the basicc functionalityy of the appliccation, you
n
need ove the appeaarance of the interface to g
to impro give the user a nicer experie ence through the use of
a
animations an
nd a consisten
nt look and feel.
You decide to
Y o create a StudentPhoto co ontrol that wiill enable you to display ph
hotographs off students in
t student lisst and other views.
the v You also
o decide to crreate a fluid m
method for a tteacher to rem
move a
s
student from their class.
FFinally, you w
want to update
e the look of tthe various vie
ews, keeping their look con
nsistent acrosss the
a
application.
O
Objectives
A
After completting this lab, you
y will be able to:
Create an
nd use user co
ontrols.
3A-SEA-DEV11-09, MSL-TM
Virtual Machine: 20483 MG1
User Nam
me: Student
Password
d: Pa$$w0rd
9-40 Designing the User Interface for a Graphical Application
You will begin by creating a StudentPhoto user control that will host the photographs on the various
pages in the UI. Then you will lay out the user controls and write code to raise the Student_Click method
when a user clicks a student photograph.
Next, you will add a remove button with a red X to the user control that users can click to remove a
student from a class. When a user hovers over the button, the opacity of the button and the photograph
will change.
Finally, you will run the application to verify that the students image is displayed correctly on the
StudentsPage view.
3. Start Visual Studio, and then open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 1
folder.
a. Grades.Web
b. Grades.WPF
5. Add a new WPF user control named StudentPhoto.xaml to the Controls folder in the Grades.WPF
project.
6. Modify the XAML markup for the user control as follows:
a. Add an Image control to the Grid. This Image control will use data binding to display the
photograph, and the source of the Image should be the File property of the data source. The
Image should fill the user control except for a margin of 8 points all the way around to allow for
a frame.
b. Add a second Image control to the Grid. This Image control will display the frame around the
student photograph, and it should completely fill the Grid, so specify a margin of 0 points. Use
the Image_Frame.png file in the Images folder as the source for the Image; this image has a
transparent center that enables the student photograph to show through.
c. Add a TextBlock control to display the name of the student underneath the photo frame. This
control will also use data binding, and the name will be provided by the Name property of the
data source. Use the static resource LabelCenter to style the text and set the FontSize to 16. Set
Programming in Visual C# 9-41
the VerticalAlignment to Bottom to ensure that the name appears underneath the photograph,
and specify a margin of 8, 0, 14.583, 8 to add a bit of space around the name.
<UserControl x:Class="Grades.WPF.StudentPhoto"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-
compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Image Stretch="UniformToFill" Source="{Binding File}" Margin="8" />
<Image Margin="0" Source="../Images/Image_Frame.png" Stretch="Fill" />
<TextBlock Text="{Binding Name}" Style="{StaticResource LabelCenter}"
FontSize="16" VerticalAlignment="Bottom" Margin="8,0,14.583,8" />
</Grid>
</UserControl>
7. In StudentPhoto.xaml.cs, remove the existing using directives and add using directives to bring the
following namespaces into scope:
System.Windows.Controls
System.Windows.Media.Animation
2. In the ItemsControl element, add an ItemsPanel control that will be used to define the layout for
the list of photographs. The ItemsPanel control should contain an ItemsPanelTemplate element
with the following property values:
o Margin: 0:
o Orientation: Horizontal
o HorizontalAlignment: Center
The completed markup should look like the following:
<ItemsControl x:Name="list">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="0" Orientation="Horizontal"
HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl>
3. Add an ItemTemplate element to the ItemsControl. This element will specify how each photograph
is displayed and formatted.
4. In the ItemTemplate element, define a DataTemplate that displays the StudentPhoto control in a
grid with a Margin property of 8 points.
9-42 Designing the User Interface for a Graphical Application
Use the following information to set the properties of the StudentPhoto control.
Height: 150
Width: 127.5
Cursor: Hand
<ItemsControl x:Name="list">
<ItemsControl.ItemsPanel>
...
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="8">
<local:StudentPhoto Height="150" Width="127.5" Cursor="Hand" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl>
The StudentProfile view subscribes to this event and uses it to display the details of the selected student.
The Student_Click method should verify that the StudentSelected event has at least one subscriber
before raising the event. The StudentSelected event expects a LocalStudent object containing the data
for the student to be provided as an event parameter (this is so that the StudentProfile view knows
which student to display). This is actually the same object that will be used as the data source for the
StudentPhoto control that the user clicked. You can retrieve this object form the DataContext property
of the sender parameter to the Student_Click method (you must cast the sender property to the
StudentPhoto type first).
Note: The LocalStudent type is a wrapper around the Student class retrieved from the
database by using the WCF data service. It provides additional helper methods that the WPF
Programming in Visual C# 9-43
application can use to format the details of a student for display purposes. This type is defined in
the Data.cs file.
The XAML markup for the StudentPhoto control should look like this:
VerticalAlignment: Top
HorizontalAlignment: Right
Background: #00000000
Opacity: 0.3
Width: 20
Height: 20
Tag: {Binding}
Note: The Tag property will contain a reference to the student, so that the "remove"
functionality knows which student to remove. This property will use the data binding of the
ItemsControl that contains the DataTemplate to reference the student.
3. Add an Image control as a child of the Grid control and use it to display the delete.png picture in
the Images folder. Set the Stretch property to Uniform. This image contains a cross symbol that will
be displayed by the remove icon.
The XAML markup for the Grid control should look like this:
This method is an event handler that will run when the mouse moves over the remove icon for a student
photograph.
5. In the RemoveStudent_MouseEnter method, add code to change the Opacity property of the Grid
control holding the delete icon to 1.0 and the Opacity property of the StudentPhoto control to 0.6.
9-44 Designing the User Interface for a Graphical Application
Note: The Grid control that holds the delete icon is available in the sender parameter; cast
it to a Grid control first before setting the Opacity property.
The StudentPhoto control can be located by accessing the Parent property of the Grid control
holding the delete icon, and then accessing the first child element; use the expression
Children[0] and cast the result to the StudentPhoto type.
This code highlights the remove icon and slightly dims the student photograph.
The completed code for this method should look like this:
7. In this method, add code to change the Opacity property of the Grid control to 0.3 and the Opacity
property of the StudentPhoto control to 1.0. This code restores the photograph to its original
brightness and dims the remove icon as the mouse moves away.
The completed code for this method should look like this:
8. In StudentsPage.xaml, in the Grid control for the remove icon, specify the event handlers to use
when the mouse traverses the control; when the mouse enters the control raise the
RemoveStudent_MouseEnter event, and when the mouse leaves the control, raise the
RemoveStudent_MouseLeave event.
9. If the user clicks the remove icon, invoke the RemoveStudent_Click event.
The code for this event has already been written; it displays a dialog box that prompts the user to
confirm that they really want to remove the student, and then removes the student if the user clicks
Yes.
The completed XAML markup for ItemsControl element, including the student photograph and the
remove icon, should look like this:
<ItemsControl x:Name="list">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="0" Orientation="Horizontal"
HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="8">
<local:StudentPhoto Height="150" Width="127.5" Cursor="Hand"
MouseLeftButtonUp="Student_Click" />
Programming in Visual C# 9-45
This method runs each time the StudentsPage view is displayed. The purpose of this method is to ensure
that the view displays a correct and up-to-date list of students for the teacher.
2. In this method, add code to find all students for the current teacher.
To do this, perform the following tasks:
Call the GetStudentsByTeacher method of the ServiceUtils object, to retrieve the list of students for
the currently logged-in teacher. Pass in the name of the current teacher as the parameter to this
method. The name is available in the UserName property of the SessionContext object.
Note: The ServiceUtils object is a wrapper around the WCF Data Service that provides the
data for the application. It provides a number of helper methods, such as
GetStudentsByTeacher that abstract the details of the WCF Data Service from the application.
The SessionContext object contains static properties that hold information about the user
currently running the application. These properties are populated when the user logs in. The
UserName property is the login name of the user.
3. In the Refresh method, add code to iterate through the set of students returned by the
GetStudentsByTeacher method and construct a list containing LocalStudent objects for each
student.
Note: Remember that a LocalStudent object is a wrapper around a Student object that is
retrieved by using the WCF Data Service. The LocalStudent type provides helper methods and
properties such as Name (which returns the full name of a student), and File (which returns a
formatted URL that references the photographic image file of a student). The StudentPhoto
control uses data binding bind to these properties.
4. Add code to bind the list of students to the list ItemsControl control.
Note: Set the ItemsSource property of the list object to the list of students.
The completed code for the Refresh method should look like this:
6. Verify that the student photograph for Martin Weber becomes transparent and that the red x
becomes opaque.
7. Move the cursor away from the red x and verify that the student photograph becomes opaque and
that the red x becomes transparent.
8. Click the red x for Martin Weber, verify that the Student message box appears, and then click Yes.
9. Verify that Martin Weber is removed from the student list.
Results: After completing this exercise, the application will display the photographs of each student on
the Student List page.
Programming in Visual C# 9-47
First, you will define styles for the username and password text boxes on the LogonPage of the
application. You will use the Style property of each control to apply the styles that you have defined.
Then you will define some global styles for use across the entire application. You will define a style for
labels and a style for text.
Next, you will define an animation for the StudentPhoto control, which will cause a students photograph
to pulse when a user hovers over it. You will then add event handlers for this animation and apply the
animation to the control.
Finally, you will run the application to verify that the styling of the text elements has changed throughout
the application and that the animations execute correctly.
The main tasks for this exercise are as follows:
a. Grades.Web
b. Grades.WPF
4. In the LogonPage user control, define a style named LoginTextBoxStyle, based on the
TextBoxStyle style, and targeting text boxes.
Margin: 5
FontSize: 24
MaxLength: 16
The XAML markup for the style should look like this:
6. Locate the definition of the username text box, delete the FontSize property of the control, and then
apply the LoginTextBoxStyle to the control.
9-48 Designing the User Interface for a Graphical Application
FontSize: 24
MaxLength: 16
9. Locate the definition of the password text box, delete the FontSize property of the control, and then
apply the PasswordBoxStyle to the control.
2. Locate the <!-- TODO: Exercise 2: Task 2a: Define the label styling used throughout the application --
> comment near the end of the file.
3. Below this comment, set the properties of the LabelStyle style by using the following information:
TextWrapping: NoWrap
FontSize: 19
Foreground: #FF303030
4. Locate the <!-- TODO: Exercise 2: Task 2b: Define the text styling used throughout the application -->
comment.
5. Below this comment, set the properties of the TextBoxStyle style by using the following information:
TextWrapping: NoWrap
FontSize: 12
TextAlignment: Left
Foreground: #FF303030
2. Add a ScaleTransform named scale to the StudentPhoto user control. You will use this transform to
change the size of the StudentPhoto user control when the mouse moves over it.
Note: Create a RenderTransform section in the user control, and add the ScaleTransform
to this section.
3. Add a Storyboard to the StudentPhoto user control that will contain animations that are performed
when the mouse enters the control; set the x:Key property to sbMouseEnter.
The animations in this storyboard will use the ScaleTransform that you have just defined.
Note: Create a Resources section in the user control, and add the storyboard to this
section.
Programming in Visual C# 9-49
4. Add a DoubleAnimation element for the x axis to the storyboard. Use the following information to
define the properties of the animation:
To: 1.1
BeginTime: 00:00:00
Duration: 00:00:00.05
Storyboard.TargetName: scale
Storyboard.TargetProperty: ScaleX
5. Add another DoubleAnimation element to the same storyboard for the y axis, using the following
information:
To: 1.1
BeginTime: 00:00:00
Duration: 00:00:00.15
Storyboard.TargetName: scale
Storyboard.TargetProperty: ScaleY
6. Add another Storyboard that will contain animations that are performed when the mouse leaves the
control; set the x:Key property to sbMouseLeave.
7. Add a DoubleAnimation element for the x axis to this storyboard, using the following information:
To: 1
BeginTime: 00:00:00
Duration: 00:00:00.05
Storyboard.TargetName: scale
Storyboard.TargetProperty: ScaleX
8. Add another DoubleAnimation element to the storyboard for the y axis, using the following
information:
To: 1
BeginTime: 00:00:00
Duration: 00:00:00.15
Storyboard.TargetName: scale
Storyboard.TargetProperty: ScaleY
2. Add code to define the OnMouseEnter event handler that triggers the mouse enter animation
(sbMouseEnter), as follows:
3. Add code to define the OnMouseLeave event handler that triggers the mouse leave animation
(sbMouseLeave).
5. In the Events region, add an event handler called Student_MouseEnter to forward the MouseEnter
event to the StudentPhoto control, as follows:
6. Add another event handler called Student_MouseLeave that forwards the MouseLeave event to the
StudentPhoto control.
7. In the XAML markup for the StudentsPage.view, specify that the MouseEnter event for the
StudentPhoto control in the DataTemplate should trigger the Student_MouseEnter event handler
method, and the MouseLeave event should trigger the Student_MouseLeave event handler.
4. In The School of Fine Arts window, verify that the styling of the text elements of the application has
changed.
Programming in Visual C# 9-51
FIGURE 9.1: UPPER: OLD STYLE LOGON VIEW. LOWER: NEW STYLE LOGON VIEW
5. Hover over one of the students in the student list and verify that the photograph animatesit should
expand and contract as the mouse passes over it
6. Close the application, and then in Visual Studio, close the solution.
Results: After completing this exercise, the Logon view and the Photograph control will be styled with a
consistent look and feel.
9-52 Designing the User Interfacce for a Graphical Application
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou learned how
h to create engaging UIss for graphical applicationss. You learned how to
usee XAML to creeate windowss and user conntrols and how
w you bind co ontrols to dataa items and co ollections.
Yoou also learned
d how to provvide a consiste
ent user experience by creaating styles ass reusable reso
ources.
Q
Question
Y
You want to u
use rows and columns to laay out a UI. W
Which contain
ner control sh
hould you
u
use?
S
Select the corrrect answer.
The Ca
anvas control.
The Do
ockPanel control.
The W
WrapPanel con
ntrol.
Q
Question
Question
Create a ListBox control. Add child controls to the ListBox control to represent each
field.
Create a ListBox control. Use a DataTemplate to specify how each field is displayed
within a list item.
Create a ListBox control. Create a custom control that inherits from ListBoxItem,
and use this custom control to specify how each field is displayed.
Create a ListBox control. Use the DisplayMemberPath property to specify the fields
you want to display in each list item.
Create a ListBox control. Use a Style to specify how each field is displayed within a
list item.
Question
You want to apply a highlighting effect to selected items in a ListBox. How should you
proceed?
Create a Style element and set the TargetType attribute to ListBox. Use a Setter
element to apply the highlighting effect.
Create a Style element and set the TargetType attribute to ListBox. Use a Trigger
element to apply the highlighting effect when a list box item is selected.
Create a Style element and set the TargetType attribute to ListBox. Use an
EventTrigger element to apply the highlighting effect when a list box item is
selected.
Create a Style element and set the TargetType attribute to ListBox. Use a
Storyboard element to apply the highlighting effect when a list box item is
selected.
Create a Style element and set the TargetType attribute to ListBox. Use a
DoubleAnimation element to apply the highlighting effect when a list box item is
selected.
10-1
Module 10
Improving Application Performance and Responsiveness
Contents:
Module Overview 10-2
Modu
ule Ove
erview
Mo odern processsors use threaads to concurrrently run multiple operatio ons. If your ap
pplication perfforms all of
its logic on a sin
ngle thread, yo
ou do not maake the best use of the avaiilable processing resources,, which can
ressult in a poor experience fo
or your users. In this module, you will leaarn how to immprove the perrformance
of your applicattions by distrib
buting your o
operations acrross multiple tthreads.
Ob
bjectives
Aftter completing this module
e, you will be able to:
Control how
w multiple thrreads can acce
ess resources concurrently..
Programming in
i Visual C# 10-3
3
Lesson 1
Implementiing Multitasking
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create tasks.
Cancel long-running ta
asks.
Crreating Taasks
The Task class lies at the heart of the Taskk Parallel Libraary in the .NETT Framework. As the name suggests,
you use the Tassk class to reppresent a task, or in other words,
w a unit o
of work. The TTask class enables you to
peerform multiplle tasks concuurrently, each on a differentt thread. Behind the sceness, the Task Parallel
Lib
brary manages the thread p pool and assig
gns tasks to th hreads. You caan implementt sophisticated d
mu ultitasking fun
nctionality by using the Tassk Parallel Librrary to chain ttasks, pause taasks, wait for tasks to
complete before e continuing, and perform many other o operations.
Crreating a Ta
ask
Yo
ou create a new Task object by using the e Task class. A Task object runs a block of code, and you specify
thiis code as a parameter to the constructo
or. You can provide this cod
de in a methood and create an Action
de
elegate that w wraps this meth
hod.
Note: A ddelegate proviides a mechannism for refereencing a blocck of code or a method. Thee
Acction class is a type in the .NET Framewo nvert a method
ork Class Libraary that enables you to con
intto a delegate. The method cannot return n a value, but it can take paarameters. The .NET
Fraamework Classs Library also provides the Func class, which
w enables you to define
e a delegate th
hat
can return a result.
The following co
ode example shows how to
o create a taskk by using an Action deleg
gate:
Creating a Task
k by Using an
n Action Dele
egate
T
Task task1 = new Task(ne
ew Action(Ge
etTheTime));
p
private stati
ic void GetT
TheTime()
{
Console.WriteLine("Th
he time now is {0}", DatteTime.Now);
;
}
an anonymous method inline, at the point you need to use it. You can use the delegate keyword to
convert an anonymous method into a delegate.
The following code example shows how to create a task by using an anonymous delegate.
If you want your delegate to invoke a named method or a single line of code, you use can use a lambda
expression. A lambda expression provides a shorthand notation for defining a delegate that can take
parameters and return a result. It has the following form:
In this case:
The lambda operator, =>, is read as goes to.
The left side of the lambda operator includes any variables that you want to pass to the expression. If
you do not require any inputsfor example, if you are invoking a method that takes no parameters
you include empty parentheses () on the left side of the lambda operator.
The right side of the lambda operator includes the expression you want to evaluate. This could be a
comparison of the input parametersfor example, the expression (x, y) => x == y will return true if x is
equal to y; otherwise, it will return false. Alternatively, you can call a method on the right side of the
lambda operator.
The following code example shows how to use lambda expressions to represent a delegate that invokes a
named method.
A lambda expression can be a simple expression or function call, as the previous example shows, or it can
reference a more substantial block of code. To do this, specify the code in curly braces (like the body of a
method) on the right side of the lambda operator:
(input parameters) => { Visual C# statements; }
The following code example shows how to use lambda expressions to represent a delegate that invokes
an anonymous method.
As your delegates become more complex, lambda expressions offer a far more concise and easily
understood way to express anonymous delegates and anonymous methods. As such, lambda expressions
are the recommended approach when you work with tasks.
10-6 Improving Application Performance and Responsiveness
Reference Links: For more information about lambda expressions, see Lambda Expressions
(C# Programming Guide) at http://go.microsoft.com/fwlink/?LinkID=267836.
Programming in
i Visual C# 10-7
7
C
Controllin
ng Task Exxecution
S
Starting Ta
asks
When your co
W ode starts a taask, the Task P
Parallel Libraryy assigns a thrread to your ttask and startss running thatt
t
task. The task runs on a sep parate thread,, so your code e does not need to wait forr the task to complete.
I
Instead, the taask and the coode that invokked the task ccontinue to ru un in parallel.
I you want to
If o queue the taask immediate
ely, you use th
he Start meth
hod.
U
Using the Task.Start Method to Queu
ue a Task
var task1 = new Task( () => Console.WriteLine
e("Task 1 ha
as completed.") );
task1.Start
t();
U
Using the TaskFactory.Sta
artNew Meth
hod to Queue
e a Task
var task3 = Task.Facto
ory.StartNew( () => Cons
sole.WriteLine("Task 3 has complete
ed.") );
The Task.Facttory.StartNew
T w method is highly configuurable and acccepts a wide range of para ameters. If
y simply waant to queue some code with the default scheduling o
you options, you ccan use the sttatic
T
Task.Run method as a shoortcut for the Task.Factory
T .StartNew method.
U
Using the Task.Run Meth
hod to Queue
e a Task
var task4 = Task.Run( () => Console.WriteLine
e("Task 4 ha
as completed. ") );
W
Waiting forr Tasks
IIn some casess, you may nee ed to pause the execution of your code until a particu
ular task has ccompleted.
T
Typically you do this if your code depennds on the result from one or
o more taskss, or if you neeed to handle
e
exceptions thaat a task may throw. The Task class offers various me
echanisms to ddo this:
10-8 Improving Application Performance and Responsiveness
If you want to wait for a single task to finish executing, use the Task.Wait method.
If you want to wait for multiple tasks to finish executing, use the static Task.WaitAll method.
If you want to wait for any one of a collection of tasks to finish executing, use the static
Task.WaitAny method.
The following code example shows how to wait for a single task to complete.
If you want to wait for multiple tasks to finish executing, or for one of a collection of tasks to finish
executing, you must add your tasks to an array. You can then pass the array of tasks to the static
Task.WaitAll or Task.WaitAny methods.
The following code example shows how to wait for multiple tasks to complete.
R
Returning
g a Value ffrom a Task
FFor tasks to be effective in real-world sceenarios, you nneed to be abble to create taasks that can return values,,
o results, to tthe code that initiated the ttask. The regu
or ular Task classs does not enable you to do this.
H
However, the Task Parallel Library also in
ncludes the geeneric Task<T TResult> classs that you can use when
y need to return
you r a value.
R
Retrieving a Value from a Task
// Create a
and queue a task that returns the dday of the week
w as a string.
Task<string
g> task1 = Task.Run<str
T ing>( () => DateTime.No
ow.DayOfWeek.ToString() );
// Retrieve
e and displa
ay the task result.
Console.Wri
iteLine(task
k1.Result);
Caancelling Long-Run
nning Task
ks
Tasks are often used to perfo orm long-runn ning operation ns without bloocking the UI thread, becau use of their
asyynchronous nature. In some cases, you w will want to giive your userss the opportunnity to cancel a task if
theey are tired off waiting. How
wever, it would be dangero ous to simply aabort the taskk on demand, because
thiis could leave your applicattion data in an unknown sttate. Instead, tthe Task Paralllel Library use
es
canncellation tokkens to supporrt a cooperativve cancellatio
on model. At a high level, thhe cancellatio
on process
woorks as followss:
1. When you create
c a task, you also create a cancellattion token.
2. You pass th
he cancellation
n token as an argument to your delegate method.
3. On the threead that created the task, you request cancellation by calling the Ca
ancel method
d on the
cancellation
n token sourcee.
4. In your taskk method, youu can check thhe status of th n token at anyy point. If the instigator
he cancellation
has requestted that the taask be cancelled, you can teerminate your task logic grracefully, posssibly rolling
back any ch hanges resulting from the wwork that the task has perfoormed.
Typically, you w
would check wwhether the caancellation tokken has been set to cancele ed at one or mmore
convenient poinnts in your tassk logic. For exxample, if you
ur task logic itterates over a collection, yo
ou might
check for cancellation after e
each iteration.
The following co
ode example shows how to
o cancel a taskk.
Ca
ancelling a Ta
ask
/
// Create a c
cancellation
n token sour
rce and obtai
in a cancell
lation token
n.
C
CancellationT
TokenSource cts = new C
CancellationT
TokenSource(
();
C
CancellationT
Token ct = c
cts.Token;
/
// Create and
d start a ta
ask.
T
Task.Run( () => doWork(c
ct) );
/
// Method run
n by the tas
sk.
p
private void doWork(Canc
cellationTok
ken token);
{
// Check f
for cancella
ation.
if(token.I
IsCancellati
ionRequested
d)
{
// Tidy
y up and fin
nish.
Programming in Visual C# 10-11
return;
}
// If the task has not been cancelled, continue running as normal.
}
This approach works well if you do not need to check whether the task ran to completion. Each task
exposes a Status property that enables you to monitor the current status of the task in the task life cycle.
If you cancel a task by returning the task method, as shown in the previous example, the task status is set
to RanToCompletion. In other words, the task has no way of knowing why the method returnedit may
have returned in response to a cancellation request, or it may simply have completed its logic.
If you want to cancel a task and be able to confirm that it was cancelled, you need to pass the cancellation
token as an argument to the task constructor in addition to the delegate method. In your task method,
you check the status of the cancellation token. If the instigator has requested the cancellation of the task,
you throw an OperationCanceledException exception. When an OperationCanceledException
exception occurs, the Task Parallel Library checks the cancellation token to verify whether a cancellation
was requested. If it was, the Task Parallel Library handles the OperationCanceledException exception,
sets the task status to Canceled, and throws a TaskCanceledException exception. In the code that
created the cancellation request, you can catch this TaskCanceledException exception and deal with the
cancellation accordingly.
The following code example shows how to cancel a task by throwing an OperationCanceledException
exception.
Reference Links: For more information about cancelling tasks, see Task Cancellation at
http://go.microsoft.com/fwlink/?LinkID=267837 and How to: Cancel a Task and Its Children at
http://go.microsoft.com/fwlink/?LinkID=267838.
10-12 Improoving Application Performance and Respponsiveness
Ru
unning Taasks in Parrallel
Ex
xecuting a S
Set of Task
ks Simultane
eously
un a fixed set of tasks in paarallel, you can use the Parrallel.Invoke m
If yyou want to ru method. Whe en you call
thiis method, you use lambdaa expressions tto specify the tasks that you want to run n simultaneouusly. You do
noot need to expplicitly create each
e taskth he tasks are created implicittly from the d
delegates that you supply
to the Parallel.IInvoke metho od.
The following co
ode example shows how to
o use the Para
allel.Invoke m
method to run
n several taskss in parallel.
Ru
unning Loo
op Iteration
ns in Paralle
el
The Parallel class also provid des methods tthat you can use
u to run forr and foreach loop iteration ns in
parallel. Clearly it will not alw
ways be appro ns in parallel. For example, if you want
opriate to run loop iteration
to compare sequential valuess, you must ru un your loop iterations sequuentially. How wever, if each loop
ite
eration represeents an independent opera ation, running loop iterations in parallel enables you tto maximize
your use of the available proccessing power.
An Action<
<Int32> deleg
gate that is exxecuted once per iteration..
The following co ode example shows how to o use a Parallel.For loop. Inn this example
e, each elemeent of an
arrray is set to th
he square roott of the indexx value. This is a simple exam
mple of a loop in which the
e order of
thee iterations dooes not matteer.
Programming in Visual C# 10-13
To run foreach loop iterations in parallel, you can use the Parallel.ForEach method. Like the Parallel.For
method, the Parallel.ForEach method includes many different overloads. In its simplest form, the
Parallel.ForEach method takes two parameters:
The following code example shows how to use a Parallel.ForEach loop. In this example, you iterate over a
generic list of Coffee objects. For each item, you call a method named CheckAvailability that accepts a
Coffee object as an argument.
Additional Reading: For more information and examples about running data operations in
parallel, see Data Parallelism (Task Parallel Library) at
http://go.microsoft.com/fwlink/?LinkID=267839.
Using PLINQ
var coffeeList = new List<Coffee>();
// Populate the coffee list
var strongCoffees =
from coffee in coffeeList.AsParallel()
where coffee.Strength > 3
select coffee;
Additional Reading: For more information about PLINQ, see Parallel LINQ (PLINQ) at
http://go.microsoft.com/fwlink/?LinkID=267840.
Programming in Visual C# 10-15
5
L
Linking Taasks
SSometimes it is useful to seequence tasks. For example e, you might require that if a task comple etes
s
successfully, aanother task iss run, or if the
e task fails, a different
d task iis run that possibly needs tto perform
s
some kind of recovery proccess. A task th hat runs only w when a previo ous task finishes is called a continuation.
T approach
This h enables you to construct a pipeline of background o operations.
Additionally, a task may spawn other tassks if the workk that it needss to perform is also multith
A hreaded in
n
nature. The paarent task (thee task that spa awned the neew or nested taasks) can waitt for the neste
ed tasks to
c
complete befoore it finishes itself, or it can return and let the child tasks continue
e running asyn nchronously.
T
Tasks use the parentt task to wait are called chiild tasks.
that cau
C
Continuatio
on Tasks
Continuation tasks enable yyou to chain multiple
C m taskss together so tthat they execcute one afterr another.
T task that invokes anoth
The her task on co
ompletion is kknown as the antecedent,
a an
nd the task th
hat it invokes
i known as th
is he continuatio
on. You can paass data from the antecede ent to the conntinuation, andd you can
c
control the exxecution of the task chain in various wayys. To create a basic continuuation, you usse the
T
Task.Continu ueWith metho od.
C
Creating a Ta
ask Continua
ation
// Create a task that returns a string.
Task<string
g> firstTask
k = new Task<string>( ()
) => return "Hello" );
// Create t
the continua
ation task.
// The dele
egate takes the result of the antec
cedent task as an argument.
Task<string
g> secondTas
sk = firstTask.ContinueW
With( (antec
cedent) =>
{
retur
rn String.Fo
ormat("{0}, W
World!", ant
tecedent.Res
sult));
}
// Start th
he anteceden
nt task.
firstTask.S
Start();
// Use the continuatio
on task's result.
Console.Wri
iteLine(seco
ondTask.Result);
// Displays
s "Hello, Wo
orld!"
Notice that w
N when you creatte the continu
uation task, yoou are providiing the result of the first task as an
a
argument to the
t delegate of
o the second d task. For example, you mig ght use the first task to collect some
10-16 Improving Application Performance and Responsiveness
data and then invoke a continuation task to process the data. Continuation tasks do not have to return
the same result type as their antecedent tasks.
Note: Continuations enable you to implement the Promise pattern. This is a common idiom
that many asynchronous environments use to ensure that operations perform in a guaranteed
sequence.
Additional Reading: For more information about continuation tasks, see Continuation
Tasks at http://go.microsoft.com/fwlink/?LinkID=267841.
To illustrate the difference between nested tasks and child tasks, consider these two simple examples.
The following code example shows how to create a nested task.
In this case, due to the delay in the nested task, the outer task completes before the nested task.
});
parent.Wait();
Console.WriteLine("Parent task completed.");
/* Output:
Parent task starting
Child task starting
Child task completing
Parent task completed.
*/
Note that the preceding example is essentially identical to the nested task example, except that in this
case, the child task is created by using the AttachedToParent option. As a result, in this case, the parent
task waits for the child task to complete before completing itself.
Nested tasks are useful because they enable you to break down asynchronous operations into smaller
units that can themselves be distributed across available threads. By contrast, it is more useful to use
parent and child tasks when you need to control synchronization by ensuring that certain child tasks are
complete before the parent task returns.
Additional Reading: For more information about nested tasks and child tasks, see Nested
Tasks and Child Tasks at http://go.microsoft.com/fwlink/?LinkID=267842.
10-18 Improoving Application Performance and Respponsiveness
Handling T
Task Excep
ptions
Wh hen a task thrrows an excep ption, the exce pagated back to the thread that initiated
eption is prop d the task
he joining threead). The task might be linkked to other taasks through continuationss or child taskks, so
(th
muultiple exceptions may be tthrown. To en nsure that all e
exceptions are
e propagated back to the jo oining
thrread, the Taskk Parallel Libraary bundles an
ny exceptionss together in aan Aggregate
eException o object. This
obbject exposes aall of the exceeptions that o
occurred throu ugh an InnerEExceptions co
ollection.
To
o catch excepttions on the jo
oining thread,, you must wa e. You do this by calling
ait for the taskk to complete
the
e Task.Wait mmethod in a try block and then catching g an Aggrega ateException exception in n the
corresponding ccatch block. A common exxception-hand dling scenario is to catch the
Ta
askCanceledE Exception excception that is i thrown wheen you cancel a task.
The following co
ode example shows how to
o handle task exceptions.
Ca
atching Task Exceptions
s
static void MMain(string[
[] args)
{
// Create a cancellattion token s
source and obbtain a canc
cellation to
oken.
CancellatiionTokenSour
rce cts = ne
ew CancellatiionTokenSour
rce();
CancellatiionToken ct = cts.Token
n;
// Create and start a long-running task.
var task1 = Task.Run((() => doWor
rk(ct),ct);
// Cancel the task.
cts.Cancell();
// Handle the TaskCannceledExcept
tion.
try
{
task1.W
Wait();
}
catch(AggregateExcepttion ae)
{
foreach
h(var inner in ae.Inner
rExceptions)
{
if(i
inner is Tas
skCanceledEx
xception)
{
C
Console.Writ
teLine("The task was canncelled.");
C
Console.Read
dLine();
}
else
e
{
Programming in Visual C# 10-19
Additional Reading: For more information about handling task exceptions, see Exception
Handling (Task Parallel Library) at http://go.microsoft.com/fwlink/?LinkID=267843.
10-20 Improoving Application Performance and Respponsiveness
Lesson 2
Perforrming Operati
O ions Assynchro
onously
y
An
n asynchronouus operation is an operation that runs onn a separate thread; the thrread that initiaates an
operation doess not need to wait for that operation to complete beffore it can con
asyynchronous o ntinue.
In this lesson, yo
ou will learn vvarious techniq
ques for invokking and man
naging asynch
hronous operaations.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
Use the Disspatcher obje
ect to run code on a specific thread.
U
Using the
e Dispatcher
IIn the .NET Frramework, eacch thread is asssociated withh a Dispatche er object. The dispatcher is responsible
f maintainin
for ng a queue off work items fo or the thread.. When you work
w across muultiple threads, for
e
example, by running asynchronous taskss, you can use e the Dispatch her object to invoke logic ono a specific
t
thread. You tyypically need to do this when you use assynchronous o operations in graphical app plications. For
e
example, if a user
u button in a Wiindows Pressentation Foundation (WPFF) application,, the click
clicks a b
e
event handlerr runs on the UI thread. If the event hand dler starts an asynchronouss task, that tassk runs on
t background thread. As a result, the task
the t logic no longer has access to contro ols on the UI, because
t
these are all o
owned by the UI thread. To o update the UI,
U the task log gic must use the
t
D
Dispatcher.B BeginInvoke m method to qu ueue the upda ate logic on thhe UI thread.
Consider a sim
C mple WPF app plication that consists of a b
button namedd btnGetTime e and a label named
l
lblTime. Whe en the user clicks the button, you use a task to get the
e current time
e. In this exam
mple, the task
s
simply queries the DateTim me.Now prop many scenarios, your applications might retrieve data
perty, but in m
f
from web servvices or datab
bases in response to activityy on the UI.
T Wrong Way
The W to Update a UI Objecct
public void
d btnGetTime
e_Click(object sender, R
RoutedEventA
Args e)
{
Task.Run
n(() =>
{
st
tring curren
ntTime = DateTime.Now.To
oLongTimeStr
ring();
Se
etTime(curre
entTime);
}
}
private voi
id SetTime(s
string time)
{
lblTime.
.Content = t
time;
}
To do this, you can retrieve the Dispatcher object that is associated with the lblTime object and then call
the Dispatcher.BeginInvoke method to invoke the SetTime method on the UI thread.
The following code example shows how to use the Dispatcher.BeginInvoke method to update a control
on the UI thread.
Note that the BeginInvoke method will not accept an anonymous delegate. The previous example uses
the Action delegate to invoke the SetTime method. However, you can use any delegate that matches the
signature of the method you want to call.
Programming in Visual C# 10-23
3
U
Using async and aw
wait
Consider a sim
C mple WPF app plication that consists of a b
button named d btnLongOp peration and a label
n
named lblRessult. When the user clicks tthe button, the event handler invokes a llong-running operation. In n
t example, it simply sleeps for 10 seco
this onds and then n returns the rresult Operattion complete
e. In practice,,
h
however, you might make a call to a web service or re etrieve inform
mation from a database. Wh hen the task iss
c
complete, thee event handle
er updates the e lblResult label with the rresult of the o
operation.
The following code example shows an application thaat performs a synchronous long-running
T g operation
o the UI thre
on ead.
R
Running a Sy
ynchronous O
Operation on
n the UI Thread
private voi
id btnLongOp
peration_Click(object se
ender, Route
edEventArgs e)
{
lblResul
lt.Content = "Commencing long-runni
ing operatio
on";
Task<str
ring> task1 = Task.Run<string>(() =
=>
{
//
/ This repre
esents a long-running op
peration.
Th
hread.Sleep(
(10000);
re
eturn "Opera
ation Complete";
}
// This statement b
blocks the UI thread unt
til the task
k result is available.
lblResul
lt.Content = task1.Result;
}
IIn this example, the final sttatement in thhe event hand dler blocks the
e UI thread unntil the result o
of the task is
a
available. Thiss means that tthe UI will effe
ectively freeze
e, and the use
er will be unab
ble to resize thhe window,
m
minimize the window, and so on. To enaable the UI to remain respo onsive, you can convert the e event
h
handler into aan asynchrono ous method.
10-24 Improving Application Performance and Responsiveness
The following code example shows an application that performs an asynchronous long-running operation
on the UI thread.
This example includes two key changes from the previous example:
Notice that when you use the await operator, you do not await the result of the taskyou await the task
itself. When the .NET runtime executes an async method, it effectively bypasses the await statement until
the result of the task is available. The method returns and the thread is free to do other work. When the
result of the task becomes available, the runtime returns to the method and executes the await
statement.
Additional Reading: For more information about using async and await, see
Asynchronous Programming with Async and Await (C# and Visual Basic) at
http://go.microsoft.com/fwlink/?LinkID=267844.
Programming in Visual C# 10-25
5
C
Creating A
Awaitable
e Methodss
If your synchronous method has a return type of TResult, your asynchronous method sh
hould return a
Task<TR Result> objectt.
An asynchron
A nous method ccan return void; however, this
t is typicallyy only used fo
or event hand
dlers.
W
Wherever posssible, you sho
ould return a T
Task object to
o enable calle
ers to use the await operattor with your
m
method.
A Long-Runn
ning Synchro
onous Method
private str
ring GetData
a()
{
var task
k1 = Task.Ru
un<string>(() =>
{
//
/ Simulate a long-running task.
Th
hread.Sleep(
(10000);
re
eturn "Opera
ation Complete.";
});
return t
task1.Result
t;
}
Modify th
he method log
gic to use the
e await operattor with any lo
ong-running operations.
10-26 Improving Application Performance and Responsiveness
The following code example shows how to convert the previous synchronous method into an
asynchronous method.
The GetData method returns a task, so you can use the method with the await operator. For example,
you might call the method in the event handler for the click event of a button and use the result to set
the value of a label named lblResult.
The following code example shows how to call an awaitable asynchronous method.
Note that you can only use the await keyword in an asynchronous method.
Additional Reading: For more information about return types for asynchronous methods,
see Async Return Types (C# and Visual Basic) at http://go.microsoft.com/fwlink/?LinkID=267845.
Programming in Visual C# 10-27
7
C
Creating aand Invok
king Callbaack Metho
ods
To configure aan asynchronous method tto invoke a caallback method, you must include a delegate for the
T
c
callback methhod as a param
meter to the aasynchronous method. A caallback metho od typically acccepts one or
m
more argume ents and does not return a value.
v This maakes the Actio
on<T> delegate a good ch hoice to
r
represent a caallback metho
od, where T is the type of your argumentt. If your callb
back method requires
r
m
multiple arguments, there aare versions o
of the Action delegate thatt accept up too 16 type paraameters.
Consider a WPF application
C n that consistss of a button named btnGe etCoffees andd a list namedd lstCoffees.
W
When the use
er clicks the bu
utton, the eve
ent handler invokes an asynnchronous me ethod that rettrieves a list off
c
coffees. When n the asynchroonous data reetrieval is com
mplete, the me
ethod invokes a callback me ethod. The
c
callback methhod removes aany duplicatess from the ressults and thenn displays the updated resuults in the
l
listCoffees lisst.
T following code example shows an asynchronous method that invokes a callback method.
The
I
Invoking a Callback Meth
hod
// This is the click event
e handler for the bu
utton.
private asy
ync void btn
nGetCoffees_Click(object
t sender, Ro
outedEventArgs e)
{
await Ge
etCoffees(Re
emoveDuplicates);
}
// This is the asynchr
ronous method.
public asyn
nc Task GetC
Coffees(Action<IEnumerab
ble<string>>
> callback)
{
// Simul
late a call to a database or a web service.
var coff
fees = await
t Task.Run(() =>
{
va
ar coffeeLis
st = new List<string>();
;
co
offeeList.Ad
dd("Caffe Americano");
co
offeeList.Ad
dd("Caf au Lait");
co
offeeList.Ad
dd("Caf au Lait");
co
offeeList.Ad
dd("Espresso Romano");
co
offeeList.Ad
dd("Latte");
co
offeeList.Ad
dd("Macchiato");
10-28 Improving Application Performance and Responsiveness
return coffeeList;
}
// Invoke the callback method asynchronously.
await Task.Run(() => callback(coffees));
}
// This is the callback method.
private void RemoveDuplicates(IEnumerable<string> coffees)
{
IEnumerable<string> uniqueCoffees = coffees.Distinct();
Dispatcher.BeginInvoke(new Action(() =>
{
lstCoffees.ItemsSource = uniqueCoffees;
}
}
In the previous example, the RemoveDuplicates callback method accepts a single argument of type
IEnumerable<string> and does not return a value. To support this callback method, you add a
parameter of type Action<IEnumerable<string>> to your asynchronous method. When you invoke the
asynchronous method, you supply the name of the callback method as an argument.
W
Working w APM
with M Operatio
ons
Classes that im
C mplement the e APM pattern n use an IAsyn
ncResult insta
ance to represent the statu
us of the
a
asynchronous s operation. The BeginOperationName m method returnns an IAsyncRResult objectt, and the
E
EndOperation nName metho od includes an
n IAsyncResuult parameter.
The Task Paraallel Library makes it easier to work with classes that im
T mplement the
e APM pattern n. Rather than n
i
implementing g a callback mmethod to call the EndOperrationName m method, you caan use the
T
TaskFactory. FromAsync m method to invvoke the operration asynchrronously and return the ressult in a single
e
s
statement. he TaskFactorry.FromAsyncc method includes several overloads to accommodate APM
Th
m
methods that take varying numbers of arguments.
a
Additional Reading: For more information about using the Task Parallel Library with APM
patterns, see TPL and Traditional .NET Asynchronous Programming at
http://go.microsoft.com/fwlink/?LinkID=267847.
Programming in Visual C# 10-31
1
D
Demonstr
ration: Ussing the T
Task Parallel Library
y to Invoke
e APM Op
perations
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA
A-DEV11-10 vvirtual machine.
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Microssoft Visual Studio, on the File menu, po
oint to Open,, and then clicck Project/So
olution.
7
7. In the Op
pen Project dialog box, bro
owse to the E::\Democode\\Starter folde
er, click APMT
Tasks.sln,
and then click Open.
8
8. On the Build menu, click Build Solu
ution.
9
9. On the D
Debug menu, cclick Start Wiithout Debug
gging.
1 Notice th
11. hat the label d
displays the message The URL ng status code: OK.
U returned the followin
1 Close the
12. e MainWindo
ow window.
1 In Solutio
13. on Explorer, exxpand MainW
Window.xamll, and then do ainWindow.x
ouble-click Ma xaml.cs.
1 Review th
14. he code in the
e MainWindo
ow class:
a. Noticce that the bttnCheckUrl_C
Click method creates an HtttpWebReque
est object and
d then calls
the B
BeginGetResp ponse method.
10-32 Improving Application Performance and Responsiveness
18. Add the following code in place of the line you just deleted:
19. Notice that the MainWindow class is now far more simple and concise.
22. Notice that the label displays the message The URL returned the following status code: OK.
23. Notice that the application works in exactly the same way as before.
24. Close the MainWindow window, and then close Visual Studio.
Programming in Visual C# 10-33
3
H
Handling Exception
ns from Aw
waitable M
Methods
C
Catching an A
Awaitable M
Method Excep
ption
private asy
ync void btn
nThrowError_Click(object
t sender, Ro
outedEventArgs e)
{
using (W
WebClient client = new W
WebClient())
)
{
try
{
st
tring data = await client.DownloadS
StringTaskAs
sync("http://contoso/bog
gus");
}
catch
h (WebExcept
tion ex)
{
lb
blResult.Con
ntent = ex.Message;
}
}
}
IIn the previou us example, th he click event handler for a button calls the
t
W
WebClient.D ownloadStringTaskAsyncc method asynchronously b by using the a
await operatoor. The URL
t
that is provide ed is invalid, sso the methodd throws a We ebException exception. Evven though th he operation
i asynchrono
is ous, control returns to the b btnThrowErro or_Click methhod when the asynchronou us operation iss
c
complete andd the exceptio on is handled correctly.
c Thiss works becauuse behind thee scenes, the T
Task Parallel
L
Library is catcching the asyn nchronous excception and re e-throwing it on the UI thre
ead.
U
Unobserved
d Exception
ns
When a task rraises an exception, you can
W n only handle e the exception when the jo oining thread accesses the
t
task, for exam
mple, by using the await op perator or by calling
c the Taask.Wait meth hod. If the join
ning thread
n
never accessees the task, the
e exception w will remain uno observed. Whe en the .NET Frramework garrbage
c
collector (GC)) detects that a task is no lo
onger required d, the task schheduler will th
hrow an excep ption if any
t
task exceptionns remain uno observed. By d default, this exxception is ignored. Howevver, you can im mplement an
e
exception han
ndler of last re
esort by subsccribing to the TaskScheduller.Unobserv vedTaskExcep ption event.
10-34 Improving Application Performance and Responsiveness
Within the exception handler, you can set the status of the exception to Observed to prevent any further
propagation.
If you use a debugger to step through this code, you will see that the UnobservedTaskException event
is fired when the GC runs.
In the .NET Framework 4.5, the .NET runtime ignores unobserved task exceptions by default and allows
your application to continue executing. This contrasts with the default behavior in the .NET Framework
4.0, where the .NET runtime would terminate any processes that throw unobserved task exceptions. You
can revert to the process termination approach by adding a ThrowUnobservedTaskExceptions element
to your application configuration file.
If you set ThrowUnobservedTaskExceptions to true, the .NET runtime will terminate any processes that
contain unobserved task exceptions. A recommended best practice is to set this flag to true during
application development and to remove the flag before you release your code.
Programming in Visual C# 10-35
10-36 Improoving Application Performance and Respponsiveness
Lesson 3
Synch
hronizin
ng Conccurrentt Accesss to Data
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
atements to prevent
Use lock sta p concu
urrent access tto code.
Use synchro
onization prim
mitives to restrict and contrrol access to re
esources.
U
Using Loccks
1
1. Check the
e current stocck level.
2
2. If sufficien
nt stock existss, make the co
offees.
3
3. Subtract tthe number o
of coffees from
m the current stock level.
IIf only one thread can call tthis method aat any one tim
me, everythingg will work fine. However, suppose two
t
threads call th
his method at the same tim
me. The curren nt stock level m
might change e between stepps 1 and 2, orr
b
between steps 2 and 3, making it impossible to keep track of the current stock level and establish whetherr
y have sufficient stock to
you o make a coffe ee.
To solve this p
T problem, you can use the lo
ock keyword to apply a mu utual-exclusio on lock to critiical sections
o code. A mu
of utual-exclusion lock means that if one th
hread is accesssing the critical section, all other threadss
a locked out. To apply a lock, you use the following
are g syntax:
l
lock (object) { statement bllock }
In the previous example, the lock statement ensures that only one thread can enter the critical section of
code within the MakeCoffee method at any one time.
Note: Internally, the lock statement actually uses another Microsoft Visual C# locking
mechanism, the Monitor.Enter and Monitor.Exit methods, to apply a mutual exclusion lock to a
critical section of code. For more information, see lock Statement (C# Reference) at
http://go.microsoft.com/fwlink/?LinkID=267848 and Thread Synchronization (C# and Visual
Basic) at http://go.microsoft.com/fwlink/?LinkID=267849.
Programming in Visual C# 10-39
9
D
Demonstr
ration: Ussing Lock Statemen
nts
2
2. Fulfills the
e order, if the
e current stockk level is sufficcient.
3
3. Subtractss the number of coffees ord
dered from the current stocck level.
IIn the Progra
am class, a Parallel.For loop creates 100 parallel operation places
0 parallel operrations. Each p
a order for b
an between one aand 100 coffe ees at random
m.
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA
A-DEV11-10 vvirtual machine.
3
3. Log on to
o Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Visual Studio, on the
e File menu, p n, and then click Project/Solution.
point to Open
7
7. In the Oppen Project dialog box, bro er, click Locking.sln, and
owse to the E::\Democode\\Starter folde
then clickk Open.
8
8. In Solutio
on Explorer, do
ouble-click Co
offee.cs.
9
9. Review th
he Coffee classs, paying parrticular attentiion to the Ma
akeCoffees m
method.
10-40 Improving Application Performance and Responsiveness
10. Notice how the MakeCoffees method uses a lock statement to prevent concurrent access to the
critical code.
13. Notice how the Main method uses a Parallel.For loop to simultaneously place 100 orders for
between one and 100 coffees.
18. In the Coffee class, comment out the following line of code:
lock (coffeeLock)
20. Notice that the application throws an exception with the message Stock cannot be negative!
21. Explain that this is due to concurrent access to the critical code section in the MakeCoffees method.
U
Using Syn
nchronizattion Primiitives with
h the Task
k Parallel LLibrary
A synchroniza
ation primitivee is a mechanism by which aan operating system enables its users, in n this case the
e
.
.NET runtime, to control the synchronizaation of threadds. The Task P
Parallel Libraryy supports a w
wide range off
s
synchronizatio
on primitives that enable yyou to control access to reso
ources in a vaariety of ways.. These are
t most com
the mmonly used ssynchronizatio on primitives:
Additio
onal Reading: For more infformation abo out the SemaphoreSlim class, see the
SSemaphoreSliim Class page
e at http://go.microsoft.com
m/fwlink/?LinkkID=267851.
10-42 Improving Application Performance and Responsiveness
The CountdownEvent class enables you to block a thread until a fixed number of threads have
signaled the CountdownEvent object. When you create a CountdownEvent object, you specify an
initial integer value. When a thread completes an operation, it can call the Signal method on the
CountdownEvent object to decrement the integer value. Any threads that call the Wait method on
the CountdownEvent object are blocked until the counter reaches zero. For example, if you need to
run ten tasks before you continue with your code, you can create a CountdownEvent object with an
initial value of ten, signal the CountdownEvent object from each task, and wait for the
CountdownEvent object to reach zero before you proceed. This is useful because your code can
dynamically set the initial value of the counter depending on how much work there is to be done.
Additional Reading: For more information about the CountdownEvent class, see the
CountdownEvent Class page at http://go.microsoft.com/fwlink/?LinkID=267852.
The ReaderWriterLockSlim class enables you to restrict write access to a resource to one thread at a
time, while permitting multiple threads to read from the resource simultaneously. If a thread wants to
read the resource, it calls the EnterReadLock method, reads the resource, and then calls the
ExitReadLock method. If a thread wants to write to the resource, it calls the EnterWriteLock
method. If one or more threads have a read lock on the resource, the EnterWriteLock method blocks
until all read locks are released. When the thread has finished writing to the resource, it calls the
ExitWriteLock method. Calls to the EnterReadLock method are blocked until the write lock is
released. As a result, at any one time, a resource can be locked by either one writer or multiple
readers. This type of read/write lock is useful in a wide range of scenarios. For example, a banking
application might permit multiple threads to read an account balance simultaneously, but a thread
that wants to modify the account balance requires an exclusive lock.
Additional Reading: For more information about the ReaderWriterLockSlim class, see
the ReaderWriterLockSlim Class page at http://go.microsoft.com/fwlink/?LinkID=267853.
The Barrier class enables you to temporarily halt the execution of several threads until they have all
reached a particular point. When you create a Barrier object, you specify an initial number of
participants. You can change this number at a later date by calling the AddParticipant and
RemoveParticipant methods. When a thread reaches the synchronization point, it calls the
SignalAndWait method on the Barrier object. This decrements the Barrier counter and also blocks
the calling thread until the counter reaches zero. When the counter reaches zero, all threads are
allowed to continue. The Barrier class is often used in forecasting scenarios, where various tasks
perform interrelated calculations on one time window and then wait for all of the other tasks to reach
the same point before performing interrelated calculations on the next time window.
Additional Reading: For more information about the Barrier class, see the Barrier Class
page at http://go.microsoft.com/fwlink/?LinkID=267854.
Many of these classes enable you to set timeouts in terms of the number of spins. When a thread is
waiting for an event, it spins. The length of time a spin takes depends on the computer that is running the
thread. For example, if you use the ManualResetEventSlim class, you can specify the maximum number
of spins as an argument to the constructor. If a thread is waiting for the ManualResetEventSlim object to
signal and it reaches the maximum number of spins, the thread is suspended and stops using processor
resources. This helps to ensure that waiting tasks do not consume excessive processor time.
Programming in Visual C# 10-43
3
U
Using Con
ncurrent C
Collection
ns
The standard collection classes in the .NET Frameworkk are, by default, not thread-safe. When you access
T
c
collections fro
om tasks or otther multithreeading techniq ques, you musst ensure thatt you do not ccompromise
t integrity o
the of the collectio
ons. One wayy to do this is to
t use the syn
nchronization primitives de escribed
e
earlier in this lesson to control concurren nt access to your collection
ns. However, tthe .NET Frammework also
i
includes a set of collectionss that are specifically designed for thread-safe access.. The following table
d
describes som
me of the classses and interfaaces that the SSystem.Colleections.Concu urrent namesspace
p
provides.
Class or inte
erface Descriptiion
ConcurrentDictionary<TK
Key, TValue> This classs provides a tthread-safe alternative to
the Dicttionary<TKey y, TValue> class.
ConcurrentQ
Queue<T> This classs provides a tthread-safe alternative to
the Que eue<T> class.
IProducerCo
onsumerColle
ection<T> This inte
erface defines methods for
impleme enting classes that exhibit
produce er/consumer behavior;
b in otther words,
classes that distinguissh between prroducers who
add itemms to a collecttion and consu umers who
read item
ms from a collection. This distinction
d is
importan nt because these collection ns need to
impleme ent a read/wriite locking pattern, where
the colle
ection can be locked either by a single
writer orr by multiple readers.
r The
ConcurrrentBag<T>, ConcurrentQ Queue<T>,
and Con ncurrentStack k<T> classes all
impleme ent this interfaace.
10-44 Improving Application Performance and Responsiveness
Consider an order management system for Fourth Coffee that uses a ConcurrentQueue<T> object to
represent the queue of orders that customers have placed. Orders are added to the queue at a single
order point, but they can be picked up by one of three baristas working in the store. The following
example simulates this scenario by creating one task that places an order every 0.25 seconds and three
tasks that pick up orders as they become available.
The following code example shows how to use the ConcurrentQueue<T> class to queue and de-queue
objects in a thread-safe way.
Reference Links: For more information about using concurrent collections, see
System.Collections.Concurrent Namespace at http://go.microsoft.com/fwlink/?LinkID=267855
and Concurrent Collections in the .NET Framework 4 at
http://go.microsoft.com/fwlink/?LinkID=267856.
Programming in Visual C# 10-45
5
Demonstrration: Im
D mproving tthe Respo
onsivenesss and Perfformance of the
A
Applicatio
on
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
10-46 Improoving Application Performance and Respponsiveness
Lab: Im
mproving the Responsivene
ess and Perforrmance of
the Appplicatiion
Sccenario
Yo
ou have been asked to updaate the Grade es application to ensure thaat the UI remaains responsivve while the
use
er is waiting ffor operationss to complete.. To achieve th his improvemment in respon nsiveness, you decide to
convert the logiic that retrievees the list of students
s for a teacher to usse asynchrono ous methods. Y You also
de
ecide to provid de visual feedback to the u user to indicate when an op peration is takking place.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
ync and awaitt keywords to
Use the asy o implement asynchronous
a methods.
Password: Pa$$w0rd
P
Programming in Visual C# 10-47
Next, you will modify the code that retrieves the list of students for a teacher. In this case, you will
configure the code that retrieves the list of students to run asynchronously. When the operation is
complete, your code will invoke a callback method to update the UI with the list of students.
Finally, you will build and test the application and verify that the UI remains responsive while the
application is retrieving data.
The main tasks for this exercise are as follows:
3. Start Visual Studio, and then open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 1
folder.
a. Grades.Web
b. Grades.WPF
8. Notice that the UI briefly freezes while fetching the list of students for Esther Valle (try moving the
application window after logging on but before the list of students appears).
9. Close the application.
X Task 2: Modify the code that retrieves teacher data to run asynchronously
1. In the Grades.WPF project, in the Services folder, open ServiceUtils.cs.
3. In the GetTeacher method, use the await operator to run the LINQ query asynchronously and return
a Task<Teacher> object.
10-48 Improving Application Performance and Responsiveness
4. In the MainWindow class, modify the Refresh method declaration so that the method runs
asynchronously.
5. In the Refresh method, in the case "Teacher" block, modify the call to the GetTeacher method to
run asynchronously.
X Task 3: Modify the code that retrieves and displays the list of students for a teacher
to run asynchronously
1. In the StudentsPage class, modify the Refresh method declaration so that the method runs
asynchronously.
2. In the Refresh method, in the Callbacks region, locate the code that iterates through the returned
set of students and updates the UI.
3. Factor out this code into a new method named OnGetStudentsByTeacherComplete. This method
should:
b. Return void.
4. In the ServiceUtils class, modify the GetStudentsByTeacher method declaration so that it:
a. Runs asynchronously.
5. Modify the GetStudentsByTeacher method so that it returns without passing a value if the call to
IsConnected returns false.
6. In the GetStudentsByTeacher method, use the await operator to run the LINQ query
asynchronously and return a Task<Student> object.
7. Modify the GetStudentsByTeacher method so that it invokes the callback method delegate
asynchronously rather than returning the results.
4. Verify that the application is more responsive than before while fetching the list of students for Esther
Valle.
5. Close the application, and then close the solution.
Results: After completing this exercise, you should have updated the Grades application to retrieve data
asynchronously.
Programming in Visual C# 10-49
10-50 Improving Application Performance and Responsiveness
Next, you will modify the code that retrieves data so that it raises one event when the data retrieval starts
and another event when the data retrieval is complete. You will create handler methods for these events
that toggle the visibility of the progress indicator control, so that the application displays the progress
indicator when data retrieval starts and hides it when data retrieval is complete.
Finally, you will build and test the application and verify that the UI displays the progress indicator while
the application is retrieving data.
2. Start the 20483A-SEA-DEV11-10 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio, and then open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 2
folder.
a. Grades.Web
b. Grades.WPF
Note: It is better to create the user control at the project level and then move it into the
Controls folder when it is created. This ensures that the user control is created in the same
namespace as other project resources.
8. Ensure that the user control does not specify dimensions by deleting the DesignWidth and
DesignHeight properties.
9. In the BusyIndicator.xaml file, modify the existing Grid element to have a background color of
#99000000.
10. In the Grid element, add a Border element with the following characteristics:
c. Set the background to a horizontal linear gradient from light gray to dark gray.
12. In the first row of the Grid element, add a ProgressBar element with the following characteristics:
e. Set the progress bar to provide generic, continuous feedback rather than actual values (hint: use
the IsIndeterminate attribute).
13. In the second row of the Grid element, add a TextBlock element with the following characteristics:
15. In the Grades.WPF project, in the MainWindow.xaml file, add a BusyIndicator element with the
following characteristics:
a. Return void.
3. In the MainWindow class, add a private method named EndBusy. The method should:
a. Return void.
3. Add a method named StartBusyEvent that takes no arguments and returns void.
4. In the StartBusyEvent method, raise the StartBusy event.
5. Add a method named EndBusyEvent that takes no arguments and returns void.
7. In the MainWindow.xaml file, in the StudentsPage element, associate the StartBusy event handler
method with the StartBusy event.
8. In the StudentsPage element, associate the EndBusy event handler method with the EndBusy event.
9. In the StudentsPage class, at the start of the Refresh method, raise the StartBusy event by calling
the StartBusyEvent method.
10. At the end of the Refresh method, raise the EndBusy event by calling the EndBusyEvent method.
Results: After completing this exercise, you should have updated the Grades application to display a
progress indicator while the application is retrieving data.
Programming in Visual C# 10-53
3
Module Rev
view an
nd Take
eaways
M
Module Rev
view
IIn this module
e, you have le
earned a varie
ety of asynchro onous programming techn niques for Visu
ual C#,
i
including how
w to use the Task Parallel Liibrary, how to
o use the asyn
nc and await keywords, andd how to use
s
synchronizatio
on primitives.
T
Test Your Kno
owledge
Question
taskk1.Wait();
taskk2.Wait();
taskk3.Wait();
Taskk.WaitAll(task1
1, task2, task3
3);
T
Test Your Kno
owledge
Question
Question
signature of the asynchronous method be?
public async Task GetCoffees(string country, int strength, out string result)
Question
You want to ensure that no more than five threads can access a resource at any one
time. Which synchronization primitive should you use?
Module 11
Integrating with Unmanaged Code
Contents:
Module Overview 11-2
Modu
ule Ove
erview
Software systemms can be commplex and mayy involve applications that are implemen nted in a varie
ety of
tecchnologies. Fo ome applications may be m
or example, so managed Micrrosoft .NET Framework ap pplications,
whhereas others may be unmaanaged C++ aapplications. Y You may wantt to use functionality from one
pplication in another or use functionality that is exposed through Component Ob
ap bject Model (COM)
asssemblies, such
h as the Micro
osoft Word 144.0 Object Library assemblyy, in your appllications.
Ob
bjectives
Aftter completing this module
e, you will be able to:
Integrate unmanaged co
ode into a Miccrosoft Visual C# applicattion by using the Dynamic Language
Runtime (DDLR).
e lifetime of un
Control the nmanaged ressources and ensure
e that yo
our application
n releases reso
ources.
Programming in
i Visual C# 11-3
3
Lesson 1
Creatting an
nd Using
g Dyna
amic Ob
bjects
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Create a d
dynamic obje
ect.
Invoke methods on a d
dynamic objecct.
11-4 Integratting with Unmanageed Code
W
What Are Dynamic
D O
Objects?
Dy
ynamic Lan
nguages
Languages suchh as IronPythoon and IronRuby are dynammic and enablee you to write
e code that is not
compiled until rrun time. Dynamic languag
ges provide th
he following benefits:
b
They enable
e faster develo
opment cycle
es because the
ey do not requ
uire a build orr compile pro
ocess.
ot have a stron
They do no ngly typed objject model to
o learn.
Un
nmanaged Code
Vissual C# is a managed
m languuage, which m
means that the e Visual C# co
ode you write is executed bby a
runntime environ nment known as the Comm mon Language e Runtime (CLLR). The CLR pprovides otherr benefits,
succh as memoryy managemen nt, Code Access Security (CAAS), and exception handlinng. Unmanage ed code
succh as C++ exe ecutes outside
e the CLR and
d in general be on times and being
enefits from ffaster executio
exttremely flexib
ble.
you just want to use a function in the user32.dll assembly that Windows provides. The process of reusing
functionality that is implemented in technologies other than the .NET Framework is known as
interoperability. These technologies can include:
COM
C++
Microsoft ActiveX
Dynamic objects simplify the code that is required to interoperate with unmanaged code.
Additional Reading: For more information about dynamic objects, see the DynamicObject
Class page at http://go.microsoft.com/fwlink/?LinkID=267857.
11-6 Integratting with Unmanageed Code
W
What Is the
e Dynamicc Languag
ge Runtim
me?
It defers typ
pe-safety checcking for unm
managed resouurces until run
n time. Visual C# is a type-ssafe
language and, by defaultt, the Visual C
C# compiler pe
erforms type--safety checking at compile e time.
The DLR does not provide functionality thaat is pertinentt to a specific language butt provides a set of
lannguage binde ers. A language binder conttains instructio
ons on how to o invoke methhods and marrshal data
beetween the un nmanaged language, such aas IronPython, and the .NET T Framework. The language binders
alsso perform run-time type cchecks, which include checkking that a me given signature actually
ethod with a g
exists in the object.
C
Creating a Dynamicc Object
1
1. In your .N
NET Frameworrk project, add
d a reference to the Microssoft.Office.Inte
erop.Word CO
OM assembly..
2
2. Bring the Microsoft.O
Office.Interop
p.Word name
espace into sco
ope.
D
Dynamic Varriable Declara
ation
using Micro
osoft.Office
e.Interop.Word;
...
dynamic wor
rd = new App
plication();
Additio
onal Reading: For more infformation abo
out the dynam mic keyword, see the Using
g
T
Type dynamicc (C# Program
mming Guide) page at http:://go.microsoft.com/fwlink//?LinkID=267
7859.
11-8 Integratting with Unmanageed Code
In
nvoking M
Methods on a Dynam
mic Objecct
The following co ode example shows how yoou can use the Add metho ument class in the Word
od of the Docu
intterop library tto create a new
w Word docu
ument.
Inv
voking a Metthod on a Dy
ynamic Objecct
/
// Start Microsoft Word.
.
d
dynamic word = new Appli
ication();
...
/
// Create a n
new document
t.
d
dynamic doc = word.Docum
ments.Add();
d
doc.Activate();
Yo
ou can also pa
ass parameterss to dynamic object metho
od calls as you
u would with aany .NET Fram
mework
ob
bject.
ode example shows how yo
The following co ou can pass a string variablle to a method that a dynamic object
exposes.
assing Parameters to a Me
Pa ethod
s
string filePa
ath = "C:\\F
FourthCoffee
e\\Documents\
\\Schedule.d
docx";
...
d
dynamic word = new Appli
ication();
d
dynamic doc = word.Docum
ments.Open(f
filePath);
d
doc.SaveAs(fi
ilePath);
Traaditionally wh
hen consuming a COM asse embly, the .NEET Frameworkk required you u to use the reef keyword
and pass a Type e.Missing objject to satisfy any optional parameters th hat a method contains. Also, any
parameters thatt you pass mu ust be of type object. This ccan result in simple method d calls requirin
ng a long
listt of Type.Misssing objects and code thatt is verbose annd difficult to
o read. By usin
ng the dynam mic
keyyword, you caan invoke the same method ds but with le
ess code.
Programming in Visual C# 11-9
Best Practice: When using dynamic objects in your code to encapsulate classes that are
exposed in COM assemblies, use the Object Browser feature in Microsoft Visual Studio to view
the COM API.
Additional Reading: For more information about how to create and consume dynamic
methods, see the How to: Define and Execute Dynamic Methods page at
http://go.microsoft.com/fwlink/?LinkID=267860.
11-10 Integrrating with Unmanagged Code
Demonstration: Inte
eroperatin
ng with Microsoft W
Word
The application will use the WWord object m model to combine several text files that ccontain excep
ption
infformation into
o an exception n report in Word format. The code uses the Word objject model to add data
om the text files, line breakss, and formattting to generaate the final document.
fro d
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
3. Log on to W
Windows 8 as
a Student with the passwo
ord Pa$$w0rrd.
4. Switch to th
he Windows 8 Start window
w.
5. Click Visual Studio 2012.
6. udio, on the F
In Visual Stu a then clickk Project/Solution.
File menu, point to Open, and
a. Expand
d COM, and th
hen click Type
e Libraries.
b. In the S
Search box, tyype Word.
11. In the Task List window, in the Categories list, click Comments.
12. Double-click the TODO: 01: Bring the Microsoft.Office.Interop.Word namespace into scope. task.
13. In the code editor, click in the blank line below the comment, and then type the following code:
using Microsoft.Office.Interop.Word;
14. Double-click the TODO: 02: Declare a global object to encapsulate Microsoft Word. task.
15. In the code editor, click in the blank line below the comment, and then type the following code:
dynamic _word;
16. Double-click the TODO: 03: Instantiate the _word object. task.
17. In the code editor, click in the blank line below the comment, and then type the following code:
18. Double-click the TODO: 04: Create a blank Word document. task.
19. In the code editor, click in the blank line below the comment, and then type the following code:
this._word.Documents.Add().Activate();
20. In the code editor, look at the following helper methods that wrap the Word COM API:
a. The GetEndOfDocument method places the cursor at the end of the document. The -1 converts
the End property to a 0-based index value. Without the -1, the CLR will throw an
IndexOutOfRange exception.
b. The AppendText method adds text to the end of the document, in the bold and/or italic style.
c. The InsertCarriageReturn method inserts a carriage return at the end of the document.
d. The Save method deletes any file with the same name and then saves the current Word
document.
27. Double-click Exceptions.docx, and then view the combined exception report in the Word document.
Lesson 2
Managing th
he Lifetime of Objectts and Control
C ling
anaged Resourrces
Unma
In this lesson, yo
ou will learn aabout the life cycle of a typical .NET Fram
mework objecct and how to ensure that
obbjects release the
t resources that they havve been using when they are destroyed.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
2
2. It initializes the block o
of memory to the new obje
ect.
1
1. The GC re
eleases resourrces.
2
2. The mem
mory that is allocated to the
e object is recllaimed.
The GC runs aautomatically in a separate thread. When
T n the GC runss, other thread
ds in the appliication are
h
halted, because the GC may move objeccts in memoryy and thereforre must updatte the memorry pointers.
Additio
onal Reading: For more infformation abo
out GC, see th
he Garbage Co
ollection page
e at
http://go.micrrosoft.com/fw
h wlink/?LinkID=
=267861.
11-14 Integrrating with Unmanagged Code
Im
mplementing the Dispose Patttern
Im
mplementin
ng the IDisp
posable Inte
erface
To
o implement the IDisposab
ble interface in
n your applicaation, perform
m the following steps:
using Sys
stem;
...
public cl
lass Managed
dWord : IDisp
posable
{
public
c void Dispo
ose()
{
thr
row new NotI
ImplementedEx
xception();
}
}
public cl
lass Managed
dWord : IDisposable
Programming in Visual C# 11-15
{
bool _isDisposed;
...
}
4. Add code to any public methods in your class to check whether the object has already been disposed
of. If the object has been disposed of, you should throw an ObjectDisposedException.
5. Add an overloaded implementation of the Dispose method that accepts a Boolean parameter. The
overloaded Dispose method should dispose of both managed and unmanaged resources if it was
called directly, in which case you pass a Boolean parameter with the value true. If you pass a Boolean
parameter with the value of false, the Dispose method should only attempt to release unmanaged
resources. You may want to do this if the object has already been disposed of or is about to be
disposed of by the GC.
6. Add code to the parameterless Dispose method to invoke the overloaded Dispose method and then
call the GC.SuppressFinalize method. The GC.SuppressFinalize method instructs the GC that the
resources that the object referenced have already been released and the GC does not need to waste
time running the finalization code.
After you have implemented the IDisposable interface in your class definitions, you can then invoke the
Dispose method on your object to release any resources that the object has consumed. You can invoke
the Dispose method from a destructor that is defined in the class.
Implementing a Destructor
You can add a destructor to a class to perform any additional application-specific cleanup that is
necessary when your class is garbage collected. To define a destructor, you add a tilde (~) followed by the
name of the class. You then enclose the destructor logic in braces.
11-16 Integrating with Unmanaged Code
The following code example shows the syntax for adding a destructor.
Defining a Destructor
class ManagedWord
{
...
// Destructor
~ManagedWord
{
// Destructor logic.
}
}
When you declare a destructor, the compiler automatically converts it to an override of the Finalize
method of the object class. However, you cannot explicitly override the Finalize method; you must
declare a destructor and let the compiler perform the conversion.
If you want to guarantee that the Dispose method is always invoked, you can include it as part of the
finalization process that the GC performs. To do this, you can add a call to the Dispose method in the
destructor of the class.
The following code example shows how to invoke the Dispose method from a destructor.
Additional Reading: For more information about the IDisposable interface, see the
IDisposable Interface page at http://go.microsoft.com/fwlink/?LinkID=267862.
Programming in Visual C# 11-17
7
M
Managing
g the Lifettime of an
n Object
Using types th
U hat implemen nt the IDispossable interface
e is not sufficiient to manag
ge resources. Y
You must
a remembe
also er to invoke thhe Dispose method
m ur code when you have finisshed with the object. If you
in you u
c
choose not to
o implement a destructor th hat invokes th
he Dispose method when tthe GC processses the
o
object, you caan do this in a number of oother ways.
O approach
One h is to explicittly invoke the Dispose metthod after anyy other code tthat uses the o
object.
I
Invoking the
e Dispose Me
ethod
var word = new Managed
dWord();
// Code to
o use the Ma
anagedWord object.
word.Dispos
se();
I
Invoking the
e Dispose Me
ethod in a finally Block
var word = default(MannagedWord);
try
{
word = n
new ManagedW
Word();
// Code to use the ManagedWord object.
}
catch
{
// Code
e to handle any errors.
}
11-18 Integrating with Unmanaged Code
finally
{
if(word!=null)
word.Dispose();
}
Note: When explicitly invoking the Dispose method, it is good practice to check whether
the object is not null beforehand, because you cannot guarantee the state of the object.
Alternatively, you can use a using statement to implicitly invoke the Dispose method. A using block is
exception safe, which means that if the code in the block throws an exception, the runtime will still
dispose of the objects that are specified in the using statement.
The following code example shows how to implicitly dispose of your object by using a using statement.
If your object does not implement the IDisposable interface, a try/finally block is an exception-safe
approach to execute code to release resources. You should aim to use a try/finally block when it is not
possible to use a using statement.
Additional Reading: For more information about using statements, see the using
Statement (C# Reference) page at http://go.microsoft.com/fwlink/?LinkID=267863.
Programming in Visual C# 11-19
9
D
Demonstr
ration: Up
pgrading the Grade
es Report Lab
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
11-20 Integrrating with Unmanagged Code
Lab: U
Upgradiing the
e Grade
es Report
Sccenario
Yo
ou have been asked to upgrade the graddes report functionality to g
generate repoorts in Word fo
ormat. In
Moodule 6, you w
wrote code th
hat generates reports as an XML file; now
w you will upd
date the code to
ge
enerate the report as a Worrd document.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
Use dynamic types.
Password: Pa$$w0rd
P
Programming in Visual C# 11-21
First you will review the existing code in the WordWrapper class that appends headings, text, breaks, and
carriage returns to a document. You will write code to create an instance of Word, create a blank Word
document, save a Word document, and navigate to the end of a document.
You will then write code in the GenerateStudentReport method to create a blank document, add a
heading and grade data to the document, and save the document using the methods that you reviewed
and wrote in the WordWrapper class. You will run this method as a separate task.
Finally, you will build and test the application and verify that the reports are now generated in Word
format.
1. Examine the WordWrapper class that provides a functional wrapper around the dynamic (COM) API for
Word
X Task 1: Examine the WordWrapper class that provides a functional wrapper around
the dynamic (COM) API for Word
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. Start the 20483A-SEA-DEV11-11 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio and open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 1 folder.
a. Grades.Web
b. Grades.WPF
6. In the WordWrapper class, add code to create a dynamic variable named _word for activating Word.
7. In the class constructor, add code to instantiate the _word variable as a new Word Application
object, but ensure that the application is not visible to the user.
8. In the CreateBlankDocument method, add code to create a new Word document and then activate
the new document.
a. Save the active Word document using the file name that is passed to the method.
b. Close the document.
10. In the GetEndOfDocument method, delete the existing return statement and add code to return the
end point of the document as a Range object.
2. In the Utility and Helper methods region, locate the GenerateStudentReport method.
b. Add the heading Grade Report: and the students name to the blank document followed by two
blank lines.
c. Add the details of each grade for that student to the document, including:
Subject name
Assessment
Date
Comment
5. Open Kevin Lius grade report in Word, review the report, and then close Word.
Results: After completing this exercise, the application will generate grade reports in Word
format.
Programming in Visual C# 11-23
You will begin by observing that currently the Word object remains in memory after the application has
generated a report. You will verify this by observing the running tasks in Task Manager.
You will update the code in the WordWrapper class to implement the dispose pattern to ensure correct
termination of the Word instance.
You will then update the code in the GenerateStudentReport method to ensure that the WordWrapper
object is disposed of when the method finishes.
Finally, you will build and test the application and verify that Word now closes after the report is
generated.
1. Run the application to generate a grades report and view the Word task in Task Manager
2. Update the WordWrapper class to terminate Word correctly
3. Wrap the object that generates the Word doc in a using statement
4. Use Task Manager to observe that Word terminates correctly after generating a report
X Task 1: Run the application to generate a grades report and view the Word task in
Task Manager
1. In Visual Studio, open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 2 folder.
a. Grades.Web
b. Grades.WPF
6. Generate a grade report for Kevin Liu, save the report in the E:\Labfiles\Starter\Exercise 2 folder, and
then close the application.
7. Use File Explorer to verify that the report has been generated.
8. Open Task Manager, and then verify that Word is still running.
9. In Task Manager, end the Word task, and then close Task Manager.
2. Modify the definition of the WordWrapper class so that it implements the IDisposable interface.
3. In the WordWrapper class, create a protected virtual void method named Dispose that takes a
Boolean parameter.
b. Check whether the Boolean parameter that is passed to the method is true.
c. Check whether the _word variable is not null.
d. If all of these checks are valid, use the Quit method of the Word object to release the managed
resources.
e. If the _word variable is still not null, use the ReleaseComObject method to release the
unmanaged resources.
7. In the WordWrapper class, create a private Boolean variable named isDisposed and assign a default
value of false.
X Task 3: Wrap the object that generates the Word doc in a using statement
1. In the Grades.WPF project, in the Views folder, open StudentProfile.xaml.cs.
2. In the Utility and Helper methods region, locate the GenerateStudentReport method.
3. Replace the current declaration for the wrapper variable with a using statement that declares the
wrapper object as a var and encloses all of the code in the method.
X Task 4: Use Task Manager to observe that Word terminates correctly after generating
a report
1. Build the solution and resolve any compilation errors.
Results: After completing this exercise, the application will terminate Word correctly after it has
generated a grades report.
Programming in Visual C# 11-25
5
Module Rev
view an
nd Take
eaways
M
Module Rev
view
IIn this modulee, you have leearned how too interoperate
e with COM asssemblies and
d how to ensure that your
o
objects disposse of any reso
ources they co
onsume.
T
Test Your Kno
owledge
Question
It de
efines an obje
ect of type objject and instru
ucts the comp
piler to perforrm type
checcking.
It de
efines a nullab
ble object and
d instructs the
e compiler to defer
d type che
ecking.
It de
efines an obje
ect of type objject and instru
ucts the comp
piler to defer type
t
checcking.
It de
efines a nullab
ble object and
d instructs the
e compiler to perform
p type checking.
V
Verify the correctness of th
he statement b
by placing a m
mark in the co
olumn to the rright.
Statement Answer
Module 12
Creating Reusable Types and Assemblies
Contents:
Module Overview 12-2
Modu
ule Ove
erview
In this module, yyou will learn how to consuume existing aassemblies byy using reflecttion and how to add
additional metaadata to typess and type me embers by usin ng attributes. You will also learn how to generate
code at run time e by using thee Code Documment Object M Model (CodeD DOM) and how w to ensure th
hat your
asssemblies are ssigned and veersioned, and available to o
other applicatiions, by using the global asssembly
cacche (GAC).
Ob
bjectives
Aftter completing this module
e, you will be able to:
on to inspect and execute assemblies.
Use reflectio
Generate m
managed code
e at run time b
by using Code
eDOM.
Version, sign, and deployy your assemb
blies to the GA
AC.
Programming in
i Visual C# 12-3
3
Lesson 1
Exam
mining O
Object Metadata
SSometimes ap pplications ne
eed to load ann existing com
mpiled assemb bly, view its co
ontents, and exxecute
f
functionality. For example, a unit testing
g utility may re
equire the ability to obtain a reference tto a type and
e
execute somee of the publicc methods thaat it exposes. R
Reflection pro
ovides a way ffor you to exaamine the
t
types in a com
mpiled assemb bly.
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Load an aassembly.
Examine tthe metadata of an existing
g type.
Invoke th
he members th
hat an assemb
bly exposes.
12-4 Creatingg Reusable Types annd Assemblies
W
What Is Refflection?
Re
eflection is a p
powerful featu
ure that enables you to insp
pect and perfo
orm dynamic manipulation
n of
asssemblies, type
es, and type m
members at ruun time.
Re
eflection is use
ed throughout the Microso oft .NET Frammework. Refle ection is used by some of thhe classes
tha
at the base cla
ass library pro
ovides and som me of the utilities that ship
p with Microsooft Visual Stud
dio. For
exaample, the serialization classes in the Sy
ystem.Runtim me.Serializatio on namespace use reflectio on to
etermine which type memb
de bers should bee serialized wh
hen serializingg types.
Re
eflection Ussage Scenarios
The following taable describess some of the possible usess for reflection
n in your applications.
U
Use Scenario
Examining me
E etadata and You might
m choose to do this if you
y are consuming an unkn nown
d
dependencies
s of an assemb
bly. assem
mbly in your application and d you want to
o determine w
whether
your aapplication sa
atisfies the unknown assem
mblys dependeencies.
Determining whether
D w a typ
pe You might
m choose to do this if you
y are creatin ng a pluggable
i
implements a specific appliccation that en nables you to include new aassemblies at run time,
i
interface. but yoou only want your applicattion to load tyypes that implement a
speciffic interface.
Exe
ecuting code by using refleection is margginally slower than executin
ng static Micro
osoft Visual C# code,
so you should o
only use reflecction to create
e and executee code when yyou really havee to and not jjust
be
ecause reflection makes it p
possible.
Programming in Visual C# 12-5
Assembly. This class enables you to load and inspect the metadata and types in a physical assembly.
ConstructorInfo. This class enables you to inspect the constructor of the type.
FieldInfo. This class enables you to inspect the characteristics of fields that are defined within a type.
MemberInfo. This class enables you to inspect members that a type exposes.
PropertyInfo. This class enables you to inspect the characteristics of properties that are defined
within a type.
MethodInfo. This class enables you to inspect the characteristics of the methods that are defined
within a type.
The System namespace includes the Type class, which also exposes a selection of members that you will
find useful when you use reflection. For example, the GetFields instance method enables you to get a list
of FieldInfo objects, representing the fields that are defined within a type.
Additional Reading: For more information about the Type class, see the Type Class page
at http://go.microsoft.com/fwlink/?LinkID=267864.
Additional Reading: For more information about reflection in the .NET Framework class,
see the Reflection in the .NET Framework page at
http://go.microsoft.com/fwlink/?LinkID=267865.
12-6 Creatingg Reusable Types annd Assemblies
Lo
oading Asssemblies by Using Reflection
n
The Assembly cclass providess a number off static and insstance membeers that you ccan use to load
d and
exaamine the con
ntents of asseemblies. There
e are two wayss that you can
n load an asseembly into youur
ap
pplication by using
u reflectio
on:
Reflection-o
only context, in which you can view the metadata thaat is associated
d with the asssembly and
not executee code.
To
o load an assem
mbly, the Asssembly class p hich include the
provides a number of staticc methods, wh
folllowing:
LoadFrom.. This method enables you to load an asssembly in exeecution contexxt by using an
n absolute
file path to the assemblyy. The followin
ng code example shows how
w to load the
FourthCofffee.Service.Ex xceptionHan ndling assemb
bly.
var assem
mblyPath =
"C:\\F
FourthCoffee
e\\Libs\\FourthCoffee.Se
ervice.Excep
ptionHandling
g.dll";
var assem
mbly = Assem
mbly.LoadFrom
m(assemblyPa
ath);
ReflectionO OnlyLoad. Thhis method ennables you to load an assemmbly in reflecttion-only conttext from a
binary large
e object (BLOB) that repressents the assem
mbly. The following code example
e show
ws how to
load the FoourthCoffee.SService.Excep ptionHandlin ng assembly frrom a byte array.
var assem
mblyPath =
"C:\\F
FourthCoffee
e\\Libs\\FourthCoffee.Se
ervice.ExcepptionHandling
g.dll";
var rawBy
ytes = File.ReadAllBytes(assemblyPa
ath);
var assem
mbly = Assem
mbly.ReflectionOnlyLoad(
(rawBytes);
var assemblyPath =
"C:\\FourthCoffee\\Libs\\FourthCoffee.Service.ExceptionHandling.dll";
var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
After you have loaded an assembly and have created an instance of the Assembly class, you can use any
of the instance members to examine the contents of the assembly. The following list describes some of
the instance members that the Assembly class provides:
FullName. This property enables you to get the full name of the assembly, which includes the
assembly version and public key token. The following code example shows the full name of the File
class in the System.IO namespace.
GetReferencedAssemblies. This method enables you to get a list of all of the names of any
assemblies that the loaded assembly references.
GlobalAssemblyCache. This property enables you to determine whether the assembly was loaded
from the GAC.
Location. This property enables you to get the absolute path to the assembly.
ReflectionOnly. This property enables you to determine whether the assembly was loaded in a
reflection-only context or in an execution context. If you load an assembly in reflection-only context,
you can only examine the code.
GetType. This method enables you to get an instance of the Type class that encapsulates a specific
type in an assembly, based on the name of the type.
GetTypes. This method enables you to get all of the types in an assembly in an array of type Type.
Additional Reading: For more information about the Assembly class, see the Assembly
Class page at http://go.microsoft.com/fwlink/?LinkID=267866.
12-8 Creatingg Reusable Types annd Assemblies
Re
eflection enables you to exaamine the deffinition of anyy type in an asssembly. Depe
ending on whether you
are
e looking for a type with a specific name
e or you want to iterate thrrough each tyype in the asse
embly in
seq
quence, you ccan use the GeetType and G GetTypes metthods that the e Assembly class provides.
The following co
ode example shows how to o load a type by using the GetType
G metthod, passing the fully
qu
ualified name of the type ass a parameterr to the metho
od call.
Lo
oad a Type by
y Using the G
GetType Meth
hod
v
var assembly = FourthCof
ffeeServices
s.GetAssembly
y();
...
v
var type = as
ssembly.GetT
Type("Fourth
hCoffee.Servi
ice.Exceptio
onHandling.H
HandleError")
);
The following co
ode example shows how to
o iterate throu
ugh each of th
he types in an
n assembly by using the
Ge
etTypes meth hod. The GetT
Types methodd returns an array of Type o
objects.
Ite
erate All Type
es in an Asse
embly by Usin
ng the GetTy
ypes Method
v
var assembly = FourthCofffeeServices
s.GetAssembly
y();
...
f
foreach (var type in asssembly.GetTy
ypes())
{
// Code to
o process ea
ach type.
var typeNa
ame = type.F
FullName;
}
GetFields. This method enables you to get all of the fields that exist in the current type. The
GetFields method returns an array that contains FieldInfo objects. The following code example
shows how to iterate through each field in a type and then determine whether the field is static or
instance by using the IsStatic property that the FieldInfo class provides.
GetProperties. This method enables you to get all of the properties that exist in the current type. The
GetProperties method returns an array that contains PropertyInfo objects. The following code
example shows how to iterate through each property and then get the propertys name.
GetMethods. This method enables you to get all of the methods that exist in the current type. The
GetMethods method returns an array that contains MethodInfo objects. The following code
example shows how to iterate through each method and then get the methods name.
GetMembers. This method enables you to get any members that exist in the current type, including
properties and methods. The GetMembers method returns an array that contains MemberInfo
objects. The following code example shows how to iterate through each member and then determine
whether the member is a property or method.
You can use these members to get a collection of xxxxInfo objects that represents the different members
that a type exposes. If you loaded the type in execution context, you can then use the xxxxInfo objects to
execute each member.
Additional Reading: For more information about the Type class, see the Type Class page
at http://go.microsoft.com/fwlink/?LinkID=267864.
Programming in Visual C# 12-11
1
I
Invoking Members by Using Reflectio
on
The reflection
T n application p
programming g interface (AP
PI) in the .NET
T Framework e enables you to o invoke
o
objects and use the functio
onality that they encapsulatte. Invoking an object by using reflection n follows the
s
same pattern that you use to invoke an object in Visuual C#, which ttypically invollves the follow
wing steps:
1
1. Create an
n instance of tthe type.
2
2. Invoke methods on the
e instance.
3
3. Get or sett property vallues on the instance.
When you invvoke static me
W embers by using reflection, there is no ne
eed to explicitly create an instance
i of
t type.
the
I
Instantiatin
ng a Type
To create an instance of a ttype by using reflection, yo
T ou need to get a reference to a constructtor that the
t
type exposes and then use the Invoke m method. To instantiate a typpe by using th
he Constructo orInfo class,
p
perform the fo
ollowing step
ps:
1
1. Create an uctor you will use to
n instance of tthe ConstructtorInfo class tthat represents the constru
initialize an
a instance off the type. The
e following co
ode example sshows how to o initialize an o
object by
using the e default consttructor.
var typ
pe = FourthCoffeeService
es.GetHandle
eErrorType();
...
var con
nstructor = type.GetCons
structor(new
w Type[0]);
2
2. Call the In
nvoke metho od on the ConnstructorInfoo object to inittialize an instaance of the tyype, passing
an objectt array that represents any parameters thhat the constrructor call exppects. The follo owing code
example shows how to o invoke the d
default constru
uctor.
12-12 Creating Reusable Types and Assemblies
You now have an instance of the type that you can use to invoke any instance methods that are defined in
the type.
Invoking Methods
To invoke an instance method, perform the following steps:
1. Create an instance of the MethodInfo class that represents the method you want to invoke. The
following code example shows how to get a method named LogError.
2. Call the Invoke method on the MethodInfo object, passing the initialized object and an object array
that represents any parameters that the method call expects. You can then cast the return value of
the Invoke method to the type of value you were expecting from the method call. The following
code example shows how to execute the LogError instance method that accepts a string parameter
and returns a string value.
When you invoke static methods, there is no need to create an instance of the type. Instead, you just
create an instance of the MethodInfo class that represents the method you want to invoke and then call
the Invoke method. To invoke a static method, perform the following steps:
1. Create an instance of the MethodInfo class that represents the method you want to invoke. The
following code example shows how to get a method named FlushLog.
2. Call the Invoke method on the MethodInfo object, passing a null value to satisfy the initialized
object and an object array that represents any parameters that the method call expects. The following
code example shows how to execute the FlushLog static method that accepts no parameters and
returns a Boolean value.
1. Create an instance of the PropertyInfo class that represents the property you want to get or set. The
following code example shows how to get a property named LastErrorMessage.
2. If you want to get the value of a property, you must invoke the GetValue method on the
PropertyInfo object. The GetValue method accepts an instance of the type as a parameter. The
following code example shows how to get the value of the LastErrorMessage property.
Programming in Visual C# 12-13
3. If you want to set the value of a property, you must invoke SetValue method on the PropertyInfo
object. The SetValue method accepts an instance of the type and the value you want to set the
property to as parameters. The following code example shows how to set the LastErrorMessage
property to the text Database connection error.
When you get or set a static property, there is no need to create an instance of the type. Instead, you just
create an instance of the PropertyInfo class and then call either the GetValue or SetValue method. To
get or set the value of a static property, perform the following steps:
1. Create an instance of the PropertyInfo class that represents the property you want to get or set. The
following code example shows how to get a property named LastErrorMessage.
2. If you want to get the value of a property, you must invoke the GetValue method on the
PropertyInfo object, passing a null value to satisfy the initialized object parameter. The following
code example shows how to get the value of the LastErrorMessage static property.
3. If you want to set the value of a property, you must invoke the SetValue method on the
PropertyInfo object, passing a null value to satisfy the initialized object parameter, and the value
you want to set the property too. The following code example shows how to set the
LastErrorMessage static property to the text Database connection error.
Demonstration: Insp
pecting Asssemblies
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
6. udio, on the F
In Visual Stu a then clickk Project/Solution.
File menu, point to Open, and
0. In Visual Stu
10 View menu, click Task List.
udio, on the V
using System.Reflecti
ion;
15. In the code editor, click in the blank line below the comment, and then type the following code:
return Assembly.ReflectionOnlyLoadFrom(path);
16. In the Task List window, double-click the TODO: 03: Get all the types from the current assembly. task.
17. In the code editor, click in the blank line below the comment, and then type the following code:
return assembly.GetTypes();
18. In the Task List window, double-click the TODO: 04: Get a specific type from the current assembly.
task.
19. In the code editor, click in the blank line below the comment, and then type the following code:
return assembly.GetType(typeName);
20. In the code editor, locate the RenderMethods method, and then review the use of the IsPublic,
IsStatic, ReturnType, and Name properties of the MethodInfo class.
21. Locate the RenderProperties method, and then review the use of the DeclaringType and Name
properties of the PropertyInfo class.
24. In the Fourth Coffee Type Inspector application, click Load Assembly.
26. In the Types list, click FourthCoffee.Core.Encryptor, and then click Inspect Type. The Members list
now shows all of the methods that the type exposes.
Lesson 2
Creatiing and
d Using Custom
m Attributes
In this lesson, yo
ou will learn h
how to create your own cusstom attribute
es and read th
he metadata tthat is
encapsulated in n custom attribbutes at run time by using reflection.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
W
What Are Attribute
es?
Attributes pro
A ovide a mechaanism that usees the declaraative programming model tto include add ditional
m
metadata abo
out elements, such as typess, properties, aand methods, in your application. Your aapplication
c use the ad
can ovide to control application
dditional information that attributes pro n behavior and d how data is
p
processed r time. You can also use the information that attrib
at run butes encapsulate in case toools and
o
other development process, such as unit test frrameworks.
utilities that aid the d
The Obso
olete attribute
e in the Syste
em namespace e, which you ccan use to ind
dicate that a ttype or a type
e
member has been supe erseded and isi only there tto ensure backkward compatibility.
The Seria
alizable attrib
bute in the Sysstem namesppace, which yo ou can use to indicate that an
IFormattter implementtation can serrialize and desserialize a type.
The NonS Serialized atttribute in the System nameespace, whichh you can use to indicate th
hat an
IFormattter implementtation should not serialize or deserialize a member in a type.
The ConffigurationPro
operty attribu
ute in the Systtem.Configuration namesspace, which you
y can use
to map a property mem
mber to a secction in an app
plication conffiguration file.
A
Applying A
Attributes
T use an attrribute in your code, perform
To m the followin
ng steps:
1
1. Bring the namespace tthat contains tthe attribute you
y want to use
u into scope
e.
2
2. Apply the
e attribute to the code elem
ment, satisfyin
ng any parame
eters that the constructor e
expects.
3
3. Optionally set any of the named parameters thatt the attribute exposes.
12-18 Creating Reusable Types and Assemblies
The following code example shows how to apply the DataContract attribute to the SalesPerson class
definition and set the Name and IsReference named parameters.
You can apply multiple attributes to a single element to create a hierarchy of metadata that describes the
element.
The following code example shows how to apply the Obsolete and DataMember attributes to the Name
property in the SalesPerson class, to indicate that the property should be serialized but will be removed
from the type definition in the next release.
Additional Reading: For more information about the Attribute class, see the Attribute
Class page at http://go.microsoft.com/fwlink/?LinkID=267867.
Programming in Visual C# 12-19
9
C
Creating aand Using
g Custom A
Attributess
1
1. Create a ttype that deriives from the Attribute base class or ano
other existing
g attribute typ
pe.
2
2. Apply thee AttributeUssage attribute
e to your custom attribute class to describe which elements you
can applyy this attribute
e to.
n attribute to an element th
Note: Iff you apply an with the value of the
hat conflicts w
AttributeUsa
A age attribute, the compiler will throw an error at buildd time.
3
3. Define a cconstructor to
o initialize the
e custom attrib
bute.
4
4. Define anny properties tthat you wantt to enable ussers of the attribute to optionally provide
e
information. Any properties that you u define that have a get acccessor will bee exposed throough the
attribute as a named pparameter.
The code exam
T mple shows h
how to create an attribute tthat encapsulaates metadataa about the de
eveloper who
o
c
creates the ele
ement.
C
Creating a Cu
ustom Attrib
bute
[Attribute
eUsage(AttributeTargets.All)]
public clas
ss Developer
rInfo : Attribute
{
private string _ema
ailAddress;
private int _revision;
public D
DeveloperInf
fo(string emailAddress, int revisio
on)
{
this.
._emailAddre
ess = emailAddress;
this.
._revision = revision;
}
12-20 Creating Reusable Types and Assemblies
Using a custom attribute is no different from using an attribute that the .NET Framework provides. You
simply apply the attribute to an element and ensure that you pass the required information to the
constructor.
The following code example shows how to apply the DeveloperInfo attribute to a type definition.
Additional Reading: For more information about how to create custom attributes, see the
Creating Custom Attributes (C# and Visual Basic) page at
http://go.microsoft.com/fwlink/?LinkID=267868.
Programming in Visual C# 12-21
1
P
Processing
g Attributtes by Using Reflecttion
IIf you use thee existing attributes that thee .NET Framewwork providess, they normally have a purrpose other
t
than just to exxist in your co
ode. For exammple, the IForm
matter serializzers use the S
Serializable atttribute
d
during the serrializing and ddeserializing p
processes.
SSimilarly, you can use attrib
butes to encap
psulate metad
data about ann element in yyour code. Forr example, if
y create an attribute that provides infformation abo
you out the develo
oper who auth hored the elem ment, you
m want a way
may w to extract this informatiion so that yo
ou can producce a documen nt listing all off the
d
developers wh
ho were involved in develooping the application.
SSimilar to acce
essing other ttype and mem
mber informattion, you can aalso use reflecction to proce
ess attributes.
T System.R
The Reflection namespace provvides a collecttion of extenssion methods that you can use to access
a
attributes and
d the metadatta they encapssulate. The following list de
escribes some
e of these metthods:
GetCusto omAttribute. This method enables you to get a speciific attribute tthat was used on an
element. The following
g code examp
ple shows howw to get a DevveloperInfo attribute
a that has been
applied to
o a type.
var typ
pe = FourthCoffeeService
es.GetHandle
eErrorType();
var get
tInheritedAttributes = f
false;
var att
tribute =
type
e.GetCustomA
Attribute(typ
peof(Develop
perInfo), getInheritedAt
ttributes);
Note: T
The getInheriteedAttributes p
parameter insttructs the GettCustomAttriibute method d call
t return eithe
to er only attribu
utes that havee been explicittly applied to the current tyype, or attribu
utes
t
that have bee
en either explicitly applied o
or inherited frrom any paren nt type.
GetCusto omAttribute. This generic method also enables you tto get a speciffic attribute thhat was used
on an ele ement. This is a generic metthod, so you ccan specify th
he type of attribute you wan
nt the
GetCusto omAttribute method to re eturn. This me
eans that you ddo not have tto write conditional logic
to filter an array of objjects to determ
mine the type
e of an attribu
ute and perforrm any casting
g. The
following g code example shows how w to get a Dev
veloperInfo attribute that hhas been applied to a type..
var typ
pe = FourthCoffeeService
es.GetHandle
eErrorType();
var get
tInheritedAttributes = f
false;
12-22 Creating Reusable Types and Assemblies
GetCustomAttributes. This method enables you to get a list of specific attributes that were used on
an element. Typically, you would use this method if more than one attribute of the same type has
been applied to an element, in which case this method call would return all instances. The following
code example shows how to get all of the DeveloperInfo attributes that were applied to a type.
GetCustomAttributes. This generic method enables you to get a list of specific attributes that were
used on an element. Similar to the GetCustomAttribute generic method, because this is a generic
method, the method call will only return attributes that match the generic type. The following code
example shows how to get all of the DeveloperInfo attributes that were applied to a type.
The following code example shows how to iterate through each of the custom attributes that have been
applied to a type definition and then access the data that any DeveloperInfo attributes encapsulate.
Note: The false value that is passed to the GetCustomAttributes method instructs the
method to only get custom attributes that have been explicitly applied to the current type, not
attributes that have been inherited.
To access custom attributes that have been applied to a member, you must create an xxxxInfo object that
represents the member and then invoke the GetCustomAttributes method.
The following code example shows how to iterate through each of the custom attributes that have been
applied to a method called GetAllSales and then access the data that any DeveloperInfo attributes have
encapsulated.
Additional Reading: For more information about how to process custom attributes, see
the Accessing Custom Attributes page at http://go.microsoft.com/fwlink/?LinkID=267869.
12-24 Creating Reusable Types and Assemblies
Demonstration: Con
nsuming C
Custom Atttributes by
b Using R
Reflection
n
In this demonstration, you wiill use reflectio e DeveloperInfo attributess that have be
on to read the een used to
pro
ovide addition
nal metadata on types and type membe ers.
The application uses the GetCCustomAttribute generic method that the Type and d MemberInffo classes
pro
ovide to extra
act any additio
onal information that a cusstom Develop
perInfo attribute encapsulaates.
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
2. 0483A-SEA-DEEV11-12 virtual machine.
Start the 20
3. Log on to W
Windows 8 as Student with
h the password Pa$$w0rd.
9. In Visual Stu
udio, on the V
View menu, click Task List.
0. In the Task
10 k List window,, in the Categ
gories list, click Commentss.
11. Double-clicck the TODO: 01: Invoke the
e Type.GetCustomAttribute
e method. tassk.
var typeAttribute = t
type.GetCust
tomAttribute<
<DeveloperIn
nfo>(false);
14. In the code editor, click in the blank line below the comment, and then type the following code:
17. In the Fourth Coffee Metadata Extractor application, click Load. The list box now contains a list of all
of the members in the Encryptor type and the details from any DeveloperInfo attributes that were
found.
Lesson 3
Generrating M
Manage
ed Code
Yoou can use Visual Studio to write manage ed code whenn you have cleearly defined requirements
r upon
whhich to base your implemen ntation. Howe ever, sometim
mes you may w want to generaate code at ru
un time
based on a varyying set of req quirements. In this scenario,, you need a framework
f that enables you to define
insstructions thatt a process can translate into executable
e code. The .NNET Frameworrk provides the
CoodeDOM featu ure for this ve
ery purpose.
In this lesson, yo how to generaate managed code at run tiime by using CodeDOM.
ou will learn h
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
pe by using CodeDOM.
Define a typ
Compile a C
CodeDOM mo
odel into sourrce code files.
W
What Is CodeDOM?
CodeDOM is a feature of th
C he .NET Frameework that ennables you to generate codde at run time. CodeDOM
e
enables you to del that represents the source code that you want to ccreate and then generate
o build a mod
t source code by using o
the one of the cod
de generators that are inclu
uded in CodeD DOM. By defa ault,
C
CodeDOM inccludes code g
generators for Visual C#, Microsoft Visual Basic, and Microsoft JSccript.
Microsofft.CSharp.CSh
harpCodePro
ovider. This naamespace con
ntains the Visu
ual C# code compiler
c and
generator.
Microsofft.JScript.JScriptCodeProv
vider. This naamespace con
ntains the JScrript code compiler and
generator.
Microsofft.VisualBasicc.VBCodePro
ovider. This naamespace con
ntains the Visu
ual Basic code
e compiler
and gene
erator.
Class Description
CodeNamespace Enables yo
ou to define a namespace tthat you can
12-28 Creating Reusable Types and Assemblies
Class Description
use to organize your class hierarchy.
After you have defined your model by using the classes in the System.CodeDom namespace, you can
then use a code generator provider, such as the CSharpCodeProvider class in the
Microsoft.CSharp.CSharpCodeProvider namespace, to compile your model and generate your code.
Additional Reading: For more information about CodeDOM, see the Dynamic Source
Code Generation and Compilation page at http://go.microsoft.com/fwlink/?LinkID=267870.
Programming in Visual C# 12-29
12-30 Creating Reusable Types and Assemblies
De
efining a type by using Cod deDOM follow ws the same pattern as defining a type in n native Visual C#. The
on
nly difference is that when u using CodeDOOM, you writee a set of instrructions that a code generaator
pro
ovider will intterpret to gen
nerate the source code thatt represents yoour model.
The System.Cod deDOM namespace includ des the types that
t you can use
u to write th
hese instructio
ons. The
folllowing steps describe how
w to use some of the System
m.CodeDOM types to define a type thatt contains
an entry point method
m nameed Main:
1. Create a Co
odeCompileU e assembly that will contain
Unit object to represent the n the type. The following
code exampple shows how
w to create a C
CodeCompile eUnit object.
2. Create a Co
odeNamespace object to rrepresent the namespace th hat the type w
will be scoped
d to and
add the nammespace to th
he CodeComp pileUnit obje
ect. The follow
wing code example shows h how to
define the F
FourthCoffeee.Dynamic naamespace.
var dynam
micNamespace
e = new CodeNamespace("F
FourthCoffee
e.Dynamic");
unit.Name
espaces.Add(
(dynamicNamespace);
dynamicNa
amespace.Imp
ports.Add(new
w CodeNamesp
paceImport("
"System"));
4. Create a Co
odeTypeDeclaration objecct that represe
ents the type you want to aadd to the namespace.
The followin
ng code exam
mple shows ho
ow to create a type named Program.
var progr
ramType = ne
ew CodeTypeDeclaration("
"Program");
dynamicNa
amespace.Typ
pes.Add(programType);
5. Create a Co
odeEntryPoinntMethod objject to represent the static main method
d in the Progrram type.
The followin
ng code exam
mple shows ho
ow to define aan entry pointt method nam
med Main and d add it to
the Program type.
var mainM
Method = new
w CodeEntryPo
ointMethod()
);
Programming in Visual C# 12-31
programType.Members.Add(mainMethod);
After you have defined your model, you can then use a code generator provider to compile and generate
your code.
Additional Reading: For more information about how to define a model by using
CodeDOM, see the Using the CodeDOM page at http://go.microsoft.com/fwlink/?LinkID=267871.
12-32 Creating Reusable Types and Assemblies
Co
ompiling a CodeDO
OM Mode
el
Co
ompiling a Model into
o a Source C
Code File
To
o compile your model and g
generate sourrce code files, perform the following step
ps:
1. nstance of the
Create an in e code generaator provider yyou want to u
use. The follow
wing code exaample
shows how to create an instance
i of th
he CSharpCod deProvider class that will pproduce Visuaal C# code.
var provi
ider = new C
CSharpCodePro
ovider();
2. Create a StrreamWriter o
object that the code generrator will use tto write the co
ompiled code
e to a file.
The followin
ng code exam
mple shows ho ow to create a StreamWritter object.
var fileN
Name = "prog
gram.cs";
var strea
am = new Str
reamWriter(fileName);
3. Create an In
ndentedTexttWriter objecct that will writte the indente
ed source cod
de to a file. Th
he following
code examp ple shows how
w to create an
n IndentedTe extWriter object.
var textW
Writer = new
w IndentedTex
xtWriter(str
ream);
4. Create a Co
odeGeneratorOptions object that encappsulates your code generattion settings. The
ode example shows how to
following co o create a Cod
deGeneratorO Options obje
ect and set the e
BlankLinessBetweenMem mbers property so that meembers are se
eparated by a blank line.
var opti
ions = new C
CodeGeneratorOptions();
options.
.BlankLinesB
BetweenMembers = true;
Programming in Visual C# 12-33
6. Close the IndentedTextWriter and StreamWriter objects. The following code example shows how
to close the IndentedTextWriter and StreamWriter objects, flushing the compiled code to the
output file.
textWriter.Close();
stream.Close();
After you have executed the code to compile your model, you will have a source .cs file that contains the
compiled Visual C# code.
The following code example shows the compiled Visual C# code for a model that contains the Program
type with an entry point method called Main.
Co
ompiling Source Co
ode into aan Assemb
bly
To
o generate an executable asssembly that ccontains the F
FourthCoffee
e.Dynamic.Prrogram type from
f a
source code file
e, perform the
e following ste
eps:
1. Create an in
nstance of the
e code generaator provider yyou want to u
use. The follow
wing code exaample
shows how to create an instance
i of th
he CSharpCod deProvider class that will pproduce the executable
assembly.
var provi
ider = new C
CSharpCodePro
ovider();
2. Create a Co
ompilerParam meters objectt that you will use to define
e the settings for the compiler, such as
which assemmblies to reference, and whhether to generate a .dll orr an .exe file. The
T following code
example shows how to create a Comp pilerParameters object, ad dd a reference e to the System
m.dll file,
and instructt the compiler to generate an executable file named FourthCoffee..exe.
var compi
ilerSettings
s = new CompilerParamete
ers();
compilerS
Settings.Ref
ferencedAssem
mblies.Add("
"System.dll"");
compilerS
Settings.Gen
nerateExecutable = true;
;
compilerS
Settings.Out
tputAssembly = "FourthCo
offee.exe";
3. Invoke the CompileAsse emblyFromFiile method onn the CSharpC CodeProvide er object to ge
enerate the
assembly. T
The following code example
e shows how tto invoke the CompileAssemblyFromF File
method, paassing the Com a a string vvariable that contains the path to the
mpilerParameters object and
source codee file.
var sourc
ceCodeFileNa
ame = "program.cs";
var compi
ilationResults = provider.CompileAs
ssemblyFromF
File(
compil
lerSettings,
source
eCodeFileNam
me);
4. You can then use the properties that the CompilerResults object provides to determine whether the
compilation was successful. The following code example shows how to iterate the
CompilationErrorCollection object by using the Errors property.
You have now generated an assembly that displays the message Hello Development Team..!! when it is
executed.
Additional Reading: For more information about how to compile a CodeDOM model, see
the Generating and Compiling Source Code from a CodeDOM Graph page at
http://go.microsoft.com/fwlink/?LinkID=267872.
12-36 Creating Reusable Types and Assemblies
Lesson 4
Versio
oning, S
Signing
g, and Deployi
D ng Assemblies
Wh hen you finish h developing an applicationn, you should sign and verssion the assem
mbly before yo ou
disstribute it to u
users. You must also consid
der how and wwhere the asseembly is goingg to be installed.
In this lesson, yo
ou will learn h
how to version
n assemblies aand install an assembly into
o the GAC.
Le
esson Obje
ectives
Aftter completing this lesson, you will be ab
ble to:
W
What Is an
n Assemb
bly?
An assembly iis a collection of types and resources thaat form a unit of functionality. An assembly might
A
c
consist of a single portable PE) file, such aas an executable (.exe) prog
e executable (P gram or dynamic link
l
library (.dll) fille, or it might consist of mu
ultiple PE filess and external resource filess, such as bitm
maps or data
f
files. An assem mbly is the building block of o a .NET Fram mework appliccation because e an application consists off
o or more aassemblies.
one
C
Contents of Assemblie
es
A assembly cconsists of the
An e following co
omponents:
The assem
mbly manifestt. This contains assembly metadata and p provides inforrmation aboutt the
assembly such as the title, the descrription, and ve ersion informaation. The manifest also contains
information about linkks to the otherr files in the assembly. The information in the manifesst is used at
run time to resolve references and vvalidate loade ed assemblies.. The assemblyy manifest cann be stored in
n
a separate file but is offten part of on
ne of the PE ffiles.
B
Boundaries
s of Assemb
blies
By arranging yyour code intto assemblies, you create a set of boundaries that you
B u can use to issolate
c
configuration to a particulaar assembly. T
The following list describes some of the boundaries
b th
hat assembliess
p
provide:
Security boundary.
b You
u set security permissions
p at an assemblyy level. You ca
an use these ppermissions to
o
request specific access for an application, for example, file I/O permissions if the applicattion must
write to a disk. When tthe assembly iis loaded at ru
un time, the permissions
p th
hat are requessted are
entered innto the securiity policy and used to determine whethe er permissionss can be grantted.
12-38 Creating Reusable Types and Assemblies
Type boundary. An assembly provides a boundary for data types, because each type has the assembly
name as part of its identity. As a result, two types can have the same name in different assemblies
without any conflict.
Reference scope boundary. An assembly provides a reference scope boundary by using the assembly
manifest to resolve type and resource requests. This metadata specifies which types and resources are
exposed outside the assembly.
Benefits of Assemblies
Assemblies provide you with the following benefits:
Single units of deployment. The client application loads assemblies when it needs them, which enables
a minimal download strategy where appropriate.
Versioning. An assembly is the smallest unit in a .NET Framework application that you can version. The
assembly manifest describes the version information and any version dependencies that are specified
for any dependent assemblies. You can only version assemblies that have strong names.
Additional Reading: For more information about assemblies, see the Assemblies in the
Common Language Runtime page at http://go.microsoft.com/fwlink/?LinkID=267873.
Programming in Visual C# 12-39
9
W
What Is th
he GAC?
al assembly name
The globa
The versio
on number off the assemblyy
B
Benefits off Using the GAC
Although you
A u can install strong-named assemblies in directories on
n the computter, the GAC o
offers several
b
benefits, inclu
uding the folloowing:
Side-by-side deploymen nt and executtion. Different versions of an assembly in n the GAC do not affect
each othe er. Therefore, applications that
t referencee different verrsions of an asssembly do no
ot fail if a
later inco
ompatible verssion of the asssembly is instaalled into the cache.
Improved d loading time. When you in nstall a strongg-named assem mbly in the GAC, it undergoes strong-
name validation, which h ensures thatt the digital signature is vallid. The verificcation processs occurs at
installatio
on time, so strrong-named aassemblies in the GAC load faster at run time than asssemblies that
are not innstalled in the
e GAC.
12-40 Creating Reusable Types and Assemblies
Reduced memory consumption. If multiple applications reference an assembly, the operating system
loads only one instance of the assembly, which can reduce the total memory that is used on the
computer.
Improved search time. The CLR can locate a strong-named assembly in the GAC faster than it can
locate a strong-named assembly that is in a directory. This is because the runtime checks the GAC for
a referenced assembly before it checks other locations.
Improved maintainability. With a single file that multiple applications share, you can easily make fixes
that affect all of the applications.
Programming in Visual C# 12-41
1
S
Signing A
Assembliess
A strong name requires two o cryptographhic keys, a public key and a private key, known as a keey pair. The
c
compiler usess the key pair at build time to create the strong name. The strong n name consists of the simplee
t
text name of tthe assembly,, the version number,
n optio
onal culture in
nformation, th
he public key, and a digital
s
signature.
C
Creating Ke
ey Pairs
You must havve a key pair to
Y o sign an asse
embly with a strong
s name. To create a kkey pair, use th
he Strong
N
Name tool (Sn
n.exe) that the
e .NET Framewwork providess. To create a key pair file, p
perform the following
f
s
steps:
1
1. Open the
e Visual Studio
o 2012 command prompt.
2
2. In the Co
ommand Prom mpt window, use the Sn.exxe tool with th
he K switch to
o create a new
w key file. The
following
g code example shows how
w to create a new key file wiith the name FourthCoffee eKeyFile.
sn -k FourthCoffee
F KeyFile.snk
A
After you havve created a ke
ey file, you can then sign yo
our assembly..
S
Signing an Assembly
When you havve created the
W e key pair, you can then associate the keey file with yo
our assembly. Y You can
a
achieve this using the Sign
ning tab in thee project prop
perties pane. W
When you spe ecify a key file
e in the
p
properties pane, Visual Studio adds the AAssemblyKey yFileAttributte attribute too the AssemblyInfo class
i your appliccation.
in
Delay-Signing an Assembly
When you sign an assembly, you might not have access to a private key. For example, for security reasons,
some organizations restrict access to their private key to just a few individuals. The public key will
generally be available because as its name implies, it is publicly accessible. In this situation, you can use
delayed signing at build time. You provide the public key and reserve space in the PE file for the strong-
name signature. However, you defer the addition of the private key until a later stage, typically just before
the assembly ships.
You can enable delay-signing on the Signing tab of the project properties window as follows:
Disabling Verification
sn Vr FourthCoffee.Core.dll
You can then submit the assembly to the signing authority of your organization for the actual strong-
name signing. Use the R option with the Sn.exe tool to resign a delay-signed assembly.
The following code example signs an assembly called FourthCoffee.Core.dll with a strong name by using
the sgKey.snk key pair.
Signing an Assembly
sn -R FourthCoffee.Core.dll sgKey.snk
Additional Reading: For more information about delay signing, see the Delay Signing an
Assembly page at http://go.microsoft.com/fwlink/?LinkID=267874.
Programming in Visual C# 12-43
3
V
Versioning
g Assemb
blies
All assembliess are given a vversion number by Visual SStudio, which iis typically 1.0
A 0.0.0. It is the responsibility
o the develop
of per to increment the assemmblys version number as th he assembly e evolves.
A
Assembly V
Version Num
mber
The version number of an assembly
T a is a four-part strin
ng with the fo
ollowing formmat: <major
v
version>.<min nor version>.<
<build numbeer>.<revision> >. For examplee, version 1.2.3.0 indicates 1 as the
m
major version, 2 as the min
nor version, 3 as the build n
number, and 0 as the revisioon number.
By default, ap
B pplications onlly run with the version of aan assembly with
w which the ey were built. To
T change an
n
a
application to
o use a differeent version of an assembly, you can creatte a version policy in one o of the
c
configuration files: the app
plication config
guration file, the publisher policy file, orr the computeer's
a
administrator configuration n file.
R
Redirecting
g Binding R
Requests
When you waant to update a strong-nam
W med component without red deploying thee client appliccation that
u
uses it, you caan use a publisher policy file to redirect a binding request to a new
wer instance off the
c
component.
W
When a clientt application m
makes a binding request, th
he runtime pe ollowing tasks:
erforms the fo
Additional Reading: For more information about versioning, see the Assembly Versioning
page at http://go.microsoft.com/fwlink/?LinkID=267875.
Programming in Visual C# 12-45
5
I
Installing an Assem
mbly into the
t GAC
I
Installing a
an Assembly
y into the G
GAC by Using Gacutil..exe
To install an aassembly into the GAC by using
T u the Gacu
util.exe comm
mand-line tooll, perform the
e following
s
steps:
1
1. Open the
e Visual Studio
o 2012 command prompt aas an administtrator.
2
2. In the Co
ommand Prom
mpt window, type the follo
owing comma
and:
gacutil i "<pathT
ToAssembly>"
V
Viewing an
n Assembly in the GAC
C by Using G
Gacutil.exe
e
To view an assembly that iss installed into
T o the GAC by using the Gaccutil.exe comm
mand-line too
ol, perform
t following steps:
the
1
1. Open the
e Visual Studio
o 2012 command prompt aas an administtrator.
2
2. In the Co
ommand Prom
mpt window, type the follo
owing comma
and:
gacutil l "<assemblyName>"
Additioonal Reading: For more infformation abo out the GAC, ssee the Globa
al Assembly Caache
p
page at http:///go.microsoftt.com/fwlink//?LinkID=2678
876.
12-46 Creating Reusable Types and Assemblies
Demonstration: Sign
ning and IInstalling an Assem
mbly into tthe GAC
De
emonstration Steps
1. Start the MSL-TMG1 virtual machine if it is not already running.
3. Log on to W
Windows 8 as Student with
h the password Pa$$w0rd.
4. In File Explo
14 orer, highlightt the FourthCo
offeeKeyFile.ssnk file that th
he Sn applicattion generated
d.
Programming in Visual C# 12-47
18. In the Choose a strong name key file list, click Browse.
19. In the Select File dialog box, click FourthCoffeeKeyFile.snk, and then click Open.
26. Run the verifyGacInstall command, and then ensure that the number of items found equals one.
27. Close the VS2012 x64 Cross Tools Command Prompt window.
Demonstration: Spe
ecifying th
he Data to
o Include in the Grades Report Lab
In this demonstration, you wiill see the taskks that you wiill perform in the lab for this module.
Programming in Visual C# 12-49
9
Lab: Specify
ying the
e Data to Inclu
ude in the
t Gra
ades Re
eport
S
Scenario
You decide to
Y o update the GGrades applicaation to use custom
c attribu
utes to define the fields and
d properties
t
that should be e included in a grade report and to formmat them appropriately. This will enable further
r
reusability of the Microsoftt Word reportting functionaality.
O
Objectives
A
After completting this lab, you
y will be able to:
Define cu
ustom attributtes.
E
Estimated Tim
me: 75 minutes
3-SEA-DEV11-12, MSL-TMG
Virtual Machine: 20483 G1
User Nam
me: Student
Password
d: Pa$$w0rd
12-50 Creating Reusable Types and Assemblies
First, you will write code for the IncludeInReportAttribute class and define the members that are
contained in it.
Next, you will apply the attribute to the appropriate properties in the LocalGrade class in the Data.cs file.
Finally, you will build the application and then use the MSIL Disassembler utility (IL DASM) to examine the
metadata that the attribute generates.
3. Build the application and review the metadata for the LocalGrades class
2. Start the 20483A-SEA-DEV11-12 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio, and then open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 1
folder.
b. Grades.WPF
5. In the Grades.Utilities project, in the IncludeInReport.cs class, add code to specify that the
IncludeInReportAttribute class is an attribute class.
6. Add code to specify that the possible targets to which the IncludeInReport attribute can be applied
are fields and properties and that the attribute can be applied only once to each entity.
7. In the IncludeInReportAttribute class, define a private Boolean variable named _include to hold the
value of the attribute.
8. In the IncludeInReportAttribute class, define two public read/write Boolean properties named
Underline and Bold.
9. In the IncludeInReportAttribute class, define a public read/write string property named Label.
10. In the IncludeInReportAttribute class, create a default constructor that sets the properties as
follows:
_include: true
Underline: false
Bold: false
Label: string.Empty
11. Create another constructor that takes a Boolean parameter named includeInReport and sets the
properties as follows:
Programming in Visual C# 12-51
_include: _includeInReport
Underline: false
Bold: false
Label: string.Empty
SubjectName property:
Bold: true
Underline: true
AssessmentDate property:
Label: Date
Assessment property:
Label: Grade
Comments property:
Label: Comments
X Task 3: Build the application and review the metadata for the LocalGrades class
1. Build the solution, and then resolve any compilation errors.
2. Use the IL DASM utility to examine the metadata of the LocalGrades class in the Grades.WPF.exe
assembly.
3. Verify that the IncludeInReport attribute has been applied to the specified properties in the class.
Results: After completing this exercise, the Grades.Utilities assembly will contain an IncludeInReport
custom attribute and the Grades class will contain fields and properties that are tagged with that
attribute.
12-52 Creating Reusable Types and Assemblies
First, you will implement a method named GetItemsToInclude in a static helper class called
IncludeProcessor that implements the logic that is necessary to discover the fields and properties that
are tagged with the IncludeInReport attribute.
You will then update the code for the StudentProfile view to include fields and properties in the report
only if they are tagged with the IncludeInReport attribute and to format them appropriately.
3. Locate the FormatField struct declaration, and then add two string members named Value and
Label and two Boolean members named IsBold and IsUnderlined.
4. In the GetItemsToInclude method of the IncludeProcessor class, after the variable declarations, add
code to find all of the public fields and properties in the dataForReport object and use the
AddRange method add them to the fieldsAndProperties list.
5. Add code to iterate through all of the public fields and properties.
6. In the loop, add code to retrieve all the custom attributes applied to an item.
7. Then use the Array.Find method to test whether any of the custom attributes applied to the item are
the IncludeInReport attribute.
8. At the end of the loop, add code to find the value of the item that is tagged with the
IncludeInReport attribute.
9. At the end of the loop, add code to construct a FormatField item containing the value of the item
and the label, bold, and underline values from the attribute.
10. At the end of the loop, add code to add the FormatField item to the collection to be returned.
2. Add code to include each tagged item in the output, using the format that is specified by the
properties of the IncludeInReport attribute for each item.
Results: After completing this exercise, the application will be updated to use reflection to include only
the tagged fields and properties in the grades report.
Programming in Visual C# 12-53
12-54 Creating Reusable Types and Assemblies
First, you will use Sn.exe to generate a key pair and then use the key pair to sign the Grades.Utilities
assembly. Next, you will use Gacutil.exe to add the assembly to the GAC.
You will then update the reference for the Grades.Utilities assembly in the Grades.WPF project to use the
new signed assembly that is hosted in the GAC, and finally you will test the application to ensure that the
reports are correctly generated.
b. Grades.WPF
3. Run the VS2012 x86 Native Tools Command Prompt window as Administrator.
4. Run the Sn.exe utility to create a key pair file named GradesKey.snk in the E:\Labfiles\Starter folder.
5. In Visual Studio, set the properties of the Grades.Utilities project to use the key pair that you have just
created to sign the assembly.
7. At the command prompt, use the Gacutil utility to add the Grades.Utilities assembly to the GAC.
X Task 2: Reference the Grades.Utilities assembly in the GAC from the application
1. In Visual Studio, remove the current reference to the Grades.Utilities project from the Grades.WPF
project.
8. Open the grades report that you just created in Word and verify that the document contains a
correctly formatted report.
9. Close Word.
Programming in Visual C# 12-55
Results: After completing this exercise, you will have a signed version of the Grades.Utilities assembly
deployed to the GAC.
12-56 Creating Reusable Types and Assemblies
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou learned how
h to consumme existing asssemblies by uusing reflectio
on and how to o add
additional metaadata to typess and type me embers by usin ng attributes. You also learned how to g generate
code at run time e by using CoodeDOM and how you can ensure that yyour assemblie es are versioned and
avaailable to other application
ns by using the GAC.
Ve
erify the correcctness of the statement by placing a maark in the column to the rig
ght.
S
Statement Answer
Q
Question
Y
You are develooping a custo om attribute. You want to derive your custom
c attrib
bute class
frrom the abstract base classs that underp
pins all attributes. Which cclass should yyou use?
S
Select the corrrect answer.
Attribu
ute
ContexxtAttribute
ExtenssionAttribute
DataA
Attribute
Programming in Visual C# 12-57
Question
AddInAttribute
Question
You are reviewing some code that uses CodeDOM to generate managed Visual C# at
run time. What does the following line of code do?
Verify the correctness of the statement by placing a mark in the column to the right.
Statement Answer
Module 13
Encrypting and Decrypting Data
Contents:
Module Overview 13-2
Modu
ule Ove
erview
It iis a common requirement forf applications to be able to secure info ormation, wheether it is a caase of
encrypting files saved to diskk or web requeests sent overr an untrusted d connection tto other remo ote systems.
The Microsoft .NET Framew work providess a variety of cclasses that en
nable you to secure
s your daata by
usiing encryption and hashing g.
In this module, yyou will learn how to impleement symme etric and asym
mmetric encryption and how w to use
hashes to generrate mathema atical represen will also learn how to create and
ntations of your data. You w
maanage X509 certificates and d how to use tthem in the asymmetric en ncryption proccess.
Ob
bjectives
e, you will be able to:
Aftter completing this module
Lesson 1
Implementiing Sym
mmetricc Encry
yption
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Describe symmetric en
ncryption.
Create dig
gital fingerpriints of data byy using hashe
es.
13-4 Encrypting and Decrypting Data
W
What Is Sym
mmetric Encryption
E n?
The name symm metric is deriveed from the faact that the saame secret ke
ey is used to e
encrypt and de
ecrypt the
data. Therefore,, when you usse symmetric e encryption, yoou must keep the secret ke ey secure.
To
o help improve e the effectiveeness of symm metric encrypttion, many sym mmetric encryyption algoritthms also
use
e an initializattion vector (IV
V) in addition to a secret ke
ey. The IV is an
n arbitrary bloock of bytes that helps to
ran
ndomize the ffirst encrypted d block of datta. The IV makkes it much m more difficult ffor a maliciouss user to
de
ecrypt your da ata.
Ad
dvantages a
and Disadv
vantages off Symmetric Encryptio
on
The following taable describess some of the advantages and
a disadvanttages of symm
metric encrypttion.
A
Advantage Disadvantage
e
There is no lim
T mit on the am
mount of data you can The same key is used to encrypt and de ecrypt the
e
encrypt. data. If the kkey is comprom
mised, anyone
e can
encrypt and decrypt the d data.
Sy
ymmetric Encryption C
Classes in the .NET Fra
amework
The .NET Frame ework contains a number of classes in the System.Seccurity.Crypto ography name espace,
whhich provide managed
m implementations of common ssymmetric enccryption algorrithms, such as a
Ad
dvanced Encryyption Standard (AES), Dataa Encryption SStandard (DESS), and TripleD
DES. Each .NET
T
Fraamework symmmetric encrypption class is d
derived from tthe abstract S
SymmetricAlg gorithm basee class.
The following taable describess the key charracteristics of tthe.NET Fram
mework encryp
ption classes.
Encryption
A
Algorithm .NET Frame
ework Class Block Size
S Key
y Size
Technique
Programming in C# 13-5
Encryption
Algorithm .NET Framework Class Block Size Key Size
Technique
Each of the .NET Framework encryption classes are known as block ciphers, which means that the
algorithm will chunk data into fixed-length blocks and then perform a cryptographic transformation on
each block.
Note: You can measure the strength of an encryption algorithm by the key size. The higher
the number of bits, the more difficult it is for a malicious user trying a large number of possible
secret keys to decrypt your data.
Additional Reading: For more information about symmetric encryption in the .NET
Framework, see the SymmetricAlgorithm Class page at
http://go.microsoft.com/fwlink/?LinkID=267877.
13-6 Encrypting and Decrypting Data
En
ncrypting Data by Using
U Sym
mmetric En
ncryption
Yo
ou can encryptt data by usinng any of the ssymmetric encryption classses in the
Sy
ystem.Securitty.Cryptograp phy namespaace. However, these classes only provide managed
implementation ns of a particular encryption n algorithm; for example, the AesManag
ged class provvides a
maanaged imple ementation of the AES algorithm. Aside ffrom encrypting and decrypting data byy using an
alg
gorithm, the encryption
e proocess typicallyy involves the following tassks:
Read and w
write encrypted data to and
d from a stream.
To
o help simplifyy the encryptio
on logic in yo
our application
ns, the .NET Framework inccludes a numb
ber of other
cryyptography classes that youu can use.
Th
he Rfc2898DeriveByte
es and Cryp
ptoStream C
Classes
The Rfc2898De eriveBytes claass provides an implementaation of the password-base ed key derivattion
fun
nction (PBKDFF2), which com
mplies with th PKCS). You can use the
he Public-Key Cryptographyy Standards (P
PB
BKDF2 functionality to derivve your secrett keys and you
ur IVs from a password and
d a salt.
Additionaal Reading: FFor more inforrmation about the Rfc2898 8DeriveBytess class, see the
Rfcc2898DeriveB
Bytes Class pagge at http://g
go.microsoft.com/fwlink/?LinkID=267878
8.
Additionaal Reading: FFor more inforrmation about the CryptoSStream class, see the
CryyptoStream C
Class page at http://go.micr
h rosoft.com/fw
wlink/?LinkID=
=267879.
Sy
ymmetrically Encrypting and Deccrypting Da
ata
pt data by using the AesManaged class:
The following stteps describe how to encryypt and decryp
Programming in C# 13-7
1. Create an Rfc2898DeriveBytes object, which you will use to derive the secret key and the IV. The
following code example shows how to create an instance of the Rfc2898DeriveBytes class, passing
values for the password and salt into the constructor.
2. Create an instance of the encryption class that you want to use to encrypt the data. The following
code example shows how to create an AesManaged object.
3. Generate the secret key and the IV from the Rfc2898DeriveBytes object. The following code
example shows how to generate the secret key and the IV by using the algorithms KeySize and
BlockSize properties.
Note: You typically use the algorithms KeySize and BlockSize properties when generating
the secret key and the IV, so that the secret key and the IV that you generate are compatible with
the algorithm.
4. Create a stream object that you will use to buffer the encrypted or unencrypted bytes. The following
code example shows how to create an instance of the MemoryStream class.
5. Create either a symmetric encryptor or decryptor depending on whether you want to encrypt or
decrypt data. The following code example shows how to invoke the CreateEncryptor method to
create an encryptor and how to invoke the CreateDecryptor method to create a decryptor. Both
methods accept the secret key and the IV as parameters.
6. Create a CryptoStream object, which you will use to write the cryptographic bytes to the buffer
stream. The following code example shows how to create an instance of the CryptoStream class,
passing the bufferStream object, the algorithm object, and the stream mode as parameters.
7. Invoke the Write and FlushFinalBlock methods on the CryptoStream object, to perform the
cryptographic transform. The following code example shows how to invoke the Write and
FlushFinalBlock methods of the CryptoStream object.
8. Invoke the Close method on the CryptoStream and the MemoryStream objects, so that the
transformed data is flushed to the buffer stream. The following code example shows how to invoke
the Close methods on both the CryptoStream and the MemoryStream objects.
cryptoStream.Close();
bufferStream.Close();
Program
mming in C# 13-9
9
H
Hashing D
Data
Hashing is the
H e process of g
generating a nnumerical reprresentation off your data. Tyypically, hash algorithms
c
compute hash
hes by mappin ng the binary representatio on of your datta to the binary values of a fixed-length
h
hash. If you use a proven hhash algorithm
m, it is consideered unlikely tthat you could
d compute the same hash
f
from two diffe
erent pieces of
o data. Thereffore, hashes are
a considered d a reliable waay to generate
e a unique
d
digital fingerp
print that can help to ensurre the integritty of data.
Consider the e
C example of th
he FourthCoffee.Beverage sservice, which sends messagges to the
F
FourthCoffee..Inventory service. When th
he FourthCoffe
ee.Inventory service
s receive
es a message,, how do the
t
two services know
k that the message wass not sabotage
ed during thee transmission
n? You could u
use hashes, ass
t following steps describe:
the
1
1. Compute
e a hash of the
e message beffore the FourtthCoffee.Beve
erage service sends
s the messsage.
2
2. Compute
e a hash of the
e message wh
hen the Fourth
hCoffee.Inventory service re
eceives the message.
3
3. Compare the two hashhes. If the two hashes are id
dentical, the d
data has not b
been tampered
d with. If the
data has been modified, the two hashes will not match.
m
H
Hash Algorrithms in th
he .NET Framework
T following table describ
The bes some of th
he hash classe
es that the .NEET Frameworkk provides.
.NET Framew
work Class Descriptio
on
SHA512Ma
anaged The SHA5 512Managed d class is an im
mplementation of the
Secure Ha ash Algorithm
m (SHA) and iss able to comp
pute a 512-
bit hash. T
The .NET Frammework also includes classe
es that
implemen nt the SHA1, SSHA256, and SHA384 algorrithms.
HMACSHA
A512 The HMA ACSHA512 cla ass uses a com
mbination of tthe SHA512
hash algo
orithm and the
e Hash-Based d Message Autthentication
Code (HMMAC) to comp pute a 512-bitt hash.
MACTriple
eDES The MAC CTripleDES claass uses a com
mbination of the
t TripleDES
encryptio
on algorithm aand a Message Authenticattion Code
13-10 Encrypting and Decrypting Data
1. Generate a secret key that the hash algorithm will use to hash the data. The sender would need
access to the key to generate the hash, and the receiver would need access to the key to verify the
hash.
2. Create an instance of the hash algorithm.
3. Invoke the ComputeHash method, passing in a stream that contains the data you want to hash. The
ComputeHash method returns a byte array that represents the hash of your data.
The following code example shows how to compute a hash by using the HMACSHA512 class.
Additional Reading: For more information about hashing in the .NET Framework, see
the Hash Values section on the Cryptographic Services page at
http://go.microsoft.com/fwlink/?LinkID=267880.
Programm
ming in C# 13-11
1
D
Demonstr
ration: En
ncrypting and Decry
ypting Daata
I this demon
In nstration, you will use symm
metric encrypttion to encryp
pt and decryptt a message.
D
Demonstra
ation Steps
1
1. Start the MSL-TMG1 viirtual machine
e if it is not already running
g.
2
2. Start the 20483A-SEA
A-DEV11-13 vvirtual machine.
3
3. Log on to
o Windows 8 as Student with the passsword Pa$$w0rd.
Note: Iff necessary, click Switch Usser to display the list of use
ers.
4
4. Switch to the Windowss 8 Start wind
dow.
5
5. Click Visu
ual Studio 20
012.
6
6. In Microssoft Visual Studio, on the File menu, po
oint to Open,, and then clicck Project/So
olution.
7
7. In the Op
pen Project dialog box, bro
owse to the E::\Democode\\FourthCoffe
ee.MessageSa
afe folder,
click FourrthCoffee.Me
essageSafe.sln, and then cclick Open.
8
8. In Visual Studio, on the
e View menu,, click Task Liist.
9
9. In the Tassk List windo
ow, in the Cate
egories list, click Commen
nts.
1 Explain th
11. hat the follow
wing code crea
ates an instancce of the AesManaged claass.
this._al
lgorithm = new
n AesManaged();
1 Explain th
13. hat the follow
wing code deteermines whethher the _algorithm object is not null and then
invokes th
he Dispose method
m to rele
ease any resou e algorithm may have used..
urces that the
if (this
s._algorithm
m != null)
{
this._algorithm.
.Dispose();
13-12 Encrypting and Decrypting Data
14. Double-click the TODO: 03: Derive a Rfc2898DeriveBytes object from the password and salt.
task.
15. Explain that the following code creates an instance of the Rfc2898DeriveBytes class by using a
password (that the user provides at run time) and salt (hard-coded value in the application).
16. Double-click the TODO: 04: Generate the secret key by using the Rfc2898DeriveBytes object.
task.
17. Explain that the following code uses the Rfc2898DeriveBytes object to derive the secret key by using
the algorithms key size in bytes.
Note: The KeySize property returns the size of the key in bits, so to get the value in bytes,
you divide the value by 8.
18. Double-click the TODO: 05: Generate the IV by using the Rfc2898DeriveBytes object. task.
19. Explain that the following code uses the Rfc2898DeriveBytes object to derive the IV by using the
algorithms block size in bytes.
Note: The BlockSize property returns the size of the block in bits, so to get the value in
bytes, you divide the value by 8.
20. Double-click the TODO: 06: Create a new MemoryStream object. task.
21. Explain that the following code creates an instance of the MemoryStream class, which will be used as
a buffer for the transformed data.
22. Double-click the TODO: 07: Create a new CryptoStream object. task.
23. Explain that the following code creates an instance of the CryptoStream class, which will transform
the data and write it to the underlying memory stream.
24. Double-click the TODO: 08: Write the bytes to the CryptoStream object. task.
25. Explain that the following code writes the transformed data to the underlying memory stream.
cryptoStream.Write(bytesToTransform, 0, bytesToTransform.Length);
cryptoStream.FlushFinalBlock();
26. Double-click the TODO: 09: Read the transformed bytes from the MemoryStream object. task.
Programming in C# 13-13
27. Explain that the following code uses the ToArray method to extract the transformed data from the
memory stream as a byte array.
28. Double-click the TODO: 10: Close the CryptoStream and MemoryStream objects. task.
29. Explain that the following code closes the cryptoStream and bufferStream objects.
cryptoStream.Close();
bufferStream.Close();
30. Double-click the TODO: 11: Use the _algorithm object to create an ICryptoTransform encryptor
object. task.
31. Explain that the following code creates an ICryptoTransform object that will encrypt data.
32. Double-click the TODO: 12: Invoke the TransformBytes method and return the encrypted bytes.
task.
33. Explain that the following code invokes the TransformBytes helper method, which will use the
ICryptoTransform object to encrypt the data.
34. Double-click the TODO: 13: Use the _algorithm object to create an ICryptoTransform decryptor
object. task.
35. Explain that the following code creates an ICryptoTransform object that will decrypt data.
36. Double-click the TODO: 14: Invoke the TransformBytes method and return the decrypted bytes.
task.
37. Explain that the following code invokes the TransformBytes helper method, which will use the
ICryptoTransform object to decrypt the data.
40. In the Fourth Coffee Message Safe application, in the Password box, type Pa$$w0rd.
41. In the Message box, type This is my secure message, and then click Save.
42. Close the Fourth Coffee Message Safe application.
44. Double-click protected_message.txt, and then view the encrypted text in Notepad.
45. Close Notepad, and then close File Explorer.
46. In Visual Studio, on the Debug menu, click Start Without Debugging.
47. In the Fourth Coffee Message Safe application, in the Password box, type Pa$$w0rd, and then click
Load.
13-14 Encrypting and Decrypting Data
48. Verify that the Message box now displays the text This is my secure message.
Lesson 2
Implementiing Asy
ymmetrric Encrryption
Asymmetric e
A encryption is the process off performing a cryptograph
hic transforma
ation of data b
by using an
a
asymmetric ncryption algo
en orithm and a combination of public andd private keys..
L
Lesson Ob
bjectives
A
After completting this lesson, you will be able to:
Describe asymmetric e
encryption.
Encrypt aand decrypt daata by using aasymmetric en
ncryption.
Create an
nd manage X5
509 certificate
es.
Manage encryption
e ke
eys in your app
plications.
13-16 Encryppting and Decrypting Data
W
What Is Asy
ymmetric Encryptio
on?
Un
nlike symmetrric encryption,, where one se
ecret key is ussed to perform
m both the en
ncryption and the
de
ecryption, asym
mmetric encryyption uses a public key to perform the encryption an nd a private ke
ey to
pe
erform the deccryption.
In a system thatt uses asymme etric encryptioon, the publicc key is made available to any application
n that
quires the ability to encrypt data. Howevver, the privatte key is kept safe and is on
req nly distributed
d to
pplications thaat require the ability to decrypt the data.. For example, HTTPS uses asymmetric encryption
ap
to encrypt and d decrypt the browsers session key when establishing a secure connection betwee en the
bro
owser and the e server.
Ad
dvantages a
and Disadv
vantages off Asymmetrric Encryption
a disadvanttages of asymmetric encryp
The following taable describess some of the advantages and ption.
Programming in C# 13-17
Advantage Disadvantage
Asymmetric encryption relies on two keys, so it is With asymmetric encryption, there is a limit on the
easier to distribute the keys and to enforce who amount of data that you can encrypt. The limit is
can encrypt and decrypt the data. different for each algorithm and is typically
proportional with the key size of the algorithm.
For example, an RSACryptoServiceProvider
object with a key length of 1,024 bits can only
encrypt a message that is smaller than 128 bytes.
Asymmetric algorithms use larger keys than Asymmetric algorithms are very slow in
symmetric algorithms, and they are therefore less comparison to symmetric algorithms.
susceptible to being cracked by using brute force
attacks.
Asymmetric encryption is a powerful encryption technique, but it is not designed for encrypting large
amounts of data. If you want to encrypt large amounts of data with asymmetric encryption, you should
consider using a combination of asymmetric and symmetric encryption.
Best Practice: To encrypt data by using asymmetric and symmetric encryption, perform
the following steps:
1. Encrypt the data by using a symmetric algorithm, such as the AesManaged class.
The IV
To decrypt, simply step through the stream extracting the data, decrypt the symmetric encryption
key, and then decrypt the data.
Additional Reading: For more information about asymmetric encryption in the .NET
Framework, see the Public-Key Encryption section on the Cryptographic Services page at
http://go.microsoft.com/fwlink/?LinkID=267881.
Programm
ming in C# 13-19
9
E
Encrypting Data by
y Using Assymmetricc Encryption
E
Encrypting Data by Ussing the RS
SACryptoSe
erviceProvid
der Class
The RSACryp
T ptoServiceProovider class provides a num mber of memb bers that enab ble you to imp
plement
a
asymmetric ncryption functionality in your
en y applicatio
ons, including
g the ability to
o import and e
export key
i
information and encrypt annd decrypt da ata.
You can creatte an instance of the RSACrryptoService
Y eProvider classs by using the
e default consstructor. If
y choose th
you his approach, the RSACrypptoServiceProovider class will
w generate a set of public and private
k
keys.
The following code example shows how to create an instance of th
T he RSACrypto
oServiceProv
vider class by
u
using the defaault constructtor.
I
Instantiating
g the RSACryp
ptoServicePrrovider Class
var rsaProv
vider = new RSACryptoServiceProvide
er();
The following code example shows how you can use tthe Encrypt aand Decrypt m
T methods to p
protect the
c
contents of a string variable.
E
Encrypting and Decryptin
ng Data by Using
U the RSA
ACryptoServiceProvider C
Class
var plainTe
ext = "hello
o world";
var rawByte
es = Encodin
ng.Default.GetBytes(plaiinText);
var decrypt
tedText = st
tring.Empty;
using (var rsaProvider
r = new RSACryptoServiceeProvider())
)
{
var use
eOaepPadding
g = true;
var enc
cryptedBytes
s = rsaProvider.Encrypt((rawBytes, useOaepPaddi
u ng);
var dec
cryptedBytes
s = rsaProvider.Decrypt((encryptedBy
ytes, useOaepPadding);
decrypt
tedText = En
ncoding.Default.GetStrinng(decrypted
dBytes);
}
// The decr
ryptedText variable
v will now contai
in " hello world"
w
13-20 Encrypting and Decrypting Data
Note: You use the useOaepPadding parameter to determine whether the Encrypt and
Decrypt methods use Optimal Asymmetric Encryption Padding (OAEP). If you pass true, the
methods use OAEP, and if you pass false, the methods use PKCS#1 v1.5 padding.
Typically, applications do not encrypt and decrypt data in the scope of the same
RSACryptoServiceProvider object. One application may perform the encryption, and then another
performs the decryption. If you attempt to use different RSACryptoServiceProvider objects to perform
the encryption and decryption, without sharing the keys, the Decrypt method will throw a
CryptographicException exception. The RSACryptoServiceProvider class exposes members that enable
you to export and import the public and private keys.
The following code example shows how to instantiate different RSACryptoServiceProvider objects and
use the ExportCspBlob and ImportCspBlob methods to share the public and private keys.
Instead of maintaining and persisting keys in your application, you can use the public and private keys in
an X509 certificate, stored in the certificate store on the computer that is running your application.
C
Creating aand Manaaging X509 Certificaates
C
Creating a Certificate by Using M
MakeCert
MakeCert is a certificate cre
M eation tool th
hat the .NET Framework pro ovides. You caan access the tool by using
t Visual Studio command
the d prompt. Thee MakeCert to ool provides a number of command-line e switches
t
that enable yo
ou to configure the X509 certificate to mmeet the requirements of your applicatio on.
Switch Description
The following code example shows how you can use tthe MakeCertt command-line tool to gen
T nerate a self-
s
signed certificcate, which co
ontains both a public and a private key.
13-22 Encrypting and Decrypting Data
MakeCert Example
makecert -n "CN=FourthCoffee" -a sha1 -pe -r -sr LocalMachine -ss my -sky exchange
Additional Reading: For more information about MakeCert, see the Makecert.exe
(Certificate Creation Tool) page at http://go.microsoft.com/fwlink/?LinkID=267883.
To open a certificate store by using the MMC snap-in, perform the following steps:
1. Log on as an administrator. If you log on without administrative privileges, you will only be able to
view certificates in your user account certificate store.
2. In the Windows 8 Start window, use search to find mmc.exe, and then click mmc.exe.
3. In the MMC window, on the File menu, click Add/Remove Snap-in.
4. In the Add or Remove Snap-ins dialog box, in the Available snap-ins list, click Certificates, and
then click Add.
5. In the Certificates snap-in dialog box, click either My user account, Service account, or Computer
account, and then perform one of the following steps:
b. If you chose Service account, click Next, and then perform the following steps:
ii. In the Certificates snap-in dialog box, in the Service account list, click the service account
you want to manage, and then click Finish.
c. If you chose Computer account, click Next, and then click Finish.
6. In the Add or Remove Snap-ins dialog box, repeat steps 4 and 5 if you want to add additional
certificate stores to your session, and then click OK.
After you have opened one or more certificate stores, you can perform any of the following tasks:
View the properties that are associated with any X509 certificate in any of the certificate stores, such
as Personal or Trusted Root Certificate Authorities stores.
Manage the private keys that are associated with an X509 certificate.
Issue a request to renew an existing X509 certificate.
Additional Reading: For more information about managing certificates, see the Working
with Certificates page at http://go.microsoft.com/fwlink/?LinkID=267884.
Programm
ming in C# 13-23
3
M
Managing
g Encryptiion Keys
X509Certtificate2. This class enable es you create aan in-memoryy representation of an X509 9 certificate
that curre ou have instantiated an X5
ently exists in a certificate sstore. When yo 509Certificate e2 object,
you can tthen use its members
m to access information, such as th
he X509 certifficates publicc and private
keys.
PublicKeey. This class e
enables you too manipulate the various pieces of metadata that are associated
X509 certificates public keyy, such as the public keys vvalue.
with an X
E
Enumerating
g a Certificate
e Store
var store = new X509St
tore(StoreName.My, StoreeLocation.Lo
ocalMachine);
var certifi
icate = defa
ault(X509Certificate2);
var certifi
icateName = "CN=FourthCoffee";
store.Open(
(OpenFlags.R
ReadOnly);
foreach (va
ar storeCert
tificate in store.Certifficates)
{
if (stor
reCertificat
te.SubjectName.Name == ccertificateN
Name)
{
certi
ificate = st
toreCertificate;
conti
inue;
}
}
store.Close
e();
HasPrivateKey. This property enables you to determine whether the X509 certificate contains a
private key.
FriendlyName. This property enables you to get the friendly name that is associated with the X509
certificate.
GetPublicKeyString. This method enables you to extract the public key that the X509 certificate
contains as a string value.
PublicKey. This property enables you to get the public key that the X509 certificate contains as a
PublicKey object.
PrivateKey. This property enables you to get the private key that the X509 certificate contains as an
AsymmetricAlgorithm object.
You can use the PublicKey and PrivateKey properties of the X509Certificate2 class to create an instance
of the RSACryptoServiceProvider class.
The following code example shows how you can use the PublicKey and PrivateKey properties to create
an instance of the RSACryptoServiceProvider class..
Additional Reading: For more information about managing encryption keys in your
application, see the System.Security.Cryptography.X509Certificates Namespace page at
http://go.microsoft.com/fwlink/?LinkID=267885.
Programm
ming in C# 13-25
5
D
Demonstr
ration: En
ncrypting and Decry
ypting Graade Reports Lab
I this demon
In nstration, you will learn abo
out the tasks tthat you will p
perform in the
e lab for this module.
m
13-26 Encryppting and Decrypting Data
Lab: E
Encrypting and
d Decry
ypting tthe Gra
ades Re
eport
Sccenario
Yo
ou have been asked to updaate the Grade es application to ensure thaat reports are secure when they are
sto
ored on a userr's computer. You decide to o use asymme etric encryptioon to protect the report as it is
geenerated, befo
ore it is written
n to disk. Adm
ministrative sta
aff will need tto merge repoorts for each cclass into
onne document, so you decide e to develop a separate application that generates a combined
c rep
port and
priints it.
Ob
bjectives
Aftter completing this lab, you
u will be able to:
Decrypt datta.
Password: Pa$$w0rd
P
Programming in C# 13-27
First, you will create an asymmetric certificate by using a prewritten batch file. The batch file uses the
MakeCert tool that ships with the Windows Software Development Kit (SDK). You will create a self-signed
certificate named Grades using the SHA-1 hash algorithm and store it in the LocalMachine certificate
store.
You will then write code in the Grades application to retrieve the certificate by looping through the
certificates in the LocalMachine store and checking the name of the certificate against the name that is
stored in the App.Config file.
Next, you will use the classes that are provided in the System.Security.Cryptography and
System.Security.Cryptography.X509Certificates namespaces to write the EncryptWithX509 method in
the Grades.Utilities.WordWrapper class. You will get the public key from the certificate that you created
and use it to create an instance of the RSAPKCS1KeyExchangeFormatter class. You will use this to
encrypt the data for the report and then return the encrypted buffered data to the calling method as a
byte array.
You will then write code in the EncryptAndSaveToDisk method to write the returned data to the file that
the user specifies.
Finally, you will build and test the application and verify that the reports are now encrypted.
2. Start the 20483A-SEA-DEV11-13 virtual machine and log on as Student with the password
Pa$$w0rd.
3. Start Visual Studio, and then open the Grades.sln solution from the E:\Labfiles\Starter\Exercise 1
folder.
a. Grades.Web
b. Grades.WPF
2. Add code to this method to loop through the certificates in the store.Certificates collection.
3. Inside the loop, if the SubjectName.Name property matches the _certificateSubjectName variable,
return the certificate to the calling method.
2. Add code to this method to get the public key from the X509 certificate, cast it to a
RSACryptoServiceProvider object, and store it in a variable named provider.
Note: You use the PublicKey.Key property of a certificate to retrieve the public key.
3. In the EncryptWithX509 method, add code to create an instance of the AesManaged encryption
class named algorithm. Enclose this line of code in a using statement and add a closing brace at the
end of the method.
4. Add code to create an instance of the MemoryStream class to hold the unencrypted data. Enclose
this line of code in a using statement and add a closing brace at the end of the method.
5. Add the following code to create an AES encryptor based on the key and IV.
6. Add a closing brace for the using statement at the end of the method.
7. Add the following code to create byte arrays to get the length of the encryption key and IV.
8. Add code to write the following data to the unencrypted memory stream object by using the Write
method of the MemoryStream instance.
d. The IV.
10. Add code to call the Write and FlushFinalBlock methods of the CryptoStream object to write all
the data to the memory stream.
11. Add code to return the encrypted buffered data to the calling method.
Programming in C# 13-29
4. Generate grade reports for George Li and Kevin Liu, saving each report in the E:\Labfiles\Reports
folder.
Results: After completing this exercise, you should have updated the Grades application to encrypt
generated reports.
13-30 Encrypting and Decrypting Data
First, you will use the classes that are provided in the System.Security.Cryptography and
System.Security.Cryptography.X509Certificates namespaces to write the DecryptWithX509 method
in the SchoolReports.WordWrapper class. You will get the private key from the certificate and use it to
create an instance of the RSACryptoServiceProvider class. You will use this to decrypt the data from the
individual reports and then return the decrypted data to the calling method as a byte array.
Finally, you will build and test the application and verify that a printed version of the composite report has
been generated.
3. Add code to this method to get the private key from the X509 certificate, cast it to a
RSACryptoServiceProvider object, and store it in a variable named provider.
Note: You can use the PrivateKey property of a certificate to retrieve the private key.
4. In the DecryptWithX509 method, add code to create an instance of the AesManaged encryption
class named algorithm. Enclose this line of code in a using statement and add a closing brace at the
end of the method.
5. Add code to create an instance of the MemoryStream class, passing the byte array that the method
received as a parameter. Enclose this line of code in a using statement and add a closing brace at the
end of the method.
6. Add the following code to create byte arrays to get the length of the encryption key and IV.
7. Add code to read the key and IV lengths from index 0 in the memory stream and then convert the
two lengths to integers.
8. Add code to determine the starting position and length of the encrypted data.
9. Add code to create byte arrays to store the encrypted key, the IV, and the encrypted data.
10. Add code to read the key, IV, and encrypted data from the memory stream and store them in the
byte arrays that you have just created.
11. Add code to decrypt the encrypted AES managed key by calling the Decrypt method of the provider
object.
Programming in C# 13-31
12. Add code to create a new instance of the MemoryStream class to store the decrypted data. Enclose
this line of code in a using statement and add a closing brace at the end of the method.
13. Add code to create an AES decryptor object, passing the decrypted key and the IV as parameters.
Enclose this line of code in a using statement and add a closing brace at the end of the method.
14. Add code to create an instance of a CryptoStream object, passing the memory stream for the
decrypted data, the AES decryptor, and the CryptoStreamMode.Write constant as parameters.
Enclose this line of code in a using statement and add a closing brace at the end of the method.
15. Add code to call the Write and FlushFinalBlock methods of the CryptoStream object to write all of
the data to the memory stream.
16. Add code to return the decrypted buffered data to the calling method.
2. Run the application, and then print a composite report that contains the two reports that you
generated earlier. Save the .oxps file in the E:\Labfiles\Reports\ClassReport folder.
3. Close the application, close the solution, and then close Visual Studio.
4. Open the composite report in the XPS Reader and verify that the data has printed correctly.
Results: After completing this exercise, you should have a composite unencrypted report that was
generated from the encrypted reports.
13-32 Encryppting and Decrypting Data
Modu
ule Reviiew and
d Takea
aways
M
Module Revie
ew
In this module, yyou learned how
h to implemment symmetric and asymm
metric encrypttion and how to use
hashes to generrate mathema atical represen
ntations of your data.
Test Your Know
wledge
Q
Question
FFourth Coffee
e wants you to o implement an encryptio on utility that can encrypt and
ddecrypt large image files. E
Each image wwill be more th han 200 meg gabytes (MB) in size.
FFourth Coffee
e envisages thhat only a sma all internal te
eam will use this tool, so co
ontrolling
wwho can encryypt and decry ypt the data iis not a conceern. Which off the following
teechniques will you choose e?
S
Select the corrrect answer.
Symm
metric encryption
Asymm
metric encryption
Hashin
ng
Ve
erify the correcctness of the statement by placing a maark in the column to the rig
ght.
S
Statement Answer
Courrse Evalluation
Y
Your evaluatio
on of this cou
urse will help M
Microsoft und
derstand the q
quality of yourr learning exp
perience.
P
Please work w
with your train
ning provider to access the course evalua
ation form.
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click School.sln, and then
click Open.
9. Double-click MainWindow.xaml.cs.
11. In the Task List window, in the Categories list, click Comments.
12. Double-click the TODO: Exercise 1: Task 1a: If the user pressed Enter, edit the details for the currently
selected student task.
13. In the code editor, click at the beginning of the comment line, press Enter, and in the blank space
above the comment, type the following code:
switch (e.Key)
{
14. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
15. After all the comments in this method, type the following code:
break;
}
MCT USE ONLY. STUDENT USE PROHIBITED
L01-2 Programming in Visual C#
X Task 2: Initialize the StudentForm window and populate it with the details of the
currently selected student
1. In the Task List window, double-click the TODO: Exercise 1: Task 2a: Use the StudentsForm to display
and edit the details of the student task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
3. In the Task List window, double-click the TODO: Exercise 1: Task 2b: Set the title of the form and
populate the fields on the form with the details of the student task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 3: Display the StudentForm window and copy the updated student details
entered back to the Student object
1. In the Task List window, double-click the TODO: Exercise 1: Task 3a: Display the form task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
if (sf.ShowDialog().Value)
{
3. After all the comments in this method, add the following code:
4. In the Task List window, double-click the TODO: Exercise 1: Task 3b: When the user closes the form,
copy the details back to the student task.
5. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
student.FirstName = sf.firstName.Text;
student.LastName = sf.lastName.Text;
student.DateOfBirth =
DateTime.Parse(sf.dateOfBirth.Text);
6. In the Task List window, double-click the TODO: Exercise 1: Task 3c: Enable saving (changes are not
made permanent until they are written back to the database) task.
7. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
8. saveChanges.IsEnabled = true;
X Task 4: Run the application and verify that the edit functionality works as expected
1. On the Build menu, click Build Solution.
MCT USE ONLY. STUDENT USE PROHIBITED
L01-3
3. Verify that the application starts and displays the initial list of students.
The initial students list should look like this:
5. Press Enter and verify that the Edit Student Details window appears and displays the correct details:
The Edit Student Details window should look similar to the following:
X Task 5: Use the Visual Studio Debugger to step through the code.
1. In Visual Studio, in the Task List window, double-click the TODO: Exercise 1: Task 2b: Set the title of
the form and populate the fields on the form with the details of the student task.
2. In the following line of code, right-click the word Title in sf.Title = "Edit Student Details";, point to
Breakpoint, and then click Insert Breakpoint.
4. Click the row containing the name George Li, and then press Enter.
5. When Visual Studio enters break mode, in the bottom left window, click the Watch 1 tab.
6. In the Watch 1 window, click below Name to create a blank row.
10. In the Watch 1 window, click below sf.firstName.Text to create a blank row.
12. In the Watch 1 window, click below sf.lastName.Text to create a blank row.
16. In the bottom middle window, click the Immediate Window tab.
17. In the Immediate Window, type sf.firstName.Text, and then press Enter.
18. Verify that "George" is displayed.
19. In the Watch 1 window, in the sf.firstName.Text row, right-click the Value field, and then click Edit
Value.
20. Type "Dominik" and press Enter.
21. In the Immediate Window, type sf.lastName.Text, and then press Enter.
24. In the Watch 1 window, in the sf.lastName.Text row, verify that the Value column has changed to
"Dubicki".
25. On the Debug menu, click Continue.
26. Verify that the Edit Student Details form contains the information in the following table:
Field Value
28. In Visual Studio, on the Debug menu, click Delete All Breakpoints.
Results: After completing this exercise, users will be able to edit the details of a student.
MCT USE ONLY. STUDENT USE PROHIBITED
L01-6 Programming in Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 2, click School.sln, and then
click Open.
3. In the Task List window, double-click the TODO: Exercise 2: Task 1a: If the user pressed Insert, add a
new student task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
case Key.Insert:
sf = new StudentForm();
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Set the title of the form to
indicate which class the student will be added to (the class for the currently selected teacher) task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 3: Display the StudentForm window and enable the user to provide the details
of the new student
1. In the Task List window, double-click the TODO: Exercise 2: Task 3a: Display the form and get the
details of the new student task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
if (sf.ShowDialog().Value)
{
3. After all the comments in this method, add the following code:
}
break;
4. In the Task List window, double-click the TODO: Exercise 2: Task 3b: When the user closes the form,
retrieve the details of the student from the form and use them to create a new Student object task.
5. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
MCT USE ONLY. STUDENT USE PROHIBITED
L01-7
X Task 4: Assign the new student to a class and enable the user to save the details of
the new student
1. In the Task List window, double-click the TODO: Exercise 2: Task 4a: Assign the new student to the
current teacher task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
this.teacher.Students.Add(newStudent);
3. In the Task List window, double-click the TODO: Exercise 2: Task 4b: Add the student to the list
displayed on the form task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
this.studentsInfo.Add(newStudent);
5. In the Task List window, double-click the TODO: Exercise 2: Task 4c: Enable saving (changes are not
made permanent until they are written back to the database) task.
6. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
saveChanges.IsEnabled = true;
X Task 5: Run the application and verify that the insert functionality works as expected
1. On the Build menu, click Build Solution.
5. Press Insert and verify that the new student window appears:
6. In the First Name text box, type Darren.
8. In the Date of Birth text box, type 02/03/2006, and then click OK.
9. Verify that Darren Parker has been added to the students list, and that the Save Changes button is
now enabled.
Note: The ID of any new student will be 0 until they are saved to the database.
Results: After completing this exercise, users will be able to add new students to a class.
MCT USE ONLY. STUDENT USE PROHIBITED
L01-9
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 3, click School.sln, and then
click Open.
3. In the Task List window, double-click the TODO Exercise: 3: Task 1a: If the user pressed Delete,
remove the currently selected student task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 2: Prompt the user to confirm that they want to remove the selected student
from the class
1. In the Task List window, double-click the TODO: Exercise 3: Task 2a: Prompt the user to confirm that
the student should be removed task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 3: Remove the student and enable the user to save the changes
1. In the Task List window, double-click the TODO: Exercise 3: Task 3a: If the user clicked Yes, remove the
student from the database task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
if (response == MessageBoxResult.Yes)
{
this.schoolContext.Students.DeleteObject(student);
3. After the final comment in this method, type the following code:
}
break;
4. In the Task List window, double-click the TODO: Exercise 3: Task 3b: Enable saving (changes are not
made permanent until they are written back to the database) task.
5. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
saveChanges.IsEnabled = true;
X Task 4: Run the application and verify that the delete functionality works as expected
1. On the Build menu, click Build Solution.
MCT USE ONLY. STUDENT USE PROHIBITED
L01-10 Programming in Visual C#
3. Verify that the application starts and displays the initial list of students.
4. Click on the drop-down menu containing the text Esther Valle: Class 3C.
5. Click the list item containing the text David Waite : Class 4B.
8. In the Confirm dialog box, click Yes, verify that Jon Orton is removed from the students list, and then
verify that the Save Changes button is enabled.
9. Close the application.
Results: After completing this exercise, users will be able to remove students from classes.
MCT USE ONLY. STUDENT USE PROHIBITED
L01-11
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 4, click School.sln, and then
click Open.
3. On the Build menu, click Build Solution.
4. In Solution Explorer, expand the School, and then double-click the MainWindow.xaml and view the
XAML code.
<app:AgeConverter x:key="ageConverter"/>
<GridViewColumn Width="75" Header="Age"
DisplayMemberBinding="{Binding Path=DateOfBirth, Converter={StaticResource
ageConverter}}" />
X Task 2: Add logic to the AgeConverter class to calculate a students age from their
date of birth
1. In the Task List window, double-click the TODO: Exercise 4: Task 2a: Check that the value provided is
not null. If it is, return an empty string task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
if (value != null)
{
3. In the code editor, after all the comments in this method, delete the following line of code:
return "";
4. In the Task List window, double-click the TODO: Exercise 4: Task 2b: Convert the value provided into a
DateTime value task.
5. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
6. In the Task List window, double-click the TODO: Exercise 4: Task 2c: Work out the difference between
the current date and the value provided task.
7. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
8. In the Task List window, double-click the TODO: Exercise 4: Task 2d: Convert this result into a number
of years task.
9. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
10. In the Task List window, double-click the TODO: Exercise 4: Task 2e: Convert the number of years into
a string and return it task.
11. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
return ageInYears.ToString();
}
else
{
return "";
}
X Task 3: Run the application and verify that the students age now appears correctly
1. On the Build menu, click Build Solution.
3. Verify that the application starts and displays the initial list of students, with their ages.
5. Press Insert.
6. In the new student window, enter your first name in the First Name box, your last name in the Last
Name box and your date of birth in the Date of Birth box.
7. Click OK and verify that your name and age display correctly in the student list.
8. Close the application.
Results: After completing this exercise, the application will display a students age in years.
MCT USE ONLY. STUDENT USE PROHIBITED
L02-1
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click School.sln, and then
click Open.
11. Double-click the TODO: Exercise 1: Task 1a: If the user double-clicks a student, edit the details for that
student task.
12. Above the comment, in the studentsList_Keydown method, locate the case Key.Enter: block, and
copy the following code to the clipboard:
student.DateOfBirth = DateTime.Parse(sf.dateOfBirth.Text);
// Enable saving (changes are not made permanent until they are written back to
the database)
saveChanges.IsEnabled = true;
}
13. Double-click the TODO: Exercise 1: Task 1a: If the user double-clicks a student, edit the details for the
student task.
14. Paste the code from the clipboard into studentsList_MouseDoubleClick method.
X Task 2: Run the application and verify that the user can now double-click a student
to edit their details
1. On the Build menu, click Build Solution.
2. On the Debug menu, click Start Without Debugging.
3. Click the row containing the name Kevin Liu and then press Enter.
4. Verify that the Edit Student Details window appears, displaying the correct details.
5. In the Last Name box, delete the existing contents, type Cook, and then click OK.
6. Verify that Liu has changed to Cook in the students list, and that the Save Changes button is now
enabled.
7. Double-click the row containing the name George Li.
8. Verify that the Edit Student Details window appears, displaying the correct details.
9. In the First Name box, delete the existing contents, and then type Darren.
10. In the Last Name box, delete the existing contents, type Parker, and then click OK.
X Task 3: Use the Analyze Solution for Code Clones wizard to detect the duplicated
code
1. On the Analyze menu, click Analyze Solution for Code Clones.
4. In the code editor, in the studentsList_MouseDoubleClick method, delete the following line of
code:
6. On the Edit menu, point to Refactor, and then click Extract Method.
7. In the Extract Method dialog box, in the New method name box, delete the existing contents, type
editStudent, and then click OK.
8. In the studentsList_MouseDoubleClick method, modify the call to the editStudent method to look
like the following code:
editStudent(this.studentsList.SelectedItem as Student);
9. Locate the editStudent method, and modify the method parameters to look like the following code:
Note: The generated method is located below the method that it was generated from.
10. In the Code Clone Analysis Results window, double-click the row containing the text
MainWindow:studentsList_KeyDown
11. In the code editor, in the studentsList_KeyDown method, in the case Key.Enter: block, delete the
code shown in step 5.
12. Click at the end of the Student student = this.studentsList.SelectedItem as Student; code line,
press Enter, and then type the following code:
editStudent(student);
13. Below the Code Clone Analysis Results window, click Task List.
X Task 4: Refactor the logic that adds and deletes a student into the addNewStudent
and deleteStudent methods
1. In the Task List window, double-click the TODO: Exercise 1: Task 4a: Refactor as the addNewStudent
method task.
2. In the code editor, locate the case Key.Insert: block, and then highlight the following code:
// When the user closes the form, retrieve the details of the student from the
form
// and use them to create a new Student object
Student newStudent = new Student();
newStudent.FirstName = sf.firstName.Text;
newStudent.LastName = sf.lastName.Text;
newStudent.DateOfBirth = DateTime.Parse(sf.dateOfBirth.Text);
// Assign the new student to the current teacher
this.teacher.Students.Add(newStudent);
// Add the student to the list displayed on the form
this.studentsInfo.Add(newStudent);
// Enable saving (changes are not made permanent until they are written back
to the database)
saveChanges.IsEnabled = true;
}
3. On the Edit menu, point to Refactor, and then click Extract Method.
4. In the Extract Method dialog box, in the New method name box, type addNewStudent, and then
click OK.
5. Locate the addnewStudent method and in the method, modify the sf = new StudentForm(); code
to look like the following code:
6. In the Task List window, double-click the TODO: Exercise 1: Task 4b: Refactor as the removeStudent
method task.
7. In the code editor, locate the case Key.Delete block, and cut the following code to the clipboard:
8. In the code editor, in the case Key.Delete: block, click at the end of student =
this.studentsList.SelectedItem as Student; code line, press Enter, then type the following code
removeStudent(student);
9. Right-click the removeStudent(student); method call, point to Generate, and then click Method
Stub.
10. Locate the removeStudent method below the studentsList_KeyDown method, delete all the
generated code in this method, and then paste the code from the clipboard.
X Task 5: Verify that students can still be added and removed from the application
1. On the Build menu, click Build Solution.
3. Click the row containing the name Kevin Liu, and then press Insert.
7. In the Date of Birth box, type 02/03/2006 and then click OK.
8. Verify that Dominik Dubicki has been added to the students list.
9. Click the row containing the name Run Liu, and then press Delete.
11. Click Yes, and then verify that Run Liu is removed from the students list.
X Task 6: Debug the application and step into the new method calls
1. In the code editor, locate the studentsList_KeyDown method, right-click on the switch (e.key)
statement, point to Breakpoint, and then click Insert Breakpoint.
3. Click the row containing the name Kevin Liu and press Enter.
4. In the Immediate window, click the Call Stack tab.
9. Repeat step 8.
10. Look at the Locals window, and note after stepping over the Student student =
this.studentsList.SelectedItem as Student; code, the value for the student variable has changed
from null to School.Data.Student.
11. In the Locals window, expand student and note the values for _FirstName and _LastName.
13. Note that execution steps into the editStudent method and that this method name has been added
to the Call Stack.
14. Look at the Locals window and note that the local variables have changed to this, student, and sf.
17. In the Locals window, expand sf and note the values for dateOfBirth, firstName, and lastName.
18. On the Debug menu, click Step Out to run the remaining code in the editStudent method and step
out again to the calling method.
23. Click the row containing the name Kevin Liu and press Insert.
24. On the Debug menu, click Step Over.
27. On the Debug menu, click Step Out to run the remaining code in the addNewStudent method and
step out again to the calling method.
37. On the Debug menu, click Step Out to run the remaining code in the removeStudent method and
step out again to the calling method.
Results: After completing this exercise, you should have updated the application to refactor duplicate
code into reusable methods.
MCT USE ONLY. STUDENT USE PROHIBITED
L02-7
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 2, click School.sln, and then
click Open.
3. On the Build menu, click Build Solution.
5. Click on the row containing the name Kevin Liu, and then press Insert.
6. Leave the First Name and Last Name boxes empty.
7. In the Date of Birth box, type 10/06/3012, and then click OK.
8. Verify that a new row has been added to the student list, containing a blank first name, blank last
name, and a negative age.
X Task 2: Add code to validate the first name and last name fields
1. In the Task List window, double-click the TODO: Exercise 2: Task 2a: Check that the user has provided
a first name task.
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
if (String.IsNullOrEmpty(this.firstName.Text))
{
MessageBox.Show("The student must have a first name", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Check that the user has provided
a last name task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
if (String.IsNullOrEmpty(this.lastName.Text))
{
MessageBox.Show("The student must have a last name", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
DateTime result;
MCT USE ONLY. STUDENT USE PROHIBITED
L02-8 Programming in Visual C#
3. In the Task List window, double-click the TODO: Exercise 2: Task 3b: Verify that the student is at least
5 years old task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 4: Run the application and verify that student information is now validated
correctly
1. On the Build menu, click Build Solution.
4. Leave the First Name, Last Name, and Date of Birth boxes empty and click OK.
5. Verify that an error message appears containing the text The student must have a first name.
7. In the new student window, in the First Name box, type Darren, and then click OK.
8. Verify that an error message appears containing the text The student must have a last name.
10. In the new student window, in the Last Name box, type Parker, and then click OK.
11. Verify that an error message appears containing the text The date of birth must be a valid date.
12. In the Error message box, click OK.
13. In the new student window, in the Date of Birth box, type 10/06/3012, and then click OK.
14. Verify that an error message appears containing the text The student must be at least 5 years old.
15. In the Error message box, click OK.
16. In the new student window, in the Date of Birth box, delete the existing date, type 10/06/2006, and
then click OK.
17. Verify that Darren Parker is added to the student list with an age appropriate to the current date.
Results: After completing this exercise, student data will be validated before it is saved.
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 3, click School.sln, and then
click Open.
3. On the Build menu, click Build Solution.
7. In the Last Name box, delete the existing contents, type Cook, and then click OK.
8. Verify that Liu has changed to Cook in the students list, and that the Save Changes button is now
enabled.
10. Click the row containing the student George Li, and then press Delete.
11. Verify that the confirmation prompt appears, and then click Yes.
12. Verify that George Li is removed from the student list, and then click Save Changes.
15. Verify that the application displays the original list of students.
16. Verify that Kevin Liu appears in the list instead of Kevin Cook and George Li is back in the student
list.
2. In the code editor, click in the blank line above the comment, and then type the following code:
using System.Data;
using System.Data.Objects;
3. In Visual Studio, in the Task List window, double-click the TODO: Exercise 3: Task 2b: Save the changes
by calling the SaveChanges method of the schoolContext object task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 3: Add exception handling to the code to catch concurrency, update, and
general exceptions
1. In the code editor, enclose the code that you wrote in the previous task in a try block. Your code
should look like the following:
try
{
// Save the changes
this.schoolContext.SaveChanges();
// Disable the Save button (it will be enabled if the user makes more changes)
saveChanges.isEnabled = false;
}
2. In the Task List window, double-click the TODO: Exercise 3: Task 3a: If an
OptimisticConcurrencyException occurs then another user has changed the same students earlier
then overwrite their changes with the new data (see the lab instructions for details) task.
3. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
catch (OptimisticConcurrencyException)
{
// If the user has changed the same students earlier, then overwrite their
changes with the new data
this.schoolContext.Refresh(
RefreshMode.StoreWins, schoolContext.Students);
this.schoolContext.SaveChanges();
}
4. In the Task List window, double-click the TODO: Exercise 3: Task 3b: If an UpdateException occurs
then report the error to the user and rollback (see the lab instructions for details) task.
5. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
6. In the Task List window, double-click the TODO: Exercise 3: Task 3c: If some other sort of error has
occurs, report the error to the user and retain the data so the user can try again - the error may be
transitory (see the lab instructions for details) task.
7. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 4: Run the application and verify that data changes are persisted to the
database
1. On the Build menu, click Build Solution.
4. Press Enter, in the Last Name box delete the existing contents, type Cook, and then click OK.
5. Verify that Liu has changed to Cook in the students list, and that the Save Changes button is now
enabled.
6. Click Save Changes and verify that the Save Changes button is now disabled.
7. Click the row containing the student George Li and press Delete.
8. Verify that the confirmation prompt appears, and then click Yes.
10. Click Save Changes and verify that the button is now disabled.
11. Close the application.
13. Verify that the changes you made to the student data have been saved to the database and are
reflected in the student list.
Results: After completing this exercise, modified student data will be saved to the database
MCT USE ONLY. STUDENT USE PROHIBITED
MCT USE ONLY. STUDENT USE PROHIBITED
L3-1
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click
GradesPrototype.sln, and then click Open.
10. Note that this is the main window for the application that will host the following views:
LogonPage.xaml
StudentProfile.xaml
StudentsPage.xaml
16. Notice that this view contains the list of students in a particular class. This view is displayed when a
teacher logs on. A teacher can click a students name and the Students Profile view will be displayed,
containing the selected students data.
X Task 2: Define the LogonSuccess event and add dummy code for the Logon_Click
event
1. On the View menu, click Task List.
MCT USE ONLY. STUDENT USE PROHIBITED
L3-2 Programming in Visual C#
3. Double-click the TODO: Exercise 1: Task 2a: Define the LogonSuccess event handler task.
4. In the code editor, click in the blank line below the comment, and then type the following code:
6. In the Task List window double-click the TODO: Exercise 1: Task 2b: Implement the Logon_Click
event handler for the Logon button task.
7. In the code editor, click in the blank line below the comments, and then type the following code:
9. In the XAML editor, locate the task TODO: Exercise 1: Task 2c: Specify that the Logon button
should raise the Logon_Click event handler in this view task.
10. In the line below the comment, modify the XAML markup <Button Grid.Row="3"
Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"
Content="Log on" FontSize="24" /> to look like the following markup:
2. In the code editor, click in the blank line in the GotoLogon method, and then type the following
code:
// Display the logon view and hide the list of students and single student view
logonPage.Visibility = Visibility.Visible;
studentsPage.Visibility = Visibility.Collapsed;
3. studentProfile.Visibility = Visibility.Collapsed;
4. In the Task List window, double-click the TODO: Exercise 1: Task 3b: Handle successful logon
task.
5. In the code editor, click in the blank line below the comments, and then type the following code:
MCT USE ONLY. STUDENT USE PROHIBITED
L3-3
8. In the line below the comment, modify the XAML markup <y:LogonPage x:Name="logonPage"
Visibility="Collapsed" /> to look like the following markup:
2. In the code editor, click in the blank line in the Refresh method, and then type the following code:
switch (SessionContext.UserRole)
{
case Role.Student:
// Display the student name in the banner at the top of the page
txtName.Text = string.Format("Welcome {0}", SessionContext.UserName);
// Display the details for the current student
GotoStudentProfile();
break;
case Role.Teacher:
// Display the teacher name in the banner at the top of the page
txtName.Text = string.Format("Welcome {0}", SessionContext.UserName);
// Display the list of students for the teacher
GotoStudentsPage();
break;
}
3. In the Task List window, double-click the TODO: Exercise 1: Task 4b: Display the details for a
single student task.
4. In the code editor, click in the blank line in the GotoStudentProfile method, and then type the
following code:
5. In the Task List window, double-click the TODO: Exercise 1: Task 4c: Display the list of students
task.
6. In the code editor, click in the blank line in the GotoStudentsPage method, and then type the
following code:
MCT USE ONLY. STUDENT USE PROHIBITED
L3-4 Programming in Visual C#
7. In the Task List window, double-click the TODO: Exercise 1: Task 4d: Display the details for the
current student including the grades for the student task.
8. In the code editor, click in the blank line in the Refresh method, and then type the following code:
// Parse the student name into the first name and last name by using a regular
expression
// The firstname is the initial string up to the first space character.
// The lastname is the string after the space character
Match matchNames = Regex.Match(SessionContext.CurrentStudent, @"([^ ]+) ([^ ]+)");
if (matchNames.Success)
{
string firstName = matchNames.Groups[1].Value; // Indexing in the Groups
collection starts at 1, not 0
string lastName = matchNames.Groups[2].Value;
// Display the first name and last name in the TextBlock controls in the
studentName StackPanel
((TextBlock)studentName.Children[0]).Text = firstName;
((TextBlock)studentName.Children[1]).Text = lastName;
}
// If the current user is a student, hide the Back button
// (only applicable to teachers who can use the Back button to return to the list of
students)
if (SessionContext.UserRole == Role.Student)
{
btnBack.Visibility = Visibility.Hidden;
}
else
{
btnBack.Visibility = Visibility.Visible;
}
2. In the code editor, click in the blank line in the Student_Click method, and then type the following
code:
3. In the Task List window, double-click the TODO: Exercise 1: Task 5b: Handle the StudentSelected
event when the user clicks a student on the Students page task.
MCT USE ONLY. STUDENT USE PROHIBITED
L3-5
4. In the code editor, click in the blank line in the studentsPage_StudentSelected method, and then
type the following code:
SessionContext.CurrentStudent = e.Child;
GotoStudentProfile();
6. In the XAML editor, locate the task TODO: Exercise 1: Task 5c: Catch the StudentSelected event
and call the studentsPage_StudentSelected event handler task.
7. In the line below the comment, modify the XAML markup <y:StudentsPage
x:Name="studentsPage" Visibility="Collapsed" /> to look like the following markup:
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password.
4. Select the Teacher check box, and then click Log on.
5. Verify that the application displays the StudentPage view.
9. Clear the Teacher check box, and then click Log on.
10. Verify that the application displays the student profile page for Eric Gruber.
11. Close the application.
Results: After completing this exercise, you should have updated the Grades Prototype application to
respond to user events and move among the application views appropriately.
MCT USE ONLY. STUDENT USE PROHIBITED
L3-7
4. In the Task List window, double-click the TODO: Exercise 2: Task 1a: Create the Grade struct task.
5. In the code editor, click in the blank line below the comment, and then type the following code:
6. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Create the Student struct
task.
7. In the code editor, click in the blank line below the comment, and then type the following code:
8. In the Task List window, double-click the TODO: Exercise 2: Task 1c: Create the Teacher struct
task.
9. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
X Task 2: Add unit tests to create and use the collections of structs
1. On the File menu, point to Add, and then click New Project.
2. In the Add New Project dialog box, in the Installed Templates list, click Test, and then in the
Templates list, click Unit Test Project.
10. In the code editor, click at the end of the line of the code using
Microsoft.VisualStudio.TestTools.UnitTesting; and then press Enter.
11. Type the following code:
using GradesPrototype.Data;
12. In the GradesUnitTests class, delete all of the existing code and then type the following code:
[TestMethod]
public void StudentTest()
{
Student student = new Student()
{
FirstName = "Eric",
LastName = "Gruber",
UserName = "grubere",
Password = "password"
};
Assert.AreEqual("Eric", student.FirstName);
Assert.AreEqual("Gruber", student.LastName);
Assert.AreEqual("grubere", student.UserName);
Assert.AreEqual("password", student.Password);
}
[TestMethod]
public void TeacherTest()
{
Teacher teacher = new Teacher()
{
FirstName = "Esther",
LastName = "Valle",
UserName = "vallee",
Password = "password",
Class = "3A"
};
Assert.AreEqual("Esther", teacher.FirstName);
Assert.AreEqual("Valle", teacher.LastName);
Assert.AreEqual("vallee", teacher.UserName);
Assert.AreEqual("password", teacher.Password);
Assert.AreEqual("3A", teacher.Class);
}
private Grade createGrade(string assessment, string subject, string comments)
{
Grade grade = new Grade();
grade.AssessmentDate = string.Format("{0:d}", DateTime.Now);
grade.Assessment = assessment;
grade.SubjectName = subject;
grade.Comments = comments;
return grade;
}
[TestMethod]
public void GradeTest()
{
MCT USE ONLY. STUDENT USE PROHIBITED
L3-9
14. On the Test menu, point to Run, and then click All Tests.
15. In the Test Explorer window, verify that all the tests are passed.
Results: After completing this exercise, the application will contain structs for the teacher, student, and
grade types.
MCT USE ONLY. STUDENT USE PROHIBITED
L3-10 Programming in Visual C#
4. In the code editor, expand the region Sample Data, and then locate the method CreateData.
5. Note how the Teachers ArrayList is populated with Teacher data, each containing TeacherID,
UserName, Password, FirstName, LastName, and Class fields.
6. Note how the Students ArrayList is populated with Student data, each containing a StudentID,
UserName, Password, TeacherID, FirstName, and LastName fields.
7. Note how the Grades ArrayList is populated with Grade data, each containing a StudentID,
AssessmentDate, SubjectName, Assessment, and Comments fields.
2. In the code editor, click in the blank line below the comment, and then type the following code:
3. In the Task List window, double-click the TODO: Exercise 3: Task 2b: Validate the username and
password against the Users collection in the MainWindow window task.
4. In the code editor, in the Logon_Click method, click in the blank line, and then type the following
code:
// Find the user in the list of possible users - first check whether the user is a
Teacher
var teacher = (from Teacher t in DataSource.Teachers
where String.Compare(t.UserName, username.Text) == 0
&& String.Compare(t.Password, password.Password) == 0
select t).FirstOrDefault();
// If the UserName of the user retrieved by using LINQ is non-empty then the user is
a teacher
if (!String.IsNullOrEmpty(teacher.UserName))
{
// Save the UserID and Role (teacher or student) and UserName in the global
context
SessionContext.UserID = teacher.TeacherID;
SessionContext.UserRole = Role.Teacher;
SessionContext.UserName = teacher.UserName;
SessionContext.CurrentTeacher = teacher;
// Raise the LogonSuccess event and finish
LogonSuccess(this, null);
return;
}
// If the user is not a teacher, check whether the username and password match those
of a student
else
{
var student = (from Student s in DataSource.Students
where String.Compare(s.UserName, username.Text) == 0
&& String.Compare(s.Password, password.Password) == 0
MCT USE ONLY. STUDENT USE PROHIBITED
L3-11
select s).FirstOrDefault();
// If the UserName of the user retrieved by using LINQ is non-empty then the user
is a student
if (!String.IsNullOrEmpty(student.UserName))
{
// Save the details of the student in the global context
SessionContext.UserID = student.StudentID;
SessionContext.UserRole = Role.Student;
SessionContext.UserName = student.UserName;
SessionContext.CurrentStudent = student;
// Raise the LogonSuccess event and finish
LogonSuccess(this, null);
return;
}
}
// If the credentials do not match those for a Teacher or for a Student then they
must be invalid
// Raise the LogonFailed event
LogonFailed(this, null);
2. In the code editor, click in the blank line below the comments, and then type the following code:
5. In the line below the comment, modify the XAML markup <y:LogonPage x:Name="logonPage"
LogonSuccess="Logon_Success" Visibility="Collapsed" /> to look like the following markup:
6. In the Task List window, double-click the TODO: Exercise 3: Task 3c: Display the student name in
the banner at the top of the page task.
7. In the code editor, click in the blank line below the comment, and then type the following code:
// Display the student name in the banner at the top of the page
txtName.Text = string.Format("Welcome {0} {1}",
SessionContext.CurrentStudent.FirstName, SessionContext.CurrentStudent.LastName);
8. In the Task List window, double-click the TODO: Exercise 3: Task 3d: Display the teacher name in
the banner at the top of the page task.
9. In the code editor, click in the blank line below the comment, and then type the following code:
// Display the teacher name in the banner at the top of the page
txtName.Text = string.Format("Welcome {0} {1}",
SessionContext.CurrentTeacher.FirstName, SessionContext.CurrentTeacher.LastName);
MCT USE ONLY. STUDENT USE PROHIBITED
L3-12 Programming in Visual C#
2. In the XAML editor, locate the ItemsControl named list and note how data binding is used to display
the name of each student.
Note: DataBinding is also used to retrieve the StudentID of a student. This binding is used
when a user clicks on a Student on the Student Page list to identify which students data to
display in the Student Profile page.
3. In the Task List window, double-click the TODO: Exercise 3: Task 4a: Display students for the
current teacher (held in SessionContext.CurrentTeacher) task.
4. In the code editor, in the Refresh method, click in the blank line, and then type the following code:
5. In the Task List window, double-click the TODO: Exercise 3: Task 4b: If the user clicks on a
student, display the details for that student task.
6. In the code editor, in the Student_Click method, click in the blank line, and then type the following
code:
7. In the Task List window, double-click the TODO: Exercise 3: Task 4c: Set the current student in
the global context to the student specified in the StudentEventArgs parameter task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
SessionContext.CurrentStudent = e.Child;
MCT USE ONLY. STUDENT USE PROHIBITED
L3-13
// Bind the studentName StackPanel to display the details of the student in the
TextBlocks in this panel
studentName.DataContext = SessionContext.CurrentStudent;
// If the current user is a student, hide the Back button
// (only applicable to teachers who can use the Back button to return to the list of
students)
if (SessionContext.UserRole == Role.Student)
{
btnBack.Visibility = Visibility.Hidden;
}
else
{
btnBack.Visibility = Visibility.Visible;
}
5. In the line below the comment, modify the XAML markup <TextBlock x:Name="firstName"
FontSize="16" /> to look like the following markup:
6. In the XAML editor, locate the task TODO: Exercise 3: Task 5c: Bind the lastName TextBlock to
the LastName property of the DataContext for this control task.
7. In the line below the comment, modify the XAML markup <TextBlock x:Name="lastName"
FontSize="16" /> to look like the following markup:
8. In the Task List window, double-click the TODO: Exercise 3: Task 5d: Create a list of the grades
for the student and display this list on the page task.
9. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
3. When the application loads, in the Username box, type parkerd, in the Password box, type
password, and then click Log on.
4. Verify that the Logon Failed dialog box appears, and then click OK.
5. In the Username box, delete the existing contents, type vallee, and then click Log on.
9. In the Username box, delete the existing contents, type grubere, and then click Log on.
10. Verify that the Student Profile page for Eric Gruber is displayed.
Results: After completing this exercise, only valid users will be able to log on to the application and they
will see only data appropriate to their role.
MCT USE ONLY. STUDENT USE PROHIBITED
L4-1
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click
GradesPrototype.sln, and then click Open.
10. Double-click the TODO: Exercise 1: Task 1a: Convert Grade into a class and define constructors
task.
11. In the code editor, below the comment, modify the public struct Grade declaration, replacing struct
with class.
12. Click at the end of the code public string Comments { get; set; }, press Enter twice, and then type
the following code:
AssessmentDate = DateTime.Now.ToString("d");
SubjectName = "Math";
Assessment = "A";
Comments = String.Empty;
}
3. In the code editor, below the comment, modify the public struct Student declaration, replacing
struct with class.
Note: An application should not be able to read passwords; only set them and verify that a
password is correct.
6. Click at the end of the code public string LastName { get; set; }, press Enter twice, and then type
the following code:
FirstName = String.Empty;
LastName = String.Empty;
TeacherID = 0;
}
8. Double-click the TODO: Exercise 1: Task 2b: Convert Teacher into a class, make the password
property write-only, add the VerifyPassword method, and define constructors task.
9. In the code editor, below the comment, modify the public struct Teacher declaration, replacing
struct with class.
12. Click at the end of the code public string Class {get; set;}, press Enter twice, and then type the
following code:
X Task 3: Use the VerifyPassword method to verify the password when a user logs in
1. In the Task List window, double-click the TODO: Exercise 1: Task 3a: Use the VerifyPassword
method of the Teacher class to verify the teachers password task.
2. In the code editor, below the comment, in the code for the teacher variable, modify the
String.Compare(t.Password, password.Password) == 0 code to look like the following code:
t.VerifyPassword(password.Password)
3. In the Task List window, double-click the TODO: Exercise 1: Task 3b: Check whether teacher is null
before examining the UserName property task.
4. In the code editor, in the line below the comment, modify the if statement condition from
!String.IsNullOrEmpty(teacher.UserName) to look like the following code:
5. In the Task List window, double-click the TODO: Exercise 1: Task 3c: Use the VerifyPassword
method of the Student class to verify the students password task.
6. In the code editor, below the comment, in the code for the student variable, modify the
String.Compare(s.Password, password.Password) == 0 code to look like the following code:
7. s.VerifyPassword(password.Password)
8. In the Task List window, double-click the TODO: Exercise 1: Task 3d: Check whether student is
null before examining the UserName property task.
9. In the code editor, in the line below the comment, modify the if statement condition from
!String.IsNullOrEmpty(student.UserName) to look like the following code:
X Task 4: Build and run the application, and verify that a teacher or student can still log
on
1. On the Build menu, click Build Solution.
5. Verify that the welcome screen appears, displaying the list of students
8. Verify that the welcome screen appears, displaying the list of subjects and grades.
Results: After completing this exercise, the Teacher, Student, and Grade structs will be implemented as
classes and the VerifyPassword method will be called when a user logs on.
MCT USE ONLY. STUDENT USE PROHIBITED
L4-6 Programming in Visual C#
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
5. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Populate the list of valid
subjects with sample data task.
6. In the code editor, in the blank line below the comment, type the following code:
X Task 2: Add validation logic to the Grade class to check the data entered by the user
1. In the Task List window, double-click the TODO: Exercise 2: Task 2a: Add validation to the
AssessmentDate property task.
2. In the code editor under comment, delete the public string AssessmentDate { get; set; } code, and
then type the following code:
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Add validation to the
SubjectName property task.
4. In the code editor, below the comment, delete the public string SubjectName { get; set; } code,
and then type the following code:
5. In the Task List window, double-click the TODO: Exercise 2: Task 2c: Add validation to the
Assessment property task.
6. In the code editor, delete the public string Assessment { get; set; } code, and then type the
following code:
X Task 3: Add a unit test to verify that the validations defined for the Grade class
functions as expected.
1. On the File menu, point to Add, and then click New Project.
2. In the Add New Project dialog box, in the Installed templates list, expand Visual C#, click Test, and
then in the Templates list, click Unit Test Project.
7. In the code editor, in the UnitTest1 class, delete all of the existing code, and then type the following
code:
[TestInitialize]
public void Init()
{
// Create the data source (needed to populate the Subjects collection)
GradesPrototype.Data.DataSource.CreateData();
}
[TestMethod]
public void TestValidGrade()
{
GradesPrototype.Data.Grade grade = new GradesPrototype.Data.Grade(1, "1/1/2012",
"Math", "A-", "Very good");
Assert.AreEqual(grade.AssessmentDate, "1/1/2012");
Assert.AreEqual(grade.SubjectName, "Math");
Assert.AreEqual(grade.Assessment, "A-");
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestBadDate()
{
// Attempt to create a grade with a date in the future
GradesPrototype.Data.Grade grade = new GradesPrototype.Data.Grade(1, "1/1/2023",
"Math", "A-", "Very good");
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void TestDateNotRecognized ()
{
// Attempt to create a grade with an unrecognized date
GradesPrototype.Data.Grade grade = new GradesPrototype.Data.Grade(1,
"13/13/2012", "Math", "A-", "Very good");
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void TestBadAssessment()
{
// Attempt to create a grade with an assessment outside the range A+ to E-
GradesPrototype.Data.Grade grade = new GradesPrototype.Data.Grade(1, "1/1/2012",
"Math", "F-", "Terrible");
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void TestBadSubject()
{
// Attempt to create a grade with an unrecognized subject
GradesPrototype.Data.Grade grade = new GradesPrototype.Data.Grade(1, "1/1/2012",
"French", "B-", "OK");
MCT USE ONLY. STUDENT USE PROHIBITED
L4-9
9. On the Test menu, point to Run, and then click All Tests.
10. In the Test Explorer window, verify that all the tests are passed.
Results: After completing this exercise, the Grade class will contain validation logic.
MCT USE ONLY. STUDENT USE PROHIBITED
L4-10 Programming in Visual C#
7. Verify that the students are not displayed in any specific order.
2. In the code editor, click at the end of the public class Student declaration, and then type the
following code:
: IComparable<Student>
3. In the Task List window, double-click the TODO: Exercise 3: Task 2b: Compare Student objects
based on their LastName and FirstName properties task.
4. In the code editor, in the blank line below the comment, type the following code:
3. In the Task List window, double-click the TODO: Exercise 3: Task 3b: Populate the List<Student>
collection task.
MCT USE ONLY. STUDENT USE PROHIBITED
L4-11
4. In the code editor, below the comment, modify the Students = new ArrayList() code to look like the
following code:
2. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
DataSource.Students.Sort();
X Task 5: Verify that Students are retrieved and displayed in order of their first name
and last name
1. On the Build menu, click Build Solution.
4. In the Password box, type password, and then click Log on.
5. Verify that the students are displayed in order of ascending last name.
6. Log off and then close the application.
Results: After completing this exercise, the application will display the students in alphabetical order of
last name and then first name.
MCT USE ONLY. STUDENT USE PROHIBITED
L4-12 Programming in Visual C#
4. In the code editor, below the comment, modify the code public static ArrayList Teachers; to look
like the following code:
5. In the Task List window, double-click the TODO: Exercise 4: Task 1b: Change the Grades collection
into a generic List task.
6. In the code editor, below the comment, modify the code public static ArrayList Grades; to look like
the following code:
7. In the Task List window, double-click the TODO: Exercise 4: Task 1c: Populate the Teachers
collection task.
8. In the code editor, below the comment, modify the code Teachers = new ArrayList() to look like the
following code:
9. In the Task List window, double-click the TODO: Exercise 4: Task 1d: Populate the Grades
collection task.
10. In the code editor, below the comment, modify the code Grades = new ArrayList()to look like the
following code:
X Task 2: Add the EnrollInClass and RemoveFromClass methods for the Teacher class
1. In the Task List window, double-click the TODO: Exercise 4: Task 2a: Enroll a student in the class
for this teacher task.
2. In the code editor, click in the blank line below the comment, and then type the following code:
}
}
3. In the Task List window, double-click the TODO: Exercise 4: Task 2b: Remove a student from the
class for this teacher task.
4. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
5. In the Task List window, double-click the TODO: Exercise 4: Task 2c: Add a grade to a student (the
grade is already populated) task.
6. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
2. In the code editor, below the comment, click in the blank line in the Student_Click method, and then
type the following code:
try
{
// Determine which student the user clicked
// the StudentID is held in the Tag property of the Button that the user clicked
Button studentClicked = sender as Button;
MCT USE ONLY. STUDENT USE PROHIBITED
L4-14 Programming in Visual C#
3. In the Task List window, double-click the TODO: Exercise 4: Task 3b: Refresh the display of
unassigned students task.
4. In the code editor, below the comment, click in the blank line in the Refresh method, and then type
the following code:
5. In the Task List window, double-click the TODO: Exercise 4: Task 3c: Enroll a student in the
teachers class task.
6. In the code editor, below the comment, click in the blank line in the EnrollStudent_Click method,
and then type the following code:
MCT USE ONLY. STUDENT USE PROHIBITED
L4-15
// Use the AssignStudentDialog to display unassigned students and add them to the
teachers class
// All of the work is performed in the code behind the dialog
AssignStudentDialog asd = new AssignStudentDialog();
asd.ShowDialog();
// Refresh the display to show any newly enrolled students
Refresh();
X Task 4: Add code to enable a teacher to remove the student from the assigned class
1. In the Task List window, double-click the TODO: Exercise 4: Task 4a: Enable a teacher to remove a
student from a class task.
2. In the code editor, below the comment, click in the blank line in the Remove_Click method, and then
type the following code:
// If the user is not a teacher, do nothing (the button should not appear anyway)
if (SessionContext.UserRole != Role.Teacher)
{
return;
}
try
{
// If the user is a teacher, ask the user to confirm that this student should be
removed from their class
string message = String.Format("Remove {0} {1}",
SessionContext.CurrentStudent.FirstName, SessionContext.CurrentStudent.LastName);
MessageBoxResult reply = MessageBox.Show(message, "Confirm",
MessageBoxButton.YesNo, MessageBoxImage.Question);
// If the user confirms, then call the RemoveFromClass method of the current
teacher to remove this student from their class
if (reply == MessageBoxResult.Yes)
{
SessionContext.CurrentTeacher.RemoveFromClass(SessionContext.CurrentStudent);
// Go back to the previous page the student is no longer a member of the
class for the current teacher
if (Back != null)
{
Back(sender, e);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error removing student from class",
MessageBoxButton.OK, MessageBoxImage.Error);
}
2. In the code editor, below the comment, click in the blank line in the AddGrade_Click method, and
then type the following code:
// If the user is not a teacher, do nothing (the button should not appear anyway)
if (SessionContext.UserRole != Role.Teacher)
{
return;
}
try
{
// Use the GradeDialog to get the details of the assessment grade
MCT USE ONLY. STUDENT USE PROHIBITED
L4-16 Programming in Visual C#
X Task 6: Run the application and verify that students can be added to and removed
from classes, and that grades can be added to students
1. On the Build menu, click Build Solution.
4. In the Password box, type password, and then click Log on.
10. Verify that the Assign Student dialog box appears and that Darren Parker is in the list.
12. Verify that the Confirm message box appears, and then click Yes.
13. In the Assign Student dialog box, verify that Darren Parker disappears and that the text "No
unassigned students" is displayed.
14. Click Close.
18. Verify that the Confirm message box appears, and then click Yes.
19. Verify that Kevin Liu is removed from the student list.
MCT USE ONLY. STUDENT USE PROHIBITED
L4-17
23. Verify that the Date box contains the current date.
26. In the Comments box, type Good, and then click OK.
27. Verify that the grade information appears on the Report Card.
Results: After completing this exercise, the application will enable teachers to add and remove students
from their classes, and to add grades to students.
MCT USE ONLY. STUDENT USE PROHIBITED
MCT USE ONLY. STUDENT USE PROHIBITED
L5-1
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click GradesPrototype.sln, and
then click Open.
10. Double-click the TODO: Exercise 1: Task 1a: Create the User abstract class with the common
functionality for Teachers and Students task.
11. In the code editor, click at the end of the comment, press Enter, and then type the following code:
12. Click at the end of the last comment in the block (before the Grade class declaration), press Enter, and
then type the following code:
13. In the Task List window, double click the TODO: Exercise 1: Task 1b: Add the UserName property to
the User class task.
14. In the code editor, click at the end of the comment, press Enter, and then type the following code:
15. In the Task List window, double click the TODO: Exercise 1: Task 1c: Add the Password property to the
User class task.
16. In the code editor, click at the end of the comment, press Enter, and then type the following code:
set
{
_password = value;
}
}
17. In the Task List window, double click the TODO: Exercise 1: Task 1d: Add the VerifyPassword method
to the User class task.
18. In the code editor, click at the end of the comment, press Enter, and then type the following code:
X Task 2: Modify the Student and Teacher classes to inherit from the User class
1. In the Task List window, double-click the TODO: Exercise 1: Task 2a: Inherit from the User class task.
2. In the code editor, modify the statement below this comment as shown below in bold:
3. In the Task List window, double-click the TODO: Exercise 1: Task 2b: Remove the UserName property
(now inherited from User) task.
4. In the code editor, delete the following statement from below the comment:
5. In the Task List window, double-click the TODO: Exercise 1: Task 2c: Remove the Password property
(now inherited from User) task.
6. In the code editor, delete the following block of code from below the comment:
7. In the Task List window, double-click the TODO: Exercise 1: Task 2d Remove the VerifyPassword
method (now inherited from User) task.
8. In the code editor, delete the following method from below the comment:
9. In the Task List window, double-click the TODO: Exercise 1: Task 2e: Inherit from the User class task.
10. In the code editor, modify the statement below this comment as shown below in bold:
11. In the Task List window, double-click the TODO: Exercise 1: Task 2f: Remove the UserName property
(now inherited from User) task.
12. In the code editor, delete the following statement from below the comment:
13. In the Task List window, double-click the TODO: Exercise 1: Task 2g: Remove the Password property
(now inherited from User) task.
14. In the code editor, delete the following block of code from below the comment:
15. In the Task List window, double-click the TODO: Exercise 1: Task 2h Remove the VerifyPassword
method (now inherited from User) task.
16. In the code editor, delete the following method from below the comment:
3. When the application starts, in the Username box, type vallee, in the Password box, type password,
and then click Log on.
4. Verify that the list of students for teacher Esther Valle is displayed.
5. Click Kevin Liu, and verify that the report card displaying the grades for Kevin Liu is displayed.
6. Click Log off.
7. In the Username box, type liuk, in the Password box, type password, and then click Log on.
8. Verify that the report card showing the grades for Kevin Liu is displayed again.
9. Click Log off.
Results: After completing this exercise, you should have removed the duplicated code from the Student
and Teacher classes, and moved the code to an abstract base class called User.
MCT USE ONLY. STUDENT USE PROHIBITED
L5-4 Programming in Visual C#
5. Double-click the TODO: Exercise 2: Task 1a: Define an abstract method for setting the password task.
6. In the code editor, review the comment below this line, click at the end of the comment, press Enter,
and then type the following code:
7. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Use the SetPassword method to
set the password task.
8. In the code editor, delete the following statement:
_password = value;
9. Add the following block of code in the place of the statement that you just deleted:
if (!SetPassword(value))
{
throw new ArgumentException("Password not complex enough", "Password");
}
X Task 2: Implement the SetPassword method in the Student and Teacher classes
1. In the Task List window, double-click the TODO: Exercise 2: Task 2a: Make _password a protected field
rather than private task.
2. In the code editor, modify the statement below the comment as shown below in bold:
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Implement SetPassword to set
the password for the student task.
4. In the code editor, review the comment below this line, click at the end of the comment, press Enter,
and then type the following code:
5. In the Task List window, double-click the TODO: Exercise 2: Task 2c: Implement SetPassword to set the
password for the teacher task.
6. In the code editor, review the comment below this line, click at the end of the comment, press Enter,
and then type the following code:
if (!newStudent.SetPassword(sd.password.Text))
{
throw new Exception("Password must be at least 6 characters long. Student not
created");
}
3. In the XAML pane, scroll down to line 27 and review the following block of XAML code:
5. In the code editor, expand the Event Handlers region, and locate the ChangePassword_Click
method.
// When the user closes the dialog by using the OK button, the password
should have been changed
// Display a message to confirm
MessageBox.Show("Password changed", "Password", MessageBoxButton.OK,
MessageBoxImage.Information);
}
}
// If the user clicks OK to change the password, validate the information that the
user has provided
private void ok_Click(object sender, RoutedEventArgs e)
{
// TODO: Exercise 2: Task 4a: Get the details of the current user
// TODO: Exercise 2: Task 4b: Check that the old password is correct for the
current user
// TODO: Exercise 2: Task 4c: Check that the new password and confirm password
fields are the same
// TODO: Exercise 2: Task 4d: Attempt to change the password
// If the password is not sufficiently complex, display an error message
// Indicate that the data is valid
this.DialogResult = true;
}
10. In the Task List window, double-click the TODO: Exercise 2: Task 4a: Get the details of the current user
task.
11. In the code editor, in the blank line below this comment, type the following code:
User currentUser;
if (SessionContext.UserRole == Role.Teacher)
{
currentUser = SessionContext.CurrentTeacher;
}
else
{
currentUser = SessionContext.CurrentStudent;
}
12. In the Task List window, double-click the TODO: Exercise 2: Task 4b: Check that the old password is
correct for the current user task.
13. In the code editor, in the blank line below this comment, type the following code:
14. In the Task List window, double-click the TODO: Exercise 2: Task 4c: Check that the new password and
confirm password fields are the same task.
15. In the code editor, in the blank line below this comment, type the following code:
16. In the Task List window, double-click the TODO: Exercise 2: Task 4d: Attempt to change the password
task.
17. In the code editor, review the comment below this line, click at the end of the comment, press Enter,
and then type the following code:
if (!currentUser.SetPassword(newPwd))
{
MessageBox.Show("The new password is not sufficiently complex", "Error",
MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
X Task 5: Run the application and test the change password functionality
1. On the Build menu, click Build Solution.
3. When the application starts, in the Username box, type vallee, in the Password box, type
password99, and then click Log on.
6. Verify that the message The password is not sufficiently complex is displayed, and then click OK.
7. In the New Password box, type password101, in the Confirm box, type password101, and then
click OK.
8. Verify that the message Password changed is displayed, and then click OK.
10. In the Username box, type vallee, in the Password box, type password101, and then click Log on.
13. Verify that the message Password must be at least 6 characters long. Student not created appears,
and then click OK.
15. In the New Student Details window, in the First Name box, type Luka, in the Last Name box, type
Abrus, in the Password box, type abcdef, and then click OK.
17. In the Assign Student window, verify that the student Luka Abrus appears.
18. Click Close.
Results: After completing this exercise, you should have implemented a polymorphic method named
SetPassword that exhibits different behavior for students and teachers. You will also have modified the
application to enable users to change their passwords.
MCT USE ONLY. STUDENT USE PROHIBITED
L5-9
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 3, click GradesPrototype.sln, and
then click Open.
3. In Visual Studio, on the View menu, click Task List.
5. Double-click the TODO: Exercise 3: Task 1a: Add custom data: the name of the class that is full task.
6. In the code editor, review the comment below this task, click at the end of the comment, press Enter,
and then type the following code:
7. In the Task List window, double-click the TODO: Exercise 3: Task 1b: Delegate functionality for the
common constructors directly to the Exception class task.
8. In the code editor, click at the end of the comment, press Enter, and then type the following code:
public ClassFullException()
{
}
public ClassFullException(string message)
: base(message)
{
}
public ClassFullException(string message, Exception inner)
: base(message, inner)
{
}
9. In the Task List window, double-click the TODO: Exercise 3: Task 1c: Add custom constructors that
populate the _className field. task.
10. In the code editor, review the comment below this task, click at the end of the comment, press Enter,
and then type the following code:
2. In the code editor, click at the end of the comment, press Enter, and then type the following code:
3. In the Task List window, double-click the TODO: Exercise 3: Task 2b: If the class is already full, then
another student cannot be enrolled task.
4. In the code editor, review the comment below this task, click at the end of the comment, press Enter,
and then type the following code:
if (numStudents == MAX_CLASS_SIZE)
{
// Throw a ClassFullException and specify the class that is full
throw new ClassFullException("Class full: Unable to enroll student", Class);
}
5. In the Task List window, double-click the TODO: Exercise 3: Task 2c: Catch and handle the
ClassFullException task.
6. In the code editor, click at the end of the comment, press Enter, and then type the following code:
3. When the application starts, in the Username box, type vallee, in the Password box, type
password99, and then click Log on.
4. In The School of Fine Arts window, click New Student.
5. In the New Student Details window, enter the following details, and then click OK.
Field Value
Password abcdef
Note: New students will not be listed in the main application window because this displays
students in the users class, and the new students have yet to be assigned to a class.
7. In the New Student Details window, enter the following details, and then click OK.
MCT USE ONLY. STUDENT USE PROHIBITED
L5-11
Field Value
Password abcdef
9. In the New Student Details window, enter the following details, and then click OK.
Field Value
Password abcdef
Field Value
Password abcdef
21. Verify that the message Class full: Unable to enroll student: Class: 3C is displayed, and then click
OK.
Results: After completing this exercise, you should have created a new custom exception class and used it
to report when too many students are enrolled in a class.
MCT USE ONLY. STUDENT USE PROHIBITED
L06-1
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click GradesPrototype.sln, and
then click Open.
9. Note that this view displays and enables users to add grades for a student. The solution has been
updated to include a Save Report button that users will click to generate and save the Grades
Report.
11. In the Task List window, in the Categories list, click Comments.
12. Double-click the TODO: Exercise 1: Task 1a: Use a SaveFileDialog to prompt the user for a filename to
save the report as (must be an XML file) task.
13. In the code editor, click in the blank line below the comment, and then type the following code:
14. Click at the end of the last comment in this method, press Enter, and then type the following code:
15. In the Task List window, double-click the TODO: Exercise 1: Task 1b: Get the grades for the currently
selected student task.
16. In the code editor, click in the blank line below the comment, and then type the following code:
select g).ToList();
17. In the Task List window, double-click the TODO: Exercise 1: Task 1c: Serialize the grades to a
MemoryStream task.
18. In the code editor, click at the end of the comment, press Enter, and then type the following code:
MemoryStream ms = FormatAsXMLStream(grades);
3. In the Task List window, double-click the TODO: Exercise 1: Task 2b: Create the root node of the XML
document. task.
4. In the code editor, click in the blank line below this and the next comment, and then type the
following code:
writer.WriteStartDocument();
writer.WriteStartElement("Grades");
writer.WriteAttributeString("Student", String.Format("{0} {1}",
SessionContext.CurrentStudent.FirstName, SessionContext.CurrentStudent.LastName));
5. In the Task List window, double-click the TODO: Exercise 1: Task 2c: Format the grades for the student
and add them as child elements of the root node task.
6. In the code editor, click in the blank line below this and the next comment, and then type the
following code:
7. In the Task List window, double-click the TODO: Exercise 1: Task 2d: Finish the XML document with
the appropriate end elements task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
writer.WriteEndElement();
writer.WriteEndDocument();
9. In the Task List window, double-click the TODO: Exercise 1: Task 2e: Flush the XmlWriter and close it
to ensure that all the data is written to the MemoryStream task.
10. In the code editor, click in the blank line below the comment, and then type the following code:
writer.Flush();
writer.Close();
MCT USE ONLY. STUDENT USE PROHIBITED
L06-3
11. In the Task List window, double-click the TODO: Exercise 1: Task 2f: Reset the MemoryStream so it can
be read from the start and then return it task.
12. In the code editor, click in the blank line below the comment, and then type the following code:
ms.Seek(0, SeekOrigin.Begin);
return ms;
13. Delete the following line of code from the end of the method:
2. In the Task List window, double-click the TODO: Exercise 1: Task 1c: Serialize the grades to a
MemoryStream task.
3. In the code editor, select the closing brace immediately below the following line of code:
MemoryStream ms = FormatAsXMLStream(grades);
7. In the Password box, type password99, and then click Log on.
Note: You will write the code to actually save the report to disk in Exercise 3 of this lab.
11. When you enter Break Mode, in the Immediate Window, type the following code, and then press
Enter.
?(new StreamReader(ms)).ReadToEnd()
12. Review the grade data formatted as XML that is returned to the Immediate Window.
Results: After completing this exercise, users will be able to specify the location for the Grades Report file.
MCT USE ONLY. STUDENT USE PROHIBITED
L06-4 Programming in Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 2, click GradesPrototype.sln, and
then click Open.
3. On the View menu, click Task List.
5. Double-click the TODO: Exercise 2: Task 1a: Generate a string representation of the report data task.
6. In the code editor, click in the blank line below the comment, and then type the following code:
8. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Preview the string version of the
report data in a MessageBox task.
9. In the code editor, click in the blank line below the comment, and then type the following code:
2. In the code editor, click in the blank line below the comment, and then type the following code:
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Use an XmlTextReader to read
the XML data from the stream task.
4. In the code editor, click in the blank line below the comment, and then type the following code:
5. In the Task List window, double-click the TODO: Exercise 2: Task 2c: Read and process the XML data a
node at a time task.
6. In the code editor, click in the blank line below the comment, and then type the following code:
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.XmlDeclaration:
// The node is an XML declaration such as <?xml
version='1.0'>
builder.Append(String.Format("<?{0} {1}>\n", reader.Name,
reader.Value));
break;
case XmlNodeType.Element:
// The node is an element (enclosed between '<' and '/>')
builder.Append(String.Format("<{0}", reader.Name));
if (reader.HasAttributes)
{
// Output each of the attributes of the element in the
form "name='value'"
MCT USE ONLY. STUDENT USE PROHIBITED
L06-5
while (reader.MoveToNextAttribute())
{
builder.Append(String.Format(" {0}='{1}'",
reader.Name, reader.Value));
}
}
builder.Append(">\n");
break;
case XmlNodeType.EndElement:
// The node is the closing tag at the end of an element
builder.Append(String.Format("</{0}>", reader.Name));
break;
}
}
7. In the Task List window, double-click the TODO: Exercise 2: Task 2d: Reset the stream and return the
string containing the formatted data task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
stream.Seek(0, SeekOrigin.Begin);
return builder.ToString();
9. Delete the following line of code from the end of the method:
4. In the Password box, type password99, and then click Log on.
Note: You will write the code to actually save the report to disk in the next exercise of this
lab.
8. Review the XML data displayed in the message box, and then click OK.
Results: After completing this exercise, users will be able to preview a report before saving it.
MCT USE ONLY. STUDENT USE PROHIBITED
L06-6 Programming in Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 3, click GradesPrototype.sln, and
then click Open.
3. On the View menu, click Task List.
5. Double-click the TODO: Exercise 3: Task 1a: Modify the message box and ask the user whether they
wish to save the report task.
6. In the code editor, delete the line of code below the comment, and then type the following code:
8. In the Task List window, double-click the TODO: Exercise 3: Task 1b: If the user says yes, then save the
data to the file that the user specified earlier task.
9. In the code editor, click at the end of the comment, press Enter, and then type the following code:
if (reply == MessageBoxResult.Yes)
{
// If the user says yes, then save the data to the file that the user specified
earlier
// If the file already exists it will be overwritten (the SaveFileDialog box will
already have asked the user whether this is OK)
FileStream file = new FileStream(dialog.FileName, FileMode.Create,
FileAccess.Write);
ms.CopyTo(file);
file.Close();
}
X Task 2: Run the application and verify that the XML document is saved correctly
1. On the Build menu, click Build Solution.
4. In the Password box, type password99, and then click Log on.
7. In the Save As dialog box, browse to the Documents folder, and then click Save.
8. Review the XML data displayed in the message box, and then click Yes.
13. In the Windows Internet Explorer dialog box, browse to the Documents folder, click Grades.xml,
and then click Open.
MCT USE ONLY. STUDENT USE PROHIBITED
L06-7
15. Verify that the file contains the expected grade data, and then close Internet Explorer.
16. In Visual Studio, on the File menu, click Close Solution.
Results: After completing this exercise, users will be able to save student reports to the local hard disk in
XML format.
MCT USE ONLY. STUDENT USE PROHIBITED
MCT USE ONLY. STUDENT USE PROHIBITED
L7-1
Note: If necessary, click Switch User to display a list of users in the Windows 8 logon
screen.
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click GradesPrototype.sln, and
then click Open.
8. On the File menu, point to Add, and then click New Project.
9. In the Add New Project dialog box, in the templates list, click Class Library, in the Name box, type
Grades.DataModel, and then click OK.
11. In the Add New Item Grades.DataModel dialog box, in the templates list, click ADO.NET Entity
Data Model, in the Name box, type GradesModel, and then click Add.
12. In the Entity Data Model Wizard, on the Choose Model Contents page, click Generate from
database, and then click Next.
13. On the Choose Your Data Connection page, click New Connection.
14. If the Choose Data Source dialog box appears, in the Data source list, click Microsoft SQL Server,
and then click Continue.
15. In the Connection Properties dialog box, in the Server name box, type (localdb)\v11.0, in the Select or
enter a database name list, click SchoolGradesDB, and then click OK.
16. In the Entity Data Model Wizard, on the Choose Your Data Connection page, click Next.
17. On the Choose Your Database Objects and Settings page, expand Tables, expand dbo, select the
following tables, and then click Finish:
Grades
Students
Subjects
MCT USE ONLY. STUDENT USE PROHIBITED
L7-2 Programming with Visual C#
Teachers
Users
18. If the Security Warning dialog box appears, click Do not show this message again, and then click
OK.
3. Right-click the heading of the Grade entity, and then click Table Mapping.
4. In the Mapping Details Grade pane, review the mappings between the columns in the database
table and the properties of the entity.
6. In the code window, note that the wizard has created a DbContext object named
SchoolGradesDBEntities.
8. Note that the wizard has created one property for each column in the Grades database table.
Results: After completing this exercise, the prototype application should include an EDM that you can use
to access The School of Fine Arts database.
MCT USE ONLY. STUDENT USE PROHIBITED
L7-3
3. In Solution Explorer, right-click GradesPrototype, and then click Set as StartUp Project.
4. On the View menu, click Task List.
6. Double-click the TODO: Exercise 2: Task 1a: Find all the grades for the student. task.
7. In the code editor, click in the blank line below the comment, and then type the following code:
8. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Display the grades in the
studentGrades ItemsControl by using databinding. task.
9. In the code editor, click in the blank line below the comment, and then type the following code:
studentGrades.ItemsSource = grades;
12. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
13. In the Class 3C view, click Kevin Liu.
15. Note that the subject column uses the subject ID rather than the subject name, and then close the
application.
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Return the subject name or the
string N/A. task.
MCT USE ONLY. STUDENT USE PROHIBITED
L7-4 Programming with Visual C#
return value;
5. In the code editor, click in the blank line below the comment, and then type the following code:
X Task 3: Display the GradeDialog view and use the input to add a new grade
1. In the Task List window, double-click the TODO: Exercise 2: Task 3a: Use the GradeDialog to get the
details of the new grade. task.
2. In the code editor, click in the blank line below the comment, and then type the following code:
3. In the Task List window, double-click the TODO: Exercise 2: Task 3b: Display the form and get the
details of the new grade. task.
4. In the code editor, click in the blank line below the comment, and then type the following code:
if (gd.ShowDialog().Value)
{
5. Click in the blank line below the final TODO comment in this try block, and then type the following
code:
6. In the Task List window, double-click the TODO: Exercise 2: Task 3c: When the user closes the form,
retrieve the details of the assessment grade from the form and use them to create a new Grade
object. task.
7. In the code editor, click in the blank line below the comment, and then type the following code:
8. In the Task List window, double-click the TODO: Exercise 2: Task 3d: Save the grade. task.
9. In the code editor, click in the blank line below the comment, and then type the following code:
SessionContext.DBContext.Grades.Add(newGrade);
SessionContext.Save();
10. In the Task List window, double-click the TODO: Exercise 2: Task 3e: Refresh the display so that the
new grade appears. task.
11. In the code editor, click at the end of the comment, press Enter, and then type the following code:
Refresh();
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
5. Verify that the list of grades now displays the subject name, not the subject ID.
6. In the Report Card view, click Add Grade.
7. In the New Grade Details dialog box, in the Subject list, click Geography, in the Assessment box,
type A+, in the Comments box, type Well done!, and then click OK.
8. Verify that the new grade is added to the list, and then close the application.
Results: After completing this exercise, users will be see the grades for the current student and add new
grades.
MCT USE ONLY. STUDENT USE PROHIBITED
L7-6 Programming with Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 3, click GradesPrototype.sln, and
then click Open.
3. In Solution Explorer, right-click GradesPrototype, and then click Set as StartUp Project.
4. In Solution Explorer, right-click Grades.DataModel, point to Add, and then click Class.
5. In the Add New Item Grades.DataModel dialog box, in the Name box, type customTeacher.cs,
and then click Add.
6. In the code editor, modify the class declaration as shown in the following code:
7. In the code editor, in the Teacher class, type the following code:
8. In the code editor, in the Teacher class, type the following code:
9. In the Task List window, double-click the TODO: Exercise 3: Task 1a: Call the EnrollInClass method to
assign the student to this teachers class. task.
10. In the code editor, click in the blank line below the comment, and then type the following code:
SessionContext.CurrentTeacher.EnrollInClass(student);
11. In the Task List window, double-click the TODO: Exercise 3: Task 1b: Save the updated student/class
information back to the database. task.
MCT USE ONLY. STUDENT USE PROHIBITED
L7-7
12. In the code editor, click in the blank line below the comment, and then type the following code:
SessionContext.Save();
X Task 2: Add validation logic for the Assessment and AssessmentDate properties
1. In Solution Explorer, right-click Grades.DataModel, point to Add, and then click Class.
2. In the Add New Item Grades.DataModel dialog box, in the Name box, type customGrade.cs,
and then click Add.
3. In the code editor, modify the class declaration as shown in the following code:
4. In the code editor, in the Grade class, type the following code:
5. In the code editor, below the existing using directives, type the following code:
using System.Text.RegularExpressions;
6. In the code editor, in the Grade class, type the following code:
7. In the Task List window, double-click the TODO: Exercise 3: Task 2a: Create a Grade object. task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
9. In the Task List window, double-click the TODO: Exercise 3: Task 2b: Call the ValidateAssessmentDate
method. task.
10. In the code editor, click in the blank line below the comment, and then type the following code:
testGrade.ValidateAssessmentDate(assessmentDate.SelectedDate.Value);
11. In the Task List window, double-click the TODO: Exercise 3: Task 2c: Call the
ValidateAssessmentGrade. task.
12. In the code editor, click in the blank line below the comment, and then type the following code:
testGrade.ValidateAssessmentGrade(assessmentGrade.Text);
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
8. In the New Grade Details dialog box, in the Date box, type tomorrows date, and then click OK.
13. Verify that the new grade is added to the list, and then close the application.
14. In Visual Studio, on the File menu, click Close Solution.
Results: After completing this exercise, the application will raise and handle exceptions when invalid data
is entered.
MCT USE ONLY. STUDENT USE PROHIBITED
L08-1
Note: If necessary, click Switch User to display a list of users in the Windows 8 logon
screen.
5. In Microsoft Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In Solution Explorer, right-click the GradesPrototype solution, point to Add, and then click New
Project.
8. In the Add New Project dialog box, in the left pane expand Visual C#, and then click Web.
10. In the Name box, type Grades.Web, and then click OK.
11. In Solution Explorer, right-click the Grades.Web project, and then click Properties.
12. On the Web tab, in the Start Action section, click Dont open a page. Wait for a request from an
external application.
13. In the Servers section, ensure that Use Local IIS Web server is selected.
14. In the Project Url box, type http://localhost:1650/, and then click Create Virtual Directory.
17. In the Solution 'GradesPrototype' Property Pages dialog box, click Multiple startup projects.
18. In the Action column for Grades.Web and GradesPrototype, click Start, and then click OK.
19. On the File menu, click Save All.
2. Delete the existing folder name, type Services, and then press Enter.
3. Right-click Services, point to Add, and then click New Item.
8. Click Browse.
9. In the Select the files to reference dialog box, browse to the E:\Labfiles\Starter\Exercise
1\packages\EntityFramework.5.0.0\lib\net45 folder, click EntityFramework.dll, and then click Add.
12. In the code editor, copy the following XML to the clipboard:
<connectionStrings>
<add name="GradesDBEntities"
connectionString="metadata=res://*/GradesModel.csdl|res://*/GradesModel.ssdl|res://*/
GradesModel.msl;provider=System.Data.SqlClient;provider connection string="data
source=(localdb)\v11.0;initial catalog=SchoolGradesDB;integrated
security=True;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
14. Click at the end of the opening <configuration> element, press Enter, and then paste the contents
of the clipboard.
X Task 3: Specify the GradesDBEntities data context for the data service
1. In Solution Explorer, in Grades.Web, expand Services, and then double-click
GradesWebDataService.svc.
2. In the code editor, click at the end of the using System.Web; code, press Enter, and then type the
following code:
using Grades.DataModel;
6. In the code editor, delete the code /* TODO: put your data source class name here */, and then
type the following code:
SchoolGradesDBEntities
7. In the Task List window, double-click the TODO: set rules to indicate which entity sets and service
operations are visible, updatable, etc. task.
8. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
config.SetEntitySetAccessRule("Users", EntitySetRights.All);
2. In the Task List window, double-click the TODO: set rules to indicate which entity sets and service
operations are visible, updatable, etc. task.
3. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
3. In Internet Explorer, if the message Intranet settings are turned off by default, click Don't show this
message again.
4. Verify that Internet Explorer displays an XML description of the entities that the data service
exposes.
5. Close Internet Explorer.
Results: After completing this exercise, you should have added a WCF Data Service to the application to
provide remote access to the SchoolGrades database.
MCT USE ONLY. STUDENT USE PROHIBITED
L08-4 Programming in Visual C#
8. In Solution Explorer, in the GradesPrototype project, in the Service References folder, expand
Grades.DataModel, expand Reference.datasvcmap, and then double-click Reference.cs.
9. In the code editor, modify the namespace GradesPrototype.Grades.DataModel code to look like
the following code:
namespace Grades.DataModel
10. In Solution Explorer, right-click the GradesPrototype project, point to Add, and then click New
Folder.
11. Delete the existing name, type DataModel, and then press Enter.
12. In Solution Explorer, expand the Grades.DataModel project, right-click Classes.cs, and then click
Copy.
X Task 2: Modify the code that accesses the EDM to use the WCF Data Service
1. In the Task List window, double-click the TODO: Exercise 2: Task 2a: Specify the URL of the
GradesWebDataService task.
2. In the code editor, below the comment, click inside the parentheses, and then type the following
code:
new Uri("http://localhost:1650/Services/GradesWebDataService.svc")
3. Add the following code to the SessionContext class, after the Save method:
static SessionContext()
{
DBContext.MergeOption = System.Data.Services.Client.MergeOption.PreserveChanges;
}
MCT USE ONLY. STUDENT USE PROHIBITED
L08-5
4. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Load User and Grades data with
Students task.
5. In the code editor, at the end of the comment, press Enter, and then type the following code:
SessionContext.DBContext.LoadProperty(student, "User");
SessionContext.DBContext.LoadProperty(student, "Grades");
6. In the Task List window, double-click the TODO: Exercise 2: Task 2c: Load User and Students data with
Teachers task.
7. In the code editor, below the comment, click at the end of the SessionContext.DBContext.Teachers
code, and then type the following code:
.Expand("User, Students")
8. In the Task List window, double-click the TODO: Exercise 2: Task 2d: Load User and Grades data with
Students task.
9. In the code editor, below the comment, click at the end of the SessionContext.DBContext.Students
code, and then type the following code:
.Expand("User, Grades")
10. In Solution Explorer, in the GradesPrototype project, expand DataModel, and then double-click
customTeacher.cs.
11. Click at the end of the using System.Threading.Tasks; code, press Enter, and then type the
following code:
using GradesPrototype.Services;
12. In the code editor, locate the TODO: Exercise 2: Task 2e: Refer to the Students collection in the
SessionContext.DBContext object comment in the customTeacher.cs file.
Note: There are two comments with this text. This is because the comment is located in the
customTeacher.cs file that you copied from the Grades.DataModel project. Make sure that you
modify the customTeacher.cs file in the GradesPrototype project.
13. In the line below the comment, delete the word Students, and then type the following code:
14. SessionContext.DBContext.Students
15. In the Task List window, double-click the TODO: Exercise 2: Task 2f: Reference the
SessionContext.DBContext.Students collection.
16. In the code editor, below the comment, change SessionContext.DBContext.Students.Local to the
following code:
SessionContext.DBContext.Students.Expand("User, Grades")
17. In the Task List window, double-click the TODO: Exercise 2: Task 2g: Use the AddToGrades method to
add a new grade.
SessionContext.DBContext.AddToGrades(newGrade);
MCT USE ONLY. STUDENT USE PROHIBITED
L08-6 Programming in Visual C#
19. In the Task List window, double-click the TODO: Exercise 2: Task 2h: Load Subject data with Grades.
20. In the code editor, below the comment, change SessionContext.DBContext.Grades to the following
code:
SessionContext.DBContext.Grades.Expand("Subject")
21. In the Task List window, double-click the TODO: Exercise 2: Task 2i: Use the AddToStudents method
to add a new student.
22. In the code editor, below the comment, change
SessionContext.DBContext.Students.Add(newStudent); to the following code:
SessionContext.DBContext.AddToStudents (newStudent);
X Task 3: Modify the code that saves changes back to the database to use the WCF
Data Service
1. In the Task List window, double-click the TODO: Exercise 2: Task 3a: Specify that the selected student
has been changed task.
2. In the code editor, click in the blank space below the comment, and then type the following code:
3. SessionContext.DBContext.UpdateObject(student);
4. In the Task List window, double-click the TODO: Exercise 2: Task 3b: Specify that the current student
has been changed task.
5. In the code editor, click in the blank space below the comment, and then type the following code:
SessionContext.DBContext.UpdateObject(SessionContext.CurrentStudent);
6. In the Task List window, double-click the TODO: Exercise 2: Task 3c: Specify that the current user has
been changed task.
7. Click in the blank space below the comment, and then type the following code:
SessionContext.DBContext.UpdateObject(currentUser);
X Task 4: Build and test the application to verify that the application still functions
correctly
1. On the Build menu, click Build Solution.
5. In the students list, click Eric Gruber, click Remove Student, and then in the Confirm dialog box,
click Yes.
7. Click Enroll Student, click Jon Orton, and then in the Confirm dialog box, click Yes.
8. Click Close, and then verify that Jon Orton is added to the student list.
12. In the Confirm box, type password88, and then click OK.
13. In the Password dialog box, click OK, and then click Log off.
14. Click Log on, verify that the Logon Failed dialog box appears, and then click OK.
15. In the password box, type password88, and then click Log on.
17. Click Log off, and then in the Username box, type grubere.
18. In the Password box, type password, and then click Log on.
19. Verify that the student profile for Eric Gruber appears, and then click Log off.
Results: After completing this exercise, you should have updated the Grades Prototype application to use
the WCF Data Service.
MCT USE ONLY. STUDENT USE PROHIBITED
L08-8 Programming in Visual C#
6. Right-click the IValueConverter keyword, point to Implement Interface, and then click Implement
Interface.
7. In the Convert method, delete the existing statement that throws a NotImplementedException,
and then type the following code:
X Task 2: Add an Image control to the StudentsPage view and bind it to the
ImageName property
1. In Solution Explorer, in the GradesPrototype project, expand Views, and then double-click
StudentsPage.xaml.
2. In the XAML editor, in the UserControl element at the top of the markup, click after the
xmlns:d=http://schemas.microsoft.com/expression/blend/2008 line, press Enter, and then type
the following markup:
xmlns:local="clr-namespace:GradesPrototype.Views"
3. Locate the TODO: Exercise 3: Task 2a. Add an instance of the ImageNameConverter class as a
resource to the view comment, click at the end of the comment, press Enter, and then type the
following markup:
<UserControl.Resources>
<local:ImageNameConverter x:Key="ImageNameConverter"/>
</UserControl.Resources>
MCT USE ONLY. STUDENT USE PROHIBITED
L08-9
4. Locate the TODO: Exercise 3: Task 2b. Add an Image control to display the photo of the student
comment, click at the end of the comment, press Enter, and then type the following markup:
5. Locate the Exercise 3: Task 2c. Bind the Image control to the ImageName property and use the
ImageNameConverter to convert the image name into a URL comment.
6. In the line above the comment, modify the <Image Height="100" /> markup to look like the
following markup:
X Task 3: Add an Image control to the StudentProfile view and bind it to the
ImageName property
1. In Solution Explorer, double-click StudentProfile.xaml.
2. Locate the TODO: Exercise 3: Task 3a. Add an instance of the ImageNameConverter class as a
resource to the view comment.
3. Click at the end of the comment, press Enter, and then type the following markup:
<app:ImageNameConverter x:Key="ImageNameConverter"/>
4. Locate the TODO: Exercise 3: Task 3b. Add an Image control to display the photo of the student and
bind the Image control to the ImageName property and use the ImageNameConverter to convert the
image name into a URL comment.
5. Click at the end of the comment, press Enter, and then type the following markup:
X Task 4: Add an Image control to the AssignStudentDialog control and bind it to the
ImageName property
1. In Solution Explorer, expand Controls, and then double-click AssignStudentDialog.xaml.
2. In the XAML editor, at the top of the markup, click at the end of the
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml line, press Enter, and then type the
following markup:
xmlns:local="clr-namespace:GradesPrototype.Views"
3. Locate the TODO: Exercise 3: Task 4a. Add an instance of the ImageNameConverter class as a
resource to the view comment.
4. Click at the end of the comment, press Enter, and then type the following markup:
<Window.Resources>
<local:ImageNameConverter x:Key="ImageNameConverter"/>
</Window.Resources>
5. Locate the TODO: Exercise 3: Task 4b. Add an Image control to display the photo of the student and
bind the control to the ImageName property and use the ImageNameConverter to convert the image
name into a URL comment.
6. Click at the end of the comment, press Enter, and then type the following markup:
MCT USE ONLY. STUDENT USE PROHIBITED
L08-10 Programming in Visual C#
X Task 5: Build and test the application, verifying that students photographs appear in
the list of students for the teacher
1. On the Build menu, click Build Solution.
2. On the Debug menu, click Start Without Debugging.
4. In the Password box, type password88, and then click Log on.
5. Verify that the students list now includes images.
6. Click George Li, and then verify that the student profile appears with an image.
7. Click Remove Student, and then in the Confirm dialog box, click Yes.
8. Click Enroll Student, and then verify that in the Assign Student dialog box, the unassigned students
each have an image.
9. Click George Li, in the Confirm dialog box, click Yes, and then verify that George Li is added to the
students list with an image.
Results: After completing this exercise, the students list, student profile, and unassigned student dialog
box will display the images of students that were retrieved across the web.
MCT USE ONLY. STUDENT USE PROHIBITED
L9-1
Note: If necessary, click Switch User to display a list of users in the Windows 8 log on
screen.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click Grades.sln, and then
click Open.
8. In Solution Explorer, right-click Solution Grades, and then click Properties.
9. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
10. In Solution Explorer, expand Grades.WPF, and then expand Controls.
11. Right-click Controls, point to Add, and then click New Item.
12. In the Add New Item Grades.WPF dialog box, in the template list, click User Control (WPF).
13. In the Name box, type StudentPhoto, and then click Add.
14. In the XAML editor, modify the markup to look like the following markup (the changes are
highlighted as bold text):
<UserControl x:Class="Grades.WPF.StudentPhoto"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Image Stretch="UniformToFill" Source="{Binding File}" Margin="8" />
<Image Margin="0" Source="../Images/Image_Frame.png" Stretch="Fill" />
<TextBlock Text="{Binding Name}" Style="{StaticResource LabelCenter}"
FontSize="16" VerticalAlignment="Bottom" Margin="8,0,14.583,8" />
</Grid>
</UserControl>
MCT USE ONLY. STUDENT USE PROHIBITED
L9-2 Programming in Visual C#
16. In the code editor, delete all of the using directives, and then type the following code:
using System.Windows.Controls;
using System.Windows.Media.Animation;
17. Modify the namespace Grades.WPF.Controls code to look like the following code:
namespace Grades.WPF
3. Click at the end of the comment, press Enter, and then type the following markup:
<ItemsControl x:Name="list">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Margin="0" Orientation="Horizontal"
HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Note: When you type an opening tag for an element, such as <ItemsControl>, the XAML
editor automatically creates a corresponding closing tag, such as </ItemsControl>. For the
purposes of these instructions, and to ensure that code appears in the correctly commented
place, delete any closing tags that are generated automatically; you will add them in at the
appropriate point in the XAML markup in later steps.
4. Locate the <!-- TODO: Exercise 1: Task 2b: Define the DataTemplate for the "list" ItemsControl
including the StudentPhoto user control --> comment, click at the end of the comment, press Enter,
and then type the following markup:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="8">
<local:StudentPhoto Height="150" Width="127.5" Cursor="Hand"
Note: At the end of this task, the XAML markup is incomplete and will display errors in the
XAML pane. In the next task, you will add closing tags and make the markup complete.
5. In the code editor, click in the blank line below the comment, and then type the following code:
7. Locate the <!-- TODO: Exercise 1: Task 3b: Set the handler for the click event for the StudentPhoto
control --> comment, and above the comment, click at the end of the Cursor="Hand" markup.
MouseLeftButtonUp="Student_Click" />
2. In the Task List window, double-click the TODO: Exercise 1: Task 4b: Animate the photo as the user
moves the mouse over the "delete" image task.
3. In the code editor, click in the blank line below the comment, press Enter, and then type the following
code:
4. In the Task List window, double-click the TODO: Exercise 1: Task 4c: Animate the photo as the user
moves the mouse away from the "delete" image task.
5. In the code editor, click in the blank line below the comment, then type the following code:
7. In the XAML editor, locate the <!-- TODO: Exercise 1: Task 4d: Add event handlers to highlight the
"Remove" button as the mouse enters and exits this control --> comment, and above the comment,
MCT USE ONLY. STUDENT USE PROHIBITED
L9-4 Programming in Visual C#
click at the end of the Tag="{Binding}" code (before the closing > tag), press Enter, and then type the
following markup:
MouseEnter="RemoveStudent_MouseEnter" MouseLeave="RemoveStudent_MouseLeave"
MouseLeftButtonUp="RemoveStudent_Click"
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
2. In the Task List window, double-click the TODO: Exercise 1: Task 5a: Find all students for the current
teacher task.
3. In the code editor, click in the blank line below the comment, and then type the following code:
4. In the Task List window, double-click the TODO: Exercise 1: Task 5b: Iterate through the returned set
of students, construct a local student object list task.
5. In the code editor, click in the blank line below the comment, and then type the following code:
6. In the Task List window, double-click the TODO: Exercise 1: Task 5c: Bind the list of students to the
"list" ItemsControl task.
7. In the code editor, click in the blank line below the comment, and then type the following code:
list.ItemsSource = resultData;
5. In the student list, hover over the red x for the student Martin Weber.
MCT USE ONLY. STUDENT USE PROHIBITED
L9-5
6. Verify that the student photograph for Martin Weber becomes transparent and that the red x
becomes opaque.
7. Move the cursor away from the red x and verify that the student photograph becomes opaque and
that the red x becomes transparent.
8. Click the red x for Martin Weber, verify that the Student message box appears, and then click Yes.
9. Verify that Martin Weber is removed from the student list.
Results: After completing this exercise, the application will display the photographs of each student on
the Student List page.
MCT USE ONLY. STUDENT USE PROHIBITED
L9-6 Programming in Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 2, click Grades.sln, and then
click Open.
3. In Solution Explorer, right-click Solutions Grades, and then click Properties.
4. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
5. In Solution Explorer, expand Grades.WPF, expand Views, and then double-click LogonPage.xaml.
6. In the XAML editor, locate the <!-- TODO: Exercise 2: Task 1a: Define the LoginTextBoxStyle -->
comment.
7. Click at the end of the comment, press Enter, and then type the following markup:
<UserControl.Resources>
<Style x:Key="LoginTextBoxStyle" BasedOn="{StaticResource TextBoxStyle}"
TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="5" />
<Setter Property="FontSize" Value="24"/>
<Setter Property="MaxLength" Value="16" />
</Style>
8. Locate the <!-- TODO: Exercise 2: Task 1b: Apply the LoginTextBoxStyle to the "username" TextBox --
> comment.
9. In the line of markup below the comment, delete the FontSize property, and then modify the markup
as shown in bold below:
10. Locate the <!-- TODO: Exercise 2: Task 1c: Define the PasswordBoxStyle --> comment.
11. Click at the end of the comment, press Enter, and then type the following markup:
12. Locate the TODO: Exercise 2: Task 1d: Apply the PasswordBoxStyle to the "password" TextBox
comment.
13. In the line of markup below the comment, delete the FontSize property, and then modify the markup
as shown in bold below:
2. In the XAML editor, locate the <!-- TODO: Exercise 2: Task 2a: Define the label styling used
throughout the application --> comment near the end of the file.
3. Click in the blank line below the comment, and type the following markup:
4. Locate the <!-- TODO: Exercise 2: Task 2b: Define the text styling used throughout the application -->
comment.
5. Click in the blank line below the comment, then type the following markup:
3. Click in the blank line below the comment, then type the following markup:
<UserControl.RenderTransform>
<ScaleTransform x:Name="scale" />
</UserControl.RenderTransform>
4. In the XAML editor, locate the <!-- TODO: Exercise 2: Task 3b: Define animations for the "scale"
transform--> comment.
5. Click in the blank line below the comment, then type the following markup:
<UserControl.Resources>
<Storyboard x:Key="sbMouseEnter">
<DoubleAnimation To="1.1" BeginTime="00:00:00" Duration="00:00:00.05"
Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To="1.1" BeginTime="00:00:00" Duration="00:00:00.15"
Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" />
</Storyboard>
<Storyboard x:Key="sbMouseLeave">
<DoubleAnimation To="1" BeginTime="00:00:00" Duration="00:00:00.05"
Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleX" />
<DoubleAnimation To="1" BeginTime="00:00:00" Duration="00:00:00.15"
Storyboard.TargetName="scale" Storyboard.TargetProperty="ScaleY" />
</Storyboard>
</UserControl.Resources>
2. In the Task List window, double-click the TODO: Exercise 2: Task 4a: Handle mouse events to trigger
the storyboards that animate the photograph task.
3. In the code editor, click in the blank line below the comment, and then type the following code:
MCT USE ONLY. STUDENT USE PROHIBITED
L9-8 Programming in Visual C#
5. In the Task List window, double-click the TODO: Exercise 2: Task 4b: Forward the MouseEnter and
MouseLeave events to the photograph control task.
6. In the code editor, click in the blank space below the comment, and then type the following code:
8. In the XAML editor, locate the <!-- TODO: Exercise 2: Task 4c: Specify the handlers for the
MouseEnter and MouseLeave events --> comment.
9. Below the comment, click at the end of the MouseLeftButtonUp="Student_Click" markup, press
Spacebar, and then type the following markup:
MouseEnter="Student_MouseEnter" MouseLeave="Student_MouseLeave"
3. When the application starts, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
4. In The School of Fine Arts window, verify that the styling of the text elements of the application has
changed.
MCT USE ONLY. STUDENT USE PROHIBITED
L9-9
FIGURE 9.1: UPPER: OLD STYLE LOGON VIEW. LOWER: NEW STYLE LOGON
VIEW
5. Hover over one of the students in the student list and verify that the photograph animatesit should
expand and contract as the mouse passes over it.
Results: After completing this exercise, the Logon view and the Photograph control will be styled with a
consistent look and feel.
MCT USE ONLY. STUDENT USE PROHIBITED
MCT USE ONLY. STUDENT USE PROHIBITED
L10-1
6. In Microsoft Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click Grades.sln, and then
click Open.
9. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
12. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
13. Notice that the UI briefly freezes while fetching the list of students for Esther Valle (try moving the
application window after logging on but before the list of students appears).
X Task 2: Modify the code that retrieves teacher data to run asynchronously
1. On the View menu, click Task List.
3. Double-click the TODO: Exercise 1: Task 2a: Convert GetTeacher into an async method that
returns a Task<Teacher> task.
5. In the blank line below the comment, type the following code:
6. In the Task List window, double-click the TODO: Exercise 1: Task 2b: Perform the LINQ query to
fetch Teacher information asynchronously task.
7. In the code editor, modify the statement below the comment as shown in bold below:
8. In the Task List window, double-click the TODO: Exercise 1: Task 2c: Mark MainWindow.Refresh
as an asynchronous method task.
9. In the code editor, modify the statement below the comment as shown in bold below:
10. In the Task List window, double-click the TODO: Exercise 1: Task 2d: Call GetTeacher
asynchronously task.
11. In the code editor, modify the statement below the comment as shown in bold below:
X Task 3: Modify the code that retrieves and displays the list of students for a teacher
to run asynchronously
1. In the Task List window, double-click the TODO: Exercise 1: Task 3a: Mark StudentsPage.Refresh
as an asynchronous method task.
2. In the code editor, modify the statement below the comment as shown in bold below:
3. In the Task List window, double-click the TODO: Exercise 1: Task 3b: Implement the
OnGetStudentsByTeacherComplete callback to display the students for a teacher here task.
4. In the blank line below the comment, type the following code:
5. In the Task List window, double-click the Exercise 1: Task 3b: Relocate the remaining code in this
method to create the OnGetStudentsByTeacherComplete callback (in the Callbacks region)
task.
6. In the code editor, move all of the code between the comment and the end of the Refresh method
to the Clipboard.
7. In the Task List window, double-click the TODO: Exercise 1: Task 3b: Implement the
OnGetStudentsByTeacherComplete callback to display the students for a teacher here task.
8. Click in the blank line between the curly braces and paste the code from the Clipboard.
MCT USE ONLY. STUDENT USE PROHIBITED
L10-3
9. In the Task List window, double-click the TODO: Exercise 1: Task 3c: Use a Dispatcher object to
update the UI task.
10. In the code editor, click at the end of the comment line, press Enter, and then type the following
code:
this.Dispatcher.Invoke(() => {
11. Immediately after the last line of code in the method, type the following code:
});
12. In the Task List window, double-click the TODO: Exercise 1: Task 3d: Convert
GetStudentsByTeacher into an async method that invokes a callback task.
14. In the blank line below the comment, type the following code:
15. In the code editor, modify the return statement below the if(!IsConnected()) line to return without
passing a value to the caller:
return;
16. In the Task List window, double-click the TODO: Exercise 1: Task 3e: Perform the LINQ query to
fetch Student data asynchronously task.
17. In the code editor, modify the statement below the comment as shown in bold below:
18. In the Task List window, double-click the TODO: Exercise 1: Task 3f: Run the callback by using a
new task rather than returning a list of students task.
19. In the code editor, delete the following code:
return students;
20. In the blank line below the comment, type the following code:
21. In the Task List window, double-click the TODO: Exercise 1: Task 3g: Invoke
GetStudentsByTeacher asynchronously and pass the OnGetStudentsByTeacherComplete
callback as the second argument task.
22. In the code editor, modify the statement below the comment as shown in bold below:
await utils.GetStudentsByTeacher(SessionContext.UserName,
OnGetStudentsByTeacherComplete);
MCT USE ONLY. STUDENT USE PROHIBITED
L10-4 Programming in Visual C#
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
4. Verify that the application is more responsive than before while fetching the list of students for Esther
Valle, and then close the application window.
Results: After completing this exercise, you should have updated the Grades application to retrieve data
asynchronously.
MCT USE ONLY. STUDENT USE PROHIBITED
L10-5
6. In Microsoft Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 2, click Grades.sln, and then
click Open.
9. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
11. In Solution Explorer, right-click Grades.WPF, point to Add, and then click User Control.
12. In the Name box, type BusyIndicator.xaml, and then click Add.
13. In Solution Explorer, expand Grades.WPF, and then drag BusyIndicator.xaml into the Controls
folder.
Note: It is better to create the user control at the project level and then move it into the
Controls folder when it is created. This ensures that the user control is created in the same
namespace as other project resources.
14. In the BusyIndicator.xaml file, in the UserControl element, delete the following attributes:
d:DesignWidth="300" d:DesignHeight="300"
15. Modify the Grid element to include a Background attribute, as the following markup shows:
<Grid Background="#99000000">
</Grid>
16. Type the following markup between the opening and closing Grid tags:
<Border CornerRadius="6"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Border.Background>
<LinearGradientBrush>
<GradientStop
Color="LightGray"
Offset="0" />
<GradientStop
MCT USE ONLY. STUDENT USE PROHIBITED
L10-6 Programming in Visual C#
Color="DarkGray"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Border.Effect>
<DropShadowEffect
Opacity="0.75" />
</Border.Effect>
</Border>
17. On the blank line before the closing Border tag, type the following code:
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
18. On the blank line before the closing Grid tag, type the following code:
<ProgressBar x:Name="progress"
IsIndeterminate="True"
Width="200"
Height="25" Margin="20" />
19. Click after the end of the ProgressBar element, and then press Enter.
<TextBlock x:Name="txtMessage"
Grid.Row="1" FontSize="14"
FontFamily="Verdana"
Text="Please Wait..."
TextAlignment="Center" />
24. Click at the end of the comment, press Enter, and then type the following code:
<y:BusyIndicator
x:Name="busyIndicator"
Margin="0"
Visibility="Collapsed" />
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Implement the EndBusy
event handler task.
4. In the blank line below the comment, type the following code:
3. In the Task List window, double-click the TODO: Exercise 2: Task 3b: Add the EndBusy public
event task.
4. In the blank line below the comment, type the following code:
5. In the Task List window, double-click the TODO: Exercise 2: Task 3c: Implement the
StartBusyEvent method to raise the StartBusy event task.
6. In the blank line below the comment, type the following code:
7. In the Task List window, double-click the TODO: Exercise 2: Task 3d: Implement the
EndBusyEvent method to raise the EndBusy event task.
8. In the blank line below the comment, type the following code:
10. In the MainWindow.xaml file, locate the TODO: Exercise 2: Task 3e: Wire up the StartBusy and
EndBusy event handlers for the StudentsPage view comment.
11. Immediately below the comment, modify the StudentsPage element to include StartBusy and
EndBusy attributes, as the following code shows:
12. In the Task List window, double-click the TODO: Exercise 2: Task 3f: Raise the StartBusy event
task.
13. In the blank line below the comment, type the following code:
StartBusyEvent();
14. In the Task List window, double-click the TODO: Exercise 2: Task 3g: Raise the EndBusy event
task.
15. In the blank line below the comment, type the following code:
EndBusyEvent();
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
4. Verify that the application displays the busy indicator while waiting for the list of students to load,
and then close the application window.
Results: After completing this exercise, you should have updated the Grades application to display a
progress indicator while the application is retrieving data.
MCT USE ONLY. STUDENT USE PROHIBITED
L11-1
Note: If necessary, click Switch User to display a list of users in the Windows 8 logon
screen.
6. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click Grades.sln, and then
click Open.
11. Examine the code that is currently contained within this class.
13. In the Task List window, in the Categories list, click Comments.
14. Double-click the TODO: Exercise 1: Task 1a: Create a dynamic variable called _word for activating
Word task.
15. In the code editor, click in the blank line below the comment, and then type the following code:
16. dynamic _word = null;
17. In the Task List window, double-click the TODO: Exercise 1: Task 1b: Instantiate _word as a new Word
Application object task.
18. In the code editor, click in the blank line below the comment, and then type the following code:
19. In the Task List window, double-click the TODO: Exercise 1: Task 1c: Create a new Word document
task.
20. In the code editor, click in the blank line below the comment, and then type the following code:
doc.Activate();
21. In the Task List window, double-click TODO: Exercise 1: Task 1d: Save the document using the
specified filename. task.
22. In the code editor, click in the blank line below the comment, and then type the following code:
23. In the Task List window, double-click the TODO: Exercise 1: Task 1e: Close the document task.
24. In the code editor, click in the blank line below the comment, and then type the following code:
currentDocument.Close();
25. In the Task List window, double-click the TODO: Exercise 1: Task 1f: Find the end of the document
task.
26. In the code editor, delete the existing code below the comment, and then type the following code:
3. In the Task List window, double-click the TODO: Exercise 1: Task 2b: Generate the report by using a
separate task task.
4. In the code editor, click in the blank line below the comment, and then type the following code:
MCT USE ONLY. STUDENT USE PROHIBITED
L11-3
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
6. In the File name box, delete the existing contents, type Kevin Liu Grades Report, and then click
Save.
7. Close the application, and then in Microsoft Visual Studio, on the File menu, click Close Solution.
8. Open File Explorer, browse to the E:\Labfiles\Starter\Exercise 1 folder, and then verify that the
report has been generated.
10. Review the grade report, and then in Word, on the File menu, click Exit.
Results: After completing this exercise, the application will generate grade reports in Word
format.
MCT USE ONLY. STUDENT USE PROHIBITED
L11-4 Programming in Visual C#
7. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
8. Click Kevin Liu, and then click save report.
10. In the File name box, delete the existing contents, type Kevin Liu Grades Report, and then click
Save.
12. Open File Explorer, browse to the E:\Labfiles\Starter\Exercise 2 folder, and then verify that the
report has been generated.
16. Click Microsoft Word (32 bit), and then click End task.
17. Close Task Manager.
:IDisposable
3. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Create the protected
Dispose(bool) method task.
4. In the code editor, click in the blank line below the comment, and then type the following code:
if (!this.isDisposed)
{
if (isDisposing)
{
// Release managed resources here
if (this._word != null)
{
this._word.Quit();
}
}
// Release unmanaged resources here
if (this._word != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(this._word);
}
this.isDisposed = true;
}
}
5. In the Task List window, double-click the TODO: Exercise 2: Task 2c: Create the public Dispose method
task.
6. In the code editor, click at the end of the comment, press Enter, and then type the following code:
7. In the Task List window, double-click the TODO: Exercise 2: Task 2d: Create a finalizer that calls the
Dispose method task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
X Task 3: Wrap the object that generates the Word doc in a using statement
1. In the Task List window, double-click the TODO: Exercise 2: Task 3: Ensure that the WordWrapper is
disposed when the method finishes task.
2. Below the comment, modify the WordWrapper wrapper = new WordWrapper(); code to look like
the following:
3. At the end of the method, after the wrapper.SaveAs(reportPath); line of code, add a closing brace
to end the using block.
4. Your code should look like the following:
X Task 4: Use Task Manager to observe that Word terminates correctly after generating
a report
1. On the Build menu, click Build Solution.
4. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
5. Click George Li, and then click save report.
7. In the File name box, delete the existing contents, and then type George Li Grades Report.
8. As you click Save, in the Task Manager window, watch the Background processes and verify that
Microsoft Word (32 bit) appears and then disappears from the list.
Results: After completing this exercise, the application will terminate Word correctly after it has
generated a grades report.
MCT USE ONLY. STUDENT USE PROHIBITED
L12-1
5. In Visual Studio, on the File menu, point to Open, and then click Project/Solution.
6. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click Grades.sln, and then
click Open.
8. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
12. Double-click the TODO: Exercise 1: Task 1a: Specify that IncludeInReportAttribute is an attribute class
task.
13. In the code editor, below the comment, click at the end of the public public class
IncludeInReportAttribute code, and then type the following code:
: Attribute
14. In the Task List window, double-click the TODO: Exercise 1: Task 1b: Specify the possible targets to
which the IncludeInReport attribute can be applied task.
15. In the code editor, click in the blank line below the comment, and then type the following code:
16. In the Task List window, double-click the TODO: Exercise 1: Task 1c: Define a private field to hold the
value of the attribute task.
17. In the code editor, click in the blank line below the comment, and then type the following code:
18. In the Task List window, double-click the TODO: Exercise 1: Task 1d: Add public properties that specify
how an included item should be formatted task.
19. In the code editor, click in the blank line below the comment, and then type the following code:
20. In the Task List window, double-click the TODO: Exercise 1: Task 1e: Add a public property that
specifies a label (if any) for the item task.
21. In the code editor, click in the blank line below the comment, and then type the following code:
22. In the Task List window, double-click the TODO: Exercise 1: Task 1f: Define constructors task.
23. In the code editor, click at the end of the comment, press Enter, and then type the following code:
public IncludeInReportAttribute()
{
this._include = true;
this.Underline = false;
this.Bold = false;
this.Label = string.Empty;
}
public IncludeInReportAttribute(bool includeInReport)
{
this._include = includeInReport;
this.Underline = false;
this.Bold = false;
this.Label = string.Empty;
}
3. In the LocalGrade method, expand the Properties region, and then expand the Readonly
Properties region.
4. Above the public string SubjectName code, click in the blank line, and then type the following
code:
5. Above the public string AssessmentDateString code, click in the blank line, press Enter, and then
type the following code:
[IncludeInReport (Label="Date")]
[IncludeInReport(Label = "Grade")]
MCT USE ONLY. STUDENT USE PROHIBITED
L12-3
8. Above the public string Comments code, click in the blank space, press Enter, and then type the
following code:
[IncludeInReport(Label = "Comments")]
X Task 3: Build the application and review the metadata for the LocalGrades class
1. On the Build menu, click Build Solution.
6. In the IL DASM application window, expand Grades.WPF, expand Grades.WPF.LocalGrade, and then
double-click Assessment : instance string();.
7. In the Grades.WPF.LocalGrade::Assessment : instance string() window, in the Assessment method,
verify that the .custom instance void [Grades.Utilities]Grades.Utilities.IncludeInReportAttribute::.ctor()
code is present, and then close the window.
8. In the IL DASM application window, double-click AssessmentDateString : instance string();.
Results: After completing this exercise, the Grades.Utilities assembly will contain an IncludeInReport
custom attribute and the Grades class will contain fields and properties that are tagged with that
attribute.
MCT USE ONLY. STUDENT USE PROHIBITED
L12-4 Programming in Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 2, click Grades.sln, and then
click Open.
3. In Solution Explorer, expand Grades.Utilities, and then double-click IncludeInReport.cs.
5. In the Task List window, double-click the TODO: Exercise 2: Task 1a: Define a struct that specifies the
formatting to apply to an item task.
6. In the code editor, click in the blank line in the FormatField struct, and then type the following code:
7. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Find all the public fields and
properties in the dataForReport object task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
9. In the Task List window, double-click the TODO: Exercise 2: Task 1c: Iterate through all public fields
and properties, and process each item that is tagged with the IncludeInReport attribute task.
10. In the code editor, click in the blank line below the comment, and then type the following code:
11. In the Task List window, double-click the TODO: Exercise 2: Task 1d: Determine whether the current
member is tagged with the IncludeInReport attribute task.
12. In the code editor, click in the blank line below the comment, and then type the following code:
13. In the Task List window, double-click the TODO: Exercise 2: Task 1e: If the member is tagged with the
IncludeInReport attribute, construct a FormatField item task.
14. In the code editor, click in the blank line below the comment, and then type the following code:
if (attributeFound != null)
{
// Find the value of the item tagged with the IncludeInReport attribute
string itemValue;
if (member is FieldInfo)
{
itemValue = (member as FieldInfo).GetValue(dataForReport).ToString();
}
else
{
MCT USE ONLY. STUDENT USE PROHIBITED
L12-5
15. In the Task List window, double-click the TODO: Exercise 2: Task 1f: Construct a FormatField item with
this data task.
16. In the code editor, click in the blank line below the comment, and then type the following code:
17. In the Task List window, double-click the TODO: Exercise 2: Task 1g: Add the FormatField item to the
collection to be returned task.
18. In the code editor, click in the blank line below the comment, and then type the following code:
items.Add(item);
}
}
3. In the code editor, click in the blank line below the comment, and then type the following code:
4. In the Task List window, double-click the TODO: Exercise 2: Task 2b: Output each tagged item, using
the format specified by the properties of the IncludeInReport attribute for each item task.
5. In the code editor, click in the blank line below the comment, and then type the following code:
Results: After completing this exercise, the application will be updated to use reflection to include only
the tagged fields and properties in the grades report.
MCT USE ONLY. STUDENT USE PROHIBITED
L12-6 Programming in Visual C#
2. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 3, click Grades.sln, and then
click Open.
3. In Solution Explorer, right-click Solutions Grades, and then click Properties.
4. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
8. In the Start window, right-click the VS2012 x86 Native Tools Command icon.
10. In the User Account Control dialog box, in the Password box, type Pa$$w0rd, and then click Yes.
11. At the command prompt, type the following code, and then press Enter:
E:
12. At the command prompt, type the following code, and then press Enter:
cd E:\Labfiles\Starter
13. At the command prompt, type the following code, and then press Enter:
sn -k GradesKey.snk
14. Verify that the text Key pair written to GradesKey.snk is displayed.
15. In Visual Studio, in Solution Explorer, right-click Grades.Utilities, and then click Properties.
18. In the Select File dialog box, browse to E:\Labfiles\Starter, click GradesKey.snk, and then click
Open.
20. Switch to the command prompt, type the following code, and then press Enter:
cd E:\Labfiles\Starter\Exercise 3\Grades.Utilities\bin\Debug
21. At the command prompt, type the following code, and then press Enter:
gacutil -i Grades.Utilities.dll
22. Verify that the text Assembly successfully added to the cache is displayed, and then close the
Command Prompt window.
MCT USE ONLY. STUDENT USE PROHIBITED
L12-7
X Task 2: Reference the Grades.Utilities assembly in the GAC from the application
1. In Visual Studio, in Solution Explorer, expand Grades.WPF, expand References, right-click
Grades.Utilities, and then click Remove.
2. Right-click References, and then click Add Reference.
3. In the Reference Manager Grades.WPF dialog box, click the Browse button.
8. In the Username box, type vallee, and in the Password box, type password99, and then click Log
on.
9. In the Class 3C view, click Kevin Liu.
10. Verify that the student report for Kevin Liu appears, and then click save report.
Results: After completing this exercise, you will have a signed version of the Grades.Utilities assembly
deployed to the GAC.
MCT USE ONLY. STUDENT USE PROHIBITED
MCT USE ONLY. STUDENT USE PROHIBITED
L13-1
6. In Microsoft Visual Studio, on the File menu, point to Open, and then click Project/Solution.
7. In the Open Project dialog box, browse to E:\Labfiles\Starter\Exercise 1, click Grades.sln, and then
click Open.
9. On the Startup Project page, click Multiple startup projects. Set Grades.Web and Grades.WPF to Start
without debugging, and then click OK.
10. In Solution Explorer, expand the Grades.Utilities node, and then double-click the
CreateCertificate.cmd file.
15. In the Start window, right-click the VS2012 x86 Native Tools Command icon.
17. In the User Account Control dialog box, in the Password box, type Pa$$w0rd, and then click Yes.
18. At the command prompt, type the following, and then press Enter.
E:
19. At the command prompt, type the following, and then press Enter.
cd E:\Labfiles\Starter\Exercise 1\Grades.Utilities
20. At the command prompt, type the following, and then press Enter.
CreateCertificate.cmd
MCT USE ONLY. STUDENT USE PROHIBITED
L13-2 Programming in C#
21. Verify that the command returns a success message, and then close the command window.
3. Double-click the TODO: Exercise 1: Task 2a: Loop through the certificates in the X509 store to
return the one matching _certificateSubjectName. task.
4. In the code editor, click in the blank line below the comment, and then type the following code:
3. In the blank line below the comment, type the following code:
6. In the code editor, click in the blank line below the comment, and then type the following code:
7. In the Task List window, double-click the TODO: Exercise 1: Task 3c: Create an underlying stream
for the unencrypted data. task.
8. In the code editor, click in the blank line below the comment, and then type the following code:
9. In the Task List window, double-click the TODO: Exercise 1: Task 3d: Create an AES encryptor
based on the key and IV. task.
10. In the code editor, click in the blank line below the comment, and then type the following code:
11. In the Task List window, double-click the TODO: Exercise 1: Task 3e: Create byte arrays to get the
length of the encryption key and IV. task.
12. In the code editor, click in the blank line below the comment, and then type the following code:
MCT USE ONLY. STUDENT USE PROHIBITED
L13-3
13. In the Task List window, double-click the TODO: Exercise 1: Task 3f: Write the following to the
out stream: task.
14. In the code editor, click in the blank line below the comment block, and then type the following code:
outStream.Write(keyLength, 0, keyLength.Length);
outStream.Write(ivLength, 0, ivLength.Length);
outStream.Write(encryptedKey, 0, encryptedKey.Length);
outStream.Write(algorithm.IV, 0, algorithm.IV.Length);
15. In the Task List window, double-click the TODO: Exercise 1: Task 3g: Create a CryptoStream that
will write the encrypted data to the underlying buffer. task.
16. In the code editor, click in the blank line below the comment, and then type the following code:
17. In the Task List window, double-click the TODO: Exercise 1: Task 3h: Write all the data to the
stream. task.
18. In the code editor, click in the blank line below the comment, and then type the following code:
encrypt.Write(bytesToEncrypt, 0, bytesToEncrypt.Length);
encrypt.FlushFinalBlock();
19. In the Task List window, double-click the TODO: Exercise 1: Task 3i: Return the encrypted
buffered data as a byte. task.
20. In the code editor, click in the blank line below the comment, and then type the following code:
return outStream.ToArray();
}
}
}
}
2. In the code editor, click in the blank line below the comment, and then type the following code:
File.WriteAllBytes(filePath, encryptedBytes);
3. When the application loads, in the Username box, type vallee, and in the Password box, type
password99, and then click Log on.
4. In the Class 3C view, click George Li.
6. In the Save As dialog box, browse to the E:\Labfiles\Reports folder, in the File name box, type
GeorgeLi, and then click Save.
11. In the Report Card view, click Log off, and then close the application.
12. On the File menu, click Close Solution.
13. Open Windows Internet Explorer, and in the address bar, type E:\Labfiles\Reports\KevinLiu.xml,
and then press Enter.
14. Note the page is blank because the file is encrypted, and then close Internet Explorer.
15. Open File Explorer, and then browse to the E:\Labfiles\Reports folder.
17. Review the encrypted data, close Notepad, and then close File Explorer.
Results: After completing this exercise, you should have updated the Grades application to encrypt
generated reports.
MCT USE ONLY. STUDENT USE PROHIBITED
L13-5
5. In the blank line below the comment, type the following code:
6. In the Task List window, double-click the TODO: Exercise 2: Task 1b: Create an instance of the
AESManaged algorithm which the data is encrypted with. task.
7. In the blank line below the comment, type the following code:
8. In the Task List window, double-click the TODO: Exercise 2: Task 1c: Create a stream to process
the bytes. task.
9. In the blank line below the comment, type the following code:
10. In the Task List window, double-click the TODO: Exercise 2: Task 1d: Create byte arrays to get the
length of the encryption key and IV. task.
11. In the blank line below the comment, type the following code:
12. In the Task List window, double-click the TODO: Exercise 2: Task 1e: Read the key and IV lengths
starting from index 0 in the in stream. task.
13. In the blank line below the comment, type the following code:
inStream.Seek(0, SeekOrigin.Begin);
inStream.Read(keyLength, 0, keyLength.Length);
inStream.Read(ivLength, 0, ivLength.Length);
14. In the Task List window, double-click the TODO: Exercise 2: Task 1f: Convert the lengths to ints
for later use. task.
15. In the blank line below the comment, type the following code:
16. In the Task List window, double-click the TODO: Exercise 2: Task 1g: Determine the starting
position and length of data. task.
17. In the blank line below the comment, type the following code:
18. In the Task List window, double-click the TODO: Exercise 2: Task 1h: Create the byte arrays for the
encrypted key, the IV, and the encrypted data. task.
19. In the blank line below the comment, type the following code:
20. In the Task List window, double-click the TODO: Exercise 2: Task 1i: Read the key, IV, and
encrypted data from the in stream. task.
21. In the blank line below the comment, type the following code:
inStream.Read(encryptionKey, 0, convertedKeyLength);
inStream.Read(iv, 0, convertedIvLength);
inStream.Read(encryptedData, 0, dataLength);
22. In the Task List window, double-click the TODO: Exercise 2: Task 1j: Decrypt the encrypted
AesManaged encryption key. task.
23. In the blank line below the comment, type the following code:
24. In the Task List window, double-click the TODO: Exercise 2: Task 1k: Create an underlying stream
for the decrypted data. task.
25. In the blank line below the comment, type the following code:
26. In the Task List window, double-click the TODO: Exercise 2: Task 1l: Create an AES decryptor
based on the key and IV. task.
27. In the blank line below the comment, type the following code:
28. In the Task List window, double-click the TODO: Exercise 2: Task 1m: Create a CryptoStream that
will write the decrypted data to the underlying buffer. task.
29. In the blank line below the comment, type the following code:
30. In the Task List window, double-click the TODO: Exercise 2: Task 1n: Write all the data to the
stream. task.
MCT USE ONLY. STUDENT USE PROHIBITED
L13-7
31. In the blank line below the comment, type the following code:
decrypt.Write(encryptedData, 0, dataLength);
decrypt.FlushFinalBlock();
32. In the Task List window, double-click the TODO: Exercise 2: Task 1o: Return the decrypted
buffered data as a byte[]. task.
33. In the blank line below the comment, type the following code:
return outStream.ToArray();
}
}
}
}
}
4. In the Browse For Folder dialog box, browse to the E:\Labfiles\Reports folder, and then click OK.
5. Click Print.
6. In the Save Print Output As dialog box, browse to the E:\Labfiles\Reports\ClassReport folder, in the
File name box, type 3CReport, and then click Save.
7. In the The School of Fine Arts dialog box, click OK, and then close the application.
Results: After completing this exercise, you should have a composite unencrypted report that was
generated from the encrypted reports.