56

Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Embed Size (px)

Citation preview

Page 1: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF
Page 2: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

There’s no better time to discover DevExpress.Visual Studio 11 beta is here and DevExpress tools are ready to run.

DXv2 is the next generation of tools that will take your applications to a new level.

Build stunning, touch enabled applications today.

Download your free 30-day trial at www.DevExpress.com

© 1998-2012 Developer Express Inc. ALL RIGHTS RESERVED. All trademarks or registered trademarks are property of their respective owners.

Introducing

Untitled-2 1 3/8/12 10:58 AM

Page 3: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

AN AGILE PRIMER

PLUS Bing Maps and the New

WPF Control Entity Framework ValidationTemplating with Knockout.js

APRI

L 20

12

Volu

me

22, N

o. 4

VisualStudioMagazine.com

In the mobile world, it’s all about time to market. If you’re not riding the Agile wave, it’s time to get on board.

Page 4: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Deliver the Ultimate User Experiencecheck out infragistics.com/ultimate

TREEMAPCommunicate the relative

differences in data weight

more effectively, with

customizable color and

flexible layouts.

FINANCIAL CHARTINGWith support for multiple

chart styles, and technical

indicators built in,

financial charting

capabilities are

on the money.

Infragistics Sales US 800 231 8588 • Europe +44 (0) 800 298 9055 • India +91 80 4151 8042 • APAC (+61) 3 9982 4545 Copyright 1996-2012 Infragistics, Inc. All rights reserved. Infragistics and NetAdvantage are registered trademarks of Infragistics, Inc. The Infragistics logo is a trademark of Infragistics, Inc.

NetAdvantage®

Untitled-6 2 3/7/12 1:34 PM

Page 5: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

GEOGRAPHIC MAPPlot millions of data

point over any type of

tile map source

or shape file.

OLAP GRID

Provide highly-

interactive pivot grid

functionality in all of

your applications.

BUSINESSCHARTING

Combine interactive

Outlook style grids with

rich business charting to

deliver a complete

portable solution.OLAP AXIS CHARTTake your data to new

depths with the

seemingly endless

drilldown capability of

the OLAP Axis Chart.

Untitled-6 3 3/7/12 1:34 PM

Page 6: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-1 1 10/11/11 11:43 AM

Page 7: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 3

FEATURES16 An Agile Primer

Agile development is growing in popularity for a reason: It results in faster time to market and, in most cases, better software. BY AARON BJORK

28 Map Your AppsBing Maps moves beyond Silverlight and AJAX with the new native WPF Control, which enables you to build interactive tools for visualizing geographical data on the desktop. BY DR. JAMES MCCAFFREY

LANGUAGE LAB 36 PRACTICAL .NET Integrating Validation with the Entity Framework

Validation should begin as close to your database as possible: in your Entity Framework entities. Here’s how you can integrate validation code into both the entities the Entity Framework generates and the ones you write. BY PETER VOGEL

42 C# CORNER Using Aspect-Oriented Programming

to Initialize and Connect WPF CommandsSee how a simple interceptor can help reduce the amount of coding needed to initialize your Windows Presentation Foundation ICommand properties. BY PATRICK STEELE

45 MOBILE CORNER Working with ListBoxes in a Windows Phone Application

By overriding templates, you can modify the look and feel of the ListBox without changing the underlying behavior. BY NICK RANDOLPH

DEPARTMENTS6 Letters to the Editor

8 DevDisastersReverse Psychology BY MARK BOWYTZ (THEDAILYWTF.COM) PAGE 8

10 DevInsights VSTOOLBOX, PAPA’S PERSPECTIVE

VSToolbox: Build Ribbon UIs with Add-in Express PAGE 10

Papa’s Perspective: Code Reuse with External Templates and Knockout.js PAGE 12

COLUMNS3 Frameworks BY KEITH WARD

48 Redmond Review BY ANDREW J. BRUST

16

April 2012 // Volume 22 // No. 4

Keith Ward, Editor in Chief, Visual Studio Magazine

{ F R A M E W O R K S }

Visual Studio AgilityOur cover story this month on Agile development comes at a good time, coinciding with the recent release of the Visual Studio 11 beta.

Agile methodology, as you probably know, is ramping up in a big way, continuing to bring new converts into the fold. It makes sense, especially with the growth of mobile applications for tablets and smartphones, where time to market is a critical factor. Getting there fi rst in this new world means shortening your development iterations.

But Agile methods aren’t just for mobile platforms. I was intrigued to fi nd out that Microsoft has implemented Agile techniques in a big way, including in the building of Visual Studio 11.

Microsoft’s Jason Zander, corporate vice president of the Visual Studio Team in the Developer Division, said in a recent interview with Visual Studio Magazine that about half the team developing Visual Studio 2010 had implemented scrum (for the uninitiated, scrum is an intensely focused version of Agile, with even tighter iterations). But for Visual Studio 11 (which doesn’t have an offi cial name yet), about 90 percent of the team is using scrum.

What’s the effect been on development for this huge project? Zander said it’s been signifi cant. “We’re going to wind up shipping the same volume of features with about half the milestones,” he noted.

Visual Studio 2010 had two betas, Zander added, while Visual Studio 11 will have one, for example. And we’re talking about “millions of lines of code,” according to Zander.

This means that no project is too big to be Agile, so if your software planning and execution strategies are still stuck in the last century, it’s time to fast-forward to 2012 and get back the edge that your competitors now have.

COVE

R IL

LUST

RATI

ON

BY

SHU

TTER

STO

CK.C

OM

/CLI

PARE

A/TI

SCH

ENKO

IRIN

A/VS

M S

TAFF

Page 8: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

4 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Get the complete picture —the latest dev news, analysis and how-to content—at VisualStudioMagazine.com and our partner sites in the Redmond Developer Network.

REDDEVNEWS.COM

Visual Studio 11 Beta Gets a New LookBY KATHLEEN RICHARDSVisual Studio 11 is in “lockstep” with the Windows 8 platform, according to Microsoft. That may explain the changes to the Visual Studio 11 beta UI, which are designed to promote Metro-style app development.

RedDevNews.com/Richards0212

New Windows Phone System Requirements Target Low-End DevicesBY GLADYS RAMAThe majority of apps in the Windows Phone Marketplace will run on the low-cost devices, according to Microsoft, but about 5 percent of apps will not work.

RedDevNews.com/Rama0212

Entity Framework Developers Clamor for Better SQL GenerationBY DAVID RAMELDeveloper complaints about SQL generation in the Entity Framework are often related to bloated code or slow performance. The core Entity Framework library update coming in the Microsoft

.NET Framework 4.5 will provide better SQL generation, but not for all listed scenarios.

RedDevNews.com/Ramel0212

ADTMAG.COM

Sonatype Java Repository Now Accepts .NET ComponentsBY JOHN K. WATERSSonatype Inc. released a new version of its Maven-based component repository. Nexus Professional 2.0, a widely used repository manager for Java components, adds support for developers who want to store and manage their .NET components in a repository.

ADTmag.com/Waters0212A

Agile Deadline Ahead: Calculating VelocityBY MARK J. BALBES, PH.D.The Agile Architect tackles how you can answer a key question of any development project: Are we going to make our deadline?

ADTmag.com/Balbes0212

Google, Microsoft, Apple Agree on Mobile Privacy AccordBY CHRIS PAOLISix tech companies have agreed to provide clear information on their individual privacy policies before their products are downloaded. According to California Attorney General Kamala D. Harri, developers who violate this accord could be prosecuted.

ADTmag.com/Paoli0212

EASY FINDITWhat we once called FindIT codes are now easy URLs. You’ll see these embedded throughout Visual Studio Magazine so you can access any additional information quickly. Simply type in VisualStudioMagazine.com/ followed by the FindIT code into your URL address field. (Note that all URLs do not have any spaces, and they are not case-sensitive.)

Online Contents

ID Statement Visual Studio Magazine (ISSN 1537-002X) is published monthly by 1105 Media, Inc., 9201 Oakdale Avenue, Ste. 101, Chatsworth, CA 91311. Periodicals postage paid at Chatsworth, CA 91311-9998, and at additional mailing offi ces. Complimentary subscriptions are sent to qualifying subscribers. Annual subscription rates payable in U.S. funds for non-qualifi ed subscribers are: U.S. $35.00, International $60.00. Annual digital subscription rates payable in U.S. funds for non-qualifi ed subscribers are: U.S. $25.00, International $25.00. Subscription inquiries, back issue requests, and address changes: Mail to: Visual Studio Magazine, P.O. Box 2166, Skokie, IL 60076-7866, email [email protected] or call toll free (888) 768-8759, fax number 847-763-9564. Interna-tional calls 847-763-9135. POSTMASTER: Send address changes to Visual Studio Magazine, P.O. Box 2166, Skokie, IL 60076-7866. Canada Publications Mail Agreement No: 40612608. Return Undeliverable Canadian Addresses to Circulation Dept. or XPO Returns: P.O. Box 201, Richmond Hill, ON L4B 4R5, Canada.

Copyright Statement © Copyright 2012 by 1105 Media, Inc. All rights reserved. Printed in the U.S.A. Reproductions in whole or part prohibited except by written permission. Mail requests to “Permissions Editor,” c/o Visual Studio Magazine, 230 California St. Suite 302, San Francisco, CA 94111.

Legal Disclaimer The information in this magazine has not undergone any formal testing by 1105 Media, Inc. and is distributed without any warranty expressed or implied. Implementation or use of any information contained herein is the reader’s sole responsibility. While the information has been reviewed for accuracy, there is no guarantee that the same or similar results may be achieved in all environments. Technical inaccuracies may result from printing errors and/or new developments in the industry.

Corporate Address 1105 Media, 9201 Oakdale Ave. Ste 101, Chatsworth, CA 91311 www.1105media.com

Media Kits Direct your Media Kit requests to Matt Morollo, VP Publishing, 508-532-1418 (phone), 508-875-6622 (fax), [email protected]

Reprints For single article reprints (in minimum quantities of 250-500), e-prints, plaques and posters contact:PARS International Phone: 212-221-9595 E-mail: [email protected] www.magreprints.com/QuickQuote.asp

List Rental This publication’s subscriber list, as well as other lists from 1105 Media, Inc., is available for rental. For more information, please contact our list manager, Merit Direct. Phone: 914-368-1000; E-mail: [email protected]; Web: www.meritdirect.com.

VISUALSTUDIOMAGAZINE.COM

Storyboarding in Team Foundation Server 11BY MICKEY GOUSSETThe Visual Studio Team Foundation Server 11 beta offers the fi rst chance to try out the new PowerPoint storyboarding add-in, designed to enable fast prototyping of a UI.

VisualStudioMagazine.com/Gousset0212

The Strategy Pattern in .NETBY ERIC VOGELC# Corner columnist Eric Vogel shows how to use a common software design pattern that allows an app to dynamically pick an appropriate method at runtime.

VisualStudioMagazine.com/Vogel0212A

Construct XAML Forms at Runtime with Resource FilesBY PETER VOGELWindows Presentation Foundation makes it easy to load non-executable resources at runtime—including a complete UI in XAML. See how you can leverage that functionality to create applications you can customize without recompiling.

VisualStudioMagazine.com/Vogel0212B

Page 9: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

1-855-221-2631 www.1and1.ca

1-877-461-2631 www.1and1.com

®

* 3 months free based on the basic confi guration ($49/month) for a total savings of $147. Setup fee and other terms and conditions may apply. Visit www.1and1.com for full promotional offer details. Program and pricing specifi cations and availability subject to change without notice. 1&1 and the 1&1 logo are trademarks of 1&1 Internet, all other trademarks are the property of their respective owners. © 2012 1&1 Internet. All rights reserved.

NEW!

1&1 DYNAMIC CLOUD SERVER

3 MONTHS

FREE!*

Base Confi guration, then $49/month

Only pay for what you need. Change your server specifi cations anytime!

Adaptable with up to 6 CPU, 24 GB of RAM, and 800 GB hard drive space

On-the-fl y resource allocation – hourly billing

Dedicated resources with full root access

Linux or Windows® operating systems available with Parallels® Plesk Panel 10.4

Free SSL Certifi cate included

2,000 GB Traffi c

24/7 Hotline and Support

1&1 servers are housed in high-tech data centers owned and operated by 1&1

NEW: Monitor and manage servers through 1&1 mobile apps for Android™ and iPhone®.

Untitled-3 1 2/29/12 1:44 PM

Page 10: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

6 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Inside Visual Studio 11Our March 2012 cover story, “More Power,” offered a tour of the productivity tools in Visual Studio 11 (still a code name) just in time for the release of the beta previews. Readers share their initial reactions to the updated beta tooling:

No macro? ... Hopefully they have fi xed the dreaded corruption of .resx fi les when using .NET 2 for x86 on x64 Windows, because I had to add a macro to fi x that. If they haven’t fi xed it, it’ll have to be a separate app, and that’s going to be a pain for source control issues and so on.

TimPosted Online

Nice to see that Silverlight is still a supported project type out of the box, but it’s weird that Model-View-Controller (MVC) 3 isn’t a default.

PhilipPosted Online

No Longer in the MIXMicrosoft canceled MIX12, the event targeted at Web developers and designers. In an online Papa’s Perspective column (“MIX: A Missed Opportunity for Microsoft?” Feb. 22, 2012), John Papa recalled the value of MIX and the confusion around the event. Readers respond:

I will go so far as to say it was a mistake. MIX was naturally evolving into a user experience (UX) conference, which was why it was so important—and the only conference that was critical, as the others were too developer focused. We need a MIX, meaning a Microsoft UX-focused, next-generation tech conference. Events like the open source event John Papa organized; and talks about UX and design as it applies to Microsoft technologies; and showcasing next-generation stuff without all the developer-focused stuff—that’s what will drive the community forward.

David J. KelleySeattle

I agree with Papa completely that the lack of focus was part of the MIX appeal. Web, mobile, design, UX, open source and other things MIX tackled all change too fast to have a set plan that works for all years. The fact that MIX adapted to the needs of the community was its greatest strength. The hardest part for me is that canceling MIX sends a clear message to agencies. As I posted a few months ago (bit.ly/sMFj1b), these moves make it very hard to present the Microsoft Web stack or Windows Phone as viable solutions to clients. When I’m telling a client that Microsoft gets the Web, and then they read that Microsoft is bailing on Web events, both of us lose a customer. Hopefully, Microsoft has a solution to address the gap left by MIX and it makes an announcement soon. I know agencies like ours are in a rough spot right now and feel a little left out.

Ian MuirPosted Online

Visual Studio Magazine wants to hear from you! Send us your thoughts about recent stories, technology updates or whatever’s on your mind. E-mail us at [email protected] and be sure to include your first and last name, city and state. Please note that letters may be edited for form, fit and style. They express the views of the individual authors, and do not necessarily reflect the views of the VSM editors or 1105 Media Inc.

Letters Check out our events at VSLive.comFor 2012, we’ll be in Brooklyn in May and

at Microsoft HQ in August!

VisualStudioMagazine.comApril 2012 • Volume 22 • No. 4

Editorial StaffEditor in Chief Keith Ward

Executive Editor Kathleen RichardsGroup Managing Editor Wendy Gonchar

Associate Managing Editor Katrina Carrasco

Tools Editor Peter Vogel

Contributing EditorsAndrew J. Brust, Ian Davis, Mickey Gousset,

Joe Kunk, Mark Michaelis, John Papa, Nick Randolph, Patrick Steele, Eric Vogel

Art StaffCreative Director Scott Shultz

Art Director Joshua GouldProduction Staff

Director, Print Production Jenny Hernandez-AsandasProduction Coordinator Serena Barnes

Online/Digital MediaSr. Director, Online Media Becky Nagel

Executive Editor, New Media Michael DomingoSite Administrator Shane Lee

Designer Rodrigo Muñoz

Advertising/SalesVP/Group Publisher Matt Morollo

Regional Sales Manager Chris KourtoglouNational Accounts Director William Smith

Microsoft Account Manager Danna Vedder

President Henry AllainVP, New Content Initiatives Doug Barney

Sr. Director of Marketing Michele Imgrund& Audience Engagement

Director of Online Marketing Tracy Cook

President & Neal Vitale Chief Executive Offi cer

Senior Vice President Richard Vitale & Chief Financial Offi cer

Executive Vice President Michael J. Valenti

Vice President, Christopher M. Coates Finance & Administration Vice President, Erik A. Lindgren

Information Technology & Application Development Vice President, David F. Myers

Event Operations

Chairman of the Board Jeffrey S. Klein

REACHING THE STAFFStaff may be reached via e-mail, telephone, fax, or mail. A list of editors and contact information is also available online at VisualStudioMagazine.com. E-mail: To e-mail any member of the staff, please use the following form: [email protected] Offi ce (weekdays, 9:00 a.m. - 5:00 p.m. PT)Telephone 949-265-1520; Fax 949-265-15284 Venture, Suite 150, Irvine, CA 92618Framingham Offi ce (weekdays, 9:00 a.m. - 5:00 p.m. ET)Telephone 508-875-6644; Fax 508-875-6633600 Worcester Road, Suite 204, Framingham, MA 01702Corporate Offi ce (weekdays, 8:30 a.m. - 5:30 p.m. PT)Telephone 818-814-5200; Fax 818-734-15229201 Oakdale Avenue, Suite 101, Chatsworth, CA 91311

Visual Studio MagazineThe opinions expressed within the articles and other contents herein do not necessarily express those of the publisher.

Page 11: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

MOTION FRAMEWORK

Create data visualizations

that deliver an animated

user experience that tells

the whole story.

MAPEnsure your geospatial

data really goes places

with a feature-laden,

interactive Map Control

for your applications.

XAML-IFY YOUR APPScheck out infragistics.com/xaml

Infragistics Sales US 800 231 8588 • Europe +44 (0) 800 298 9055 • India +91 80 4151 8042 • APAC (+61) 3 9982 4545Copyright 1996-2012 Infragistics, Inc. All rights reserved. Infragistics and NetAdvantage are registered trademarks of Infragistics, Inc. The Infragistics logo is a trademark of Infragistics, Inc.

XAMTRADERBuild high-performance

applications using ultra-

fast grids and charts.

NETWORK NODEHelp your users make

the connection with

visual representations

of simple or complex

network relationships.

NetAdvantage®

for Silverlight Data Visualization

NetAdvantage®

for WPF Data Visualization

NetAdvantage®

for Silverlight

NetAdvantage®

for WPF

Untitled-11 1 3/7/12 2:43 PM

Page 12: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

8 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

</DevDisasters>

ILLU

STRA

TIO

N B

Y SH

UTT

ERST

OCK

.CO

M/A

LBU

MKO

RETS

KY

Everything at Henry’s company revolved around contracts with vendors. The IT department had relied on the aptly named Contract Manager—the sole remaining Visual Basic 6 client-server application—to support that business for the past 12 years.

Contract Manager was a rotten apple in the IT department’s orchard of .NET Web apps. Its picky nature kept the company one release behind the latest Windows version, just to be on the safe side. The system’s logic was ineffi cient and tangled, making it a pain to develop and maintain.

The only reason anyone could fi gure it was still around was because, though old, Contract Manager rarely broke. Rest assured, though, on those rare occurrences when it did break, people noticed.

Break Big or Not at All“The Contract Manager is crashing!” yelled a voice on the phone. “We can’t add new contracts into the system! This is really critical!”

Henry was jarred upright. He wasn’t used to these kinds of calls.“Um, OK. Well, are you getting any error messages?” Henry

stammered, but it was of no use—the line was already dead. Call after call came in and played out the same way.

One user, who followed up with an e-mail after Henry ignored her phone calls, was kind enough to include a screenshot of the error, which pointed to a culprit:

Integer Overflow on N_CONTRACT_ID.

Henry gulped.He knew that in Visual Basic 6, integers overfl ow at 32,768.

Could it be that users had managed to exhaust all of the possible Contract ID numbers? Henry quickly checked to confi rm his

suspicions and sure enough: the 32,768th contract was entered earlier that morning.

Henry knew he could easily fi x the code to accept larger IDs, but there was a catch. The Contract Manager .EXE was compiled against a COM+ DLL. This meant Henry had a choice. Fix the COM+ DLL to allow for larger Contract IDs, recompile the client, and force everyone to upgrade the right way (and take forever) … or he could hack it.

Strike That—Reverse ItHenry had a bold idea . While he was out of positive ID numbers, there were plenty of negative ones. He turned the sequence that generated Contract IDs around, so that it started at -1 and counted down, but that created a new problem.

Contract Manager had huge amounts of business logic in the database, and that meant that it was scattered in dozens of procedures, packages and views. The code to fetch the latest contract resembled the following:

WHERE q.n_contract_id =

(SELECT MAX(n_contract_id) FROM contract_rev cr WHERE cr.n_bid = q.n_bid)

So, Henry brute-forced it and replaced all of the SELECT MAXs with this code:

SELECT CASE

  WHEN MIN(n_contract_id) < 0 THEN MIN(n_contract_id)

  ELSE MAX(n_contract_id)

END CASE

Terrible, kludgy and awful, but in the end, it worked! Henry had squeezed another decade out of Contract Manager. He just hoped the system wouldn’t be around that long. VSM

Reverse Psychology

{ S O F T W A R E D E V E L O P M E N T G O N E W R O N G }

SERVED UP BY MARK BOWYTZ

Mark Bowytz is a contributor to the popular Web site The Daily WTF (thedailywtf.com). He has more than a decade of IT experience and is currently a systems analyst for PPG Industries. Have you experienced the darker side of development? E-mail your tale to Executive Editor Kathleen Richards at [email protected].

Tell Us Your Tale

Could it be that users had managed to exhaust all of the possible Contract ID numbers?

Page 13: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

SMART, STYLISH UI

SOLUTIONS

The most sophisticated set

of continually enhanced,

performance-dominating

Windows Forms UI controls

available anywhere.

CHARTINGWith advanced graphics and

more than 50 2D and 3D

Chart Types, easily create

and customize the

best visualizations of

your information.

check out infragistics.com/windowsforms

Infragistics Sales US 800 231 8588 • Europe +44 (0) 800 298 9055 • India +91 80 4151 8042 • APAC (+61) 3 9982 4545Copyright 1996-2012 Infragistics, Inc. All rights reserved. Infragistics and NetAdvantage are registered trademarks of Infragistics, Inc. The Infragistics logo is a trademark of Infragistics, Inc.

GANTT VIEWPlan for success

Microsoft Project-

style, with Timeline

and Grid Views,

Styling capabilities

and support for

Custom Columns.GRIDBe more productive

with this hierarchical

data grid control as

the backbone of

your applications.

NetAdvantage®

for Windows Forms

Modern Applications Need Sophisticated Controls

Want to ensure

your WPF and

Windows Forms

application UIs are

fully optimized?

TURN THE PAGE!

Untitled-3 1 3/7/12 1:28 PM

Page 14: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

10 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

VSToolbox

BY PETER VOGELSharePoint 2010 and Office 365 both revolve around a “Web-inized” version of the infamous Office Ribbon menu. As a result, if you want to integrate your code with SharePoint or Office 365, you’ll need to extend the Ribbon. If your only tools are Visual Studio and SharePoint, then you’ll be forced to either craft arcane XML or limit yourself to the three options offered by the SharePoint Ribbon wizard.

Ribbon Designer from Add-in Express Ltd. can help by providing a Visual Studio visual designer for creating rich Ribbon UI menus. The company’s tools are designed to make Office development easier for Visual Studio developers—and, with this latest offering, Add-in Express seems determined to follow that mandate into the cloud.

With Ribbon Designer, you can create a new Ribbon project or add a Ribbon to an existing project. Either choice creates all the necessary element and feature files, along with an EventReceiver file that’s associated with the visual designer. You use the designer’s toolbar to add tabs and context groups to the Ribbon. Your menu controls (either provided by Add-in Express, or your own custom controls) are added to those tabs and context groups in the form of one or more RibbonGroups.

Add-in Express provides a wide range of controls for you to use in your menu. Of course, you get a button, but you also get (among other controls) a toggle, a checkbox, a dropdown list, a color picker, a label, and a variety of separator and container controls. After adding a control, you can set properties on it and attach code to its events. You can also import controls from existing Ribbon XML files.

Ribbon Designer includes a TreeView that allows you to navigate through the nested containers in the visual designer.

Unfortunately, while the TreeView displays the names for the containers, for controls it only displays the class name (for instance, ADXSRibbonDropDown). In a complicated menu, this makes it more difficult to figure out what you’ve selected in the TreeView.

Workaround for Sandbox SolutionsMany of the Ribbon controls support both client-side (JavaScript) and server-side events, but some controls (the dropdown list, for instance) only support client-side events. The server-side events aren’t supported in sandboxed solutions, so you’ll need to leverage the Client Object Model to implement server-side changes.

Installing the package was simple. I downloaded it from the Add-in Express site, but you can also get it through Visual Studio Extension Manager on th e Visual Studio Tools menu. The installation package

includes a Developer’s Guide in PDF format. If you want to try the product out before buying, there’s a trial version that limits you to creating Ribbons with one tab holding one control group. The full version is just $99, but if you also want the source code, you can get the Professional version for $100 more.

You can still use XML to create or modify your Ribbon menus. But Ribbon Designer frees you to do what Visual Studio programmers do best: design the UI visually and add the code to make it work. VSM

Peter Vogel is the Visual Studio Magazine tools editor and a principal at PH&V Information Services, specializing in ASP.NET development.

Ad

d-i

n E

xpre

ss

Rib

bon

Des

ign

er

</DevInsight>

To make it easier to handle nested controls within the menu’s containers, the designer includes a TreeView display of all the controls.

Ribbon Designer

Add-in Express Ltd.Web: add-in-express.comPhone: 375 (291) 944101Price: $99 for Standard version; $199 for Professional (includes source code)Quick Facts: A visual designer for creating and modifying Ribbons for SharePoint 2010 and Office 365Pros: Enables programmers to create Ribbon menus the way they prefer: adding controls to a Visual DesignerCons: Not functional for sandboxed SharePoint solutions

Build Ribbon UIs for SharePoint and Office 365 with Add-in ExpressIf you want to customize the SharePoint 2010 and Offi ce 365 Ribbon, the Add-in Express Ribbon Designer eases UI development in the cloud.

Page 15: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Application Assurancecheck out infragistics.com/testadvantage

Infragistics Sales US 800 231 8588 • Europe +44 (0) 800 298 9055 • India +91 80 4151 8042 • APAC (+61) 3 9982 4545Copyright 1996-2012 Infragistics, Inc. All rights reserved. Infragistics and NetAdvantage are registered trademarks of Infragistics, Inc. The Infragistics logo is a trademark of Infragistics, Inc.

ARE YOUR WPF AND WINDOWS FORMS APPLICATIONS FULLY OPTIMIZED? Reduce the risks associated with project development and deployment of your applications

with TestAdvantage for WPF and Windows Forms, the first out-of-the-box tools to enable

automated of testing of applications built with NetAdvantage for WPF and Windows Forms

toolsets. TestAdvantage for WPF (for HP QuickTest Professional) and Windows Forms

(for HP QuickTest Professional or IBM Rational Functional Tester) extend the capabilities of

your testing environment to ensure your applications are designed and optimized for success.

TestAdvantage®

for Windows Formsfor HP QuickTest Professional software

TestAdvantage®

for Windows Formsfor IBM Rational Functional Tester

TestAdvantage®

for WPFfor HP QuickTest Professional software

Untitled-3 1 3/7/12 1:29 PM

Page 16: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

12 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Papa’sPerspective

Model-View-ViewModel, data binding and separation of concerns are just some of the reasons that Knockout.js, which I introduced in a recent column (“2 Great JavaScript Data-Binding Libraries,” February 2012), has become a popular data-binding library in the Web community. Knockout supports external templating libraries such as jQuery templates, but, starting with Knockout 2.0.0, it also includes its own native templating engine.

Templating has become second nature to many developers. Whether you use Model-View-Controller (MVC) or XAML or JavaScript, there’s often a need to separate a section of structure into its own unit of work or template.

In HTML, it’s common to have a structure that you want to repeat in many places. Whenever you see a structure that needs to be reused, templates should pop into your head.

Another common use for templates is in object hierarchies where you need to dive into a list of items and want to use the same structure for each item.

Inevitably your app will pile up the templates and you’ll want to keep them in a separate file. Separating the templates into files has a few immediate advantages. First, it can reduce the structure in your main HTML file (less to look at is easier to grok).

Second, just-in-time (JIT) templates allow you to grab them as needed and leave the others on the server.

Templates EverywhereThe Knockout native template engine offers multiple ways to implement templates. You can name templates and refer to them in a script tag by their id. This is a popular technique used by other engines such as jQuery templates. Another option is to use anonymous templates inline. I prefer anonymous inline templates when my template won’t be reused because it keeps my HTML flowing, as opposed to having to go find a script tag somewhere else (which breaks my flow).

The following code shows a simple Knockout anonymous inline template that implicitly creates a template for the <li> elements. Notice there’s no name for the template because it’s all inline, which is nice and clean:

<ul class="smallList" data-bind="foreach:products">

<li data-bind="css: {selected: isSelected}"

class="selectable">

<div data-bind="text: shortDesc,

click:$root.selectProduct">

</div>

</li>

</ul>

Your HTML page could also contain another template, perhaps to display the selected product’s details. This master list and item details scenario is pretty common and templates make a lot of sense for it. Listing 1 shows the product-details template contained within a script tag.

The output for the HTML page is shown in Figure 1 (p. 13). The anonymous template is used in a list to display each product, which ends up rendering nine times. The script template is used to render the details of the product. The source for this sample is in the file 01-ko-anonymous-and-script-template.html in the code download (VisualStudioMagazine.com/Papa0412).

External TemplatesThe previous example puts the templates inline and in script tags, but they’re still in the same file. If these templates are moved to separate files, they can be reused. One way to tackle this is to store the templates in another file, wrap them in script tags, give them each an id and write a function that loads the templates via AJAX. The function has to ensure the Knockout bindings do not apply until all templates are returned, and handle other errors that could arise. Fortunately, there’s a way to do this that requires practically no coding effort.

Jim Cowart recently wrote a plug-in for Knockout called Knockout.js External Template Engine. You can find the source for this library on GitHub at bit.ly/mVXdye,

Kn

ocko

ut

Ext

ern

al T

empl

ates

</DevInsight>

Code Reuse with External Templates and Knockout.jsExternal templates allow you to reduce the code in your main HTML page, and reuse it in multiple places.

BY JOHN PAPA

Listing 1. The product-details template contained within a script tag.

<script id="productDetails" type="text/html"><div data-bind="with: selectedProduct"> <div class="photoContainer leftFloat"> <img src="/images/guitar.jpg" data-bind="attr: {alt: shortDesc}" class="photoThumbnail"></img> </div> <div> <span>Brand: </span> <span data-bind="text: model().brand" class="textValues"></span> </div> <div> <span>Model: </span> <span data-bind="text: model().name" class="textValues"></span> </div> <div> <span>Price: </span> <span data-bind= "text: my.formatCurrency(salePrice())" class="textValues"></span> </div> <div> <span>Description:</span></div> <div> <span data-bind="text: description" class="textValues"></span> </div></div></script>

Page 17: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

vslive.com/newyork

➤ Windows 8 / WinRT➤ Silverlight / WPF➤ Web➤ Visual Studio 2010+ / .NET 4.0➤ Cloud Computing

➤ Data Management➤ HTML5➤ Windows Phone 7➤ Cross Platform Mobile

Check out the hot track topics that will make YOU a more valuable part of your company’s development team:

Brooklyn, NY | May 14-17 | NY Marriott at the Brooklyn Bridge

YOUR MAP TO THE .NET DEVELOPMENT PLATFORM

Intense Take-Home Training for Developers, Soft ware Architects and Designers

BIG CODE IN THE BIG APPLE

Page 18: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

➤ In-depth training for all levels of developers➤ A stellar speaker lineup that includes top

industry experts and Microsoft insiders➤ 60+ educational sessions ➤ 9 tracks that cover today’s hot topics➤ Pre-event full-day workshops➤ Special events and networking opportunities Scan the QR

code for more information on Visual Studio Live!

Use Promo Code VTIP

Register BeforeApril 11th and Save $200!

vslive.com/newyork

Brooklyn, NY | May 14-17 | NY Marriott at the Brooklyn Bridge

PRODUCED BYSUPPORTED BY MEDIA SPONSOR

Page 19: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 13

Kn

ocko

ut

Ext

ern

al T

empl

ates

or you can use NuGet to add a reference to it from your Visual Studio project (which is my preference). This library extends the native template engine built into Knockout so you don’t have to alter your code. It works with jQuery templates, too, if you go that route. For this example, I’m going to stick with the Knockout native templates.

Linking to the External Template EngineThe quickest way to get up and running is to grab the package using NuGet and add a link to the koExternalTemplateEngine_all.js file in your HTML page. Make sure you put the koExternalTemplateEngine file after the links to jQuery and Knockout, because it depends on both of those libraries:

<script src="/scripts/jquery-1.7.1.js"

type="text/javascript"></script>

<script src="/scripts/knockout-2.0.0.js"

type="text/javascript"></script>

<script src=

"/scripts/koExternalTemplateEngine_all.js"

type="text/javascript"></script>

There’s also a minified version of the library that I recommend using in production. The koExternalTemplate-Engine_all.js file contains the TrafficCop and infuser libraries, too, which is a nice convenience. If you want to, you can link to the libraries separately, as they’re all included in the NuGet package.

Ready, Set, GoOnce you’ve linked to the library, using it is simple. You can move the productList template containing the <li> tags to its own file in the /templates/product List.tmpl.html

file. The productDetails template in the script tag can also be moved to its own file in /templates/productDetails.tmpl.html. This removes the templates from the flow of the page and allows them to be reused.

The productDe-tails.tmpl.html file now contains the contents of the template without the

script tag wrapper. This is nice because it allows Visual Studio and its great IntelliSense to shine through on the HTML. Also, with the template in another file, it can be retrieved as needed, JIT.

Knockout can refer to the template by name, where the convention is the name of the file. Most templates will follow a naming convention, so you can set the prefix or suffix of the templates using some JavaScript:

infuser.defaults.templateSuffix = ".tmpl.html";

This JavaScript indicates that by default, all templates will have a suffix of .tmpl.html. This means the Knockout code can refer to the template by the name of the file, without the extension.

Another common technique is to put all of the templates in a special folder. The following code shows how you can set the default folder for the templates:

infuser.defaults.templateUrl = "/templates";

These defaults can be overridden as needed, so I recommend using them for the most common template settings.

You can also use a template simply by referring to its name by string (this code retrieves the productList.tmpl.html template in the /template folder):

<ul class="smallList" data-bind="template:

{name: 'productList', foreach:products}">

</ul>

If you prefer Knockout’s containerless, comment-based syntax, you can refer to a template as shown in this sample code, which also passes the selectedProduct to the template as its data context:

<!-- ko template: {name: 'productDetails',

data: selectedProduct}-->

<!-- /ko -->

This code will retrieve the product-Details.tmpl.html template from the /templates folder. If you want to override one of the default settings, such as the URL location of the templates, you can override them inline. This code indicates that the template is located in the /somewhere folder:

<!-- ko template: {name: 'productDetails',

data: selectedProduct,

templateUrl: '/somewhere'}-->

<!-- /ko -->

The main settings for the Knockout external template library are templateSuffix, templatePrefix, templateUrl and loading-Template.content. The latter can be set to indicate the HTML content that will be displayed while the template is loading. You don’t need to override the default loading content unless you want to follow a custom style. You can also override AJAX settings such as ajax.cache. The complete HTML source code for the external template sample can be found in 02-ko-external-template.html, while its JavaScript can be found in 02-ko- external-template.js.

Wrapping UpUsing external templates lets you reduce code in your main HTML page and reuse it in other places, which is great for maintenance. I highly recommend the Knockout External Template library; it’s easy to integrate and unobtrusive. And that is Papa’s perspective. VSM

John Papa is a Microsoft Regional Director and former Microsoft technical evangelist. Author of 100-plus articles and 10 books, he specializes in professional application development with Windows, HTML5, JavaScript, CSS, Silverlight, Windows Presentation Foundation, C#, .NET and SQL Server. Check out his online training with Pluralsight or find him at johnpapa.net and on Twitter at twitter.com/john_papa.

GO ONLINEGo to VisualStudioMagazine.com/Papa0412 to read th is article online and to download the sample code.

Papa’sPerspective

Figure 1. The anonymous template is used in a list to display each product, which ends up rendering nine times. The script template is used to render the details of the product.

Page 20: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-1 2 12/1/11 1:58 PM

Page 21: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-1 3 12/1/11 1:58 PM

Page 22: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

16 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

ILLU

STRA

TIO

N B

Y SH

UTT

ERST

OCK

.CO

M/C

LIPA

REA/

TISC

HEN

KO IR

INA/

VSM

STA

FF

VSM COVER STORY

Do you remember who the popular kids were in your high school? If you’re like me, it was fairly easy to identify who was a part of the “in crowd” during your younger years. It’s hard to describe what separated them from others, but in a subtle way it was obvious. The popular kids stood out. Others gravitated toward them, wanting to be included in the “inner circle.” They were different.

In many ways, Agile practices are the “popular kids” of the software industry today. Most development shops have either tried them, are in the process of trying them or are planning to try them. Some shops are finding success; others are struggling to see what’s different. Regardless, the popularity of Agile practices can no longer be ignored. They’ve arrived on the scene, and are becoming more and more mainstream.

If you’re new to Agile software development, you’ll want to start by reading and understanding the “Agile Manifesto” (agilemanifesto.org). In short, 10 years ago in Snowbird, Utah, a group of software profes-sionals met to search for answers as to why some software projects

ANAGILEPRIMER

Agile development is growing in popularity for a reason: It results in faster time to market and, in most cases, better software.BY AARON BJORK

Page 23: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 17

VSM COVER STORY

are successful, and some are not. The result of that meeting was the creation of the Agile Manifesto: four value statements and 12 principles that define and guide the approach known today as Agile software development. The four pillars:

1. Individuals and interactions over processes and tools2. Working software over comprehensive documentation3. Cu stomer collaboration over contract negotiation4. Responding to change over following a planThe manifesto states up front that while there’s value to each item

on the right side of a statement (for instance, processes and tools), there’s more value in the items on the left side of each statement (for instance, individuals and interactions). I won’t comment more on the history of the manifesto, but will point out that the creation of the Agile Manifesto set the stage for the growing movement to adopt Agile practices. That movement has taken root and is now a mainstream part of the software development world.

Last summer, Dave West of Forrester Research Inc. published an article touting the rising popularity of Agile in today’s organizations (“Water-Scrum-Fall Is the Reality of Agile for Most Organizations Today,” July 26, 2011). In that article, West states: “Forrester has observed Agile changing from an approach practiced only by Agilists to one that many organizations employ. We continue to see Agile methods gaining popularity; in a Q3 2010 survey fielded by Forrester Research and Dr. Dobb’s Journal, about 39 percent of 1,023 IT professionals said that they follow an Agile method.” (See Figure 1for a graphical breakdown of the survey results.)

Evolving EnvironmentsLet’s first take a look at why Agile is catching on. What’s driving the popularity? What’s different? The place to start is by looking at the environments in which software is used, purchased and developed.

I clearly remember my software buying habits back in the late ’90s and early 2000s: I’d drive to one of the “big box” stores and peruse the shelves, flipping over product boxes to stare at the screenshots on the back. I’d then glance at the “requirements” section to make sure my PC at home had enough RAM and hard disk space to keep up. After making a decision, I’d buy the box, drive home, and spend the next few hours installing and configuring the software for use. This was normal. This was how we made software decisions. A lot has changed.

I honestly don’t remember the last time I bought a piece of software that came in a box—or even on a piece of physical media, for that matter. It’s just not the way things operate in today’s world. Instead we down-load, we “try” for free, or we buy from our phones or tablets with the touch of a finger. What used to require a car trip and a card-board box now requires simply an Internet connection. If I don’t like the result, I try something else. Switching is easy. The barriers and investment that used to exist are gone. Again, a lot has changed.

Because of this change, anyone building software has been forced to look for new ways to operate. There’s an increasing need

to make better decisions and eliminate waste. Diego Lo Giudice and Dave West from Forrester Research said it best in their article,

“Transforming Application Delivery” (bit.ly/z4jJsu): “Firms today experience a much higher velocity of business change. Market oppor-tunities appear or dissolve in months or weeks instead of years. This increased business velocity demands much greater agility from business systems.”

A need has developed for a new approach to building software. Enter Agile processes and methods. They’re new, they’re lighter-weight and they provide the perfect environment for building software in today’s world. In the remainder of this article, I’ll outline a few key factors I feel are absolutely necessary to be successful with Agile. I won’t spend any time focusing on specific practices (daily stand-up, pairing and so on) or methodologies like scrum and extreme programming. Instead, I want to examine the environment an Agile team works in and lay out a few concrete steps necessary for an Agile transition.

Building an EnvironmentI live in the Pacific Northwest and have for all of my life. Yes, the rumors you’ve heard are true—it does rain a lot. Despite the rain, we get a reasonable amount of sun each summer and generally have a very pleasant climate. A few years ago my wife and I decided to experiment with a vegetable garden. We had some extra space in our yard and it seemed like a fun experiment to see if we could grow something that we would actually eat. This experiment led me to build a series of raised gardening beds in our yard where our bountiful harvest would thrive. At least, that was the plan. I actually ended up building the beds twice after learning that treated lumber has high amounts of arsenic in it. Arsenic and edible vegetables are not a good mix. Lesson learned.

Figure 1. Agile development is the most popular methodology today, according to Forrester Research Inc.

“Please select the methodology that most closely reflects the developmentprocess you are currently using.”

2010*2009†

*Base: 1,023 application development professionals†Base: 1,298 application development professionals

(”other” responses not included; percentages may not total 100 because of rounding)

*Source: Forrester/Dr. Dobb’s Global Developer Technographics® Survey, Q3 2010†Source: Forrester/Dr. Dobb’s Global Developer Technographics Survey, Q3 2009

Iterative:2010 — 19.5%2009 — 20.6%

Traditional:2010 — 13.0%2009 — 13.4%

Agile 35.4%38.6%

Do not use a formal process methodology 30.6%28.8%

Iterative Development 16.3%16.1%

Rational Unified Process (RUP) 2.7%1.9%

Spiral 1.6%1.5%

Waterfall 8.4%9.4%

Capability Maturity Model Integration (CMMI) 2.5%2.2%

ISO 9000 2.5%1.4%

Page 24: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

18 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Agile PlanningCOVER STORY

The point is that to successfully grow vegetables, it was necessary to create a healthy environment for the vegetables to grow. This included picking a spot in our yard that received the right amount of sun. It included creating a place for the garden and constructing a place for the plants to live. It also included adding rich soil to the garden and eliminating weeds that would choke out the plants. In the end, we were quite successful. We had more tomatoes than we knew what to do with, zucchini coming out of our ears, and enough lettuce and carrots to keep us going all summer. The garden was a success, and the environment we created was critical to that success.

I have no doubt that if we had taken a different and more cavalier approach, our harvest would have been significantly less. Imagine if I’d simply wandered into my backyard and scattered seeds in random places, “hoping” they’d grow. We might have ended up with a zucchini or two, but I’m sure the harvest would have looked much different. Moving to Agile is no different. You can’t just say,

“We’re going to be Agile,” and expect good things to happen. You’ve got to go out and create an environment where new practices and new thinking will work.

3 MotivationsSo, where do you start in creating a healthy environment? I believe the No. 1 place is motivation. Agile is about the team: the people building the software. To build a great environment for teams, you need to understand what motivates them. This brings me to a book I read a few years ago by Daniel Pink: “Drive: The Surprising Truth About What Motivates Us” (Riverhead Hardcover, 2009). It was a book I couldn’t put down; it captivated me and opened my eyes to some truths about motivation.

In “Drive,” Pink contrasts traditional motivation techniques (rewards and punishment) with three new essentials critical to moti-vation in today’s environment: autonomy, mastery and purpose. These three essentials lead to what Pink describes as “intrinsic motivation.” The idea is that we all crave autonomy, mastery and purpose in everything we do. When individuals and teams find these things, good things happen. Let’s define them.

1. Autonomy. The first essential presented by Pink is autonomy: The ability for one to make his own decisions. For a software development team, this is critical. A team needs to feel empow-ered, and a team needs to be empowered. Why? Because Agile teaches us that change is inevitable during the software develop-ment process. Learning about the product, the architecture and the customers will occur after the team has started executing. The team must feel empowered to react to change and commu-nicate what it’s learning. This doesn’t mean the team should have the authority to do whatever it wants; rather, it gives the team freedom to do what’s right. A team lacking autonomy is more likely to blindly follow a plan handed down from above while ignoring critical learning.

2. Mastery. The concept of mastery is fairly simple: People want to get better at what they do. We find this in all areas of life. Part of our basic DNA involves the desire to improve. Toddlers work tirelessly to master the art of walking. They usually need very little encouragement. By nature, they have a deep-rooted desire to master walking, and they work at it until it becomes second nature. This doesn’t change as we get older. I love to play golf and I have a desire to be a better golfer year after year. Improvement is part of my love for the game. I’m certainly not a master (my career on the PGA Tour hasn’t yet materialized), but I continue to strive to improve hole after

hole, round after round, year after year. The process and the results are exhilarating.

Software teams are no different. Every software team has a basic desire to find newer and better ways to accomplish the goal set before it. Members of the team love to build software and love to solve difficult problems. If they didn’t, they wouldn’t be in a dif-ficult industry. The challenge and art of building an elegant yet functional solution drive them. Too often, however, we treat teams and the people on them as if they’re pieces on a game board that can be moved, shifted and changed without conse-quences. We shuffle resources, change goals and randomize their priorities. By doing this we remove their ability to become masters. It’s a pattern I see repeated again and again in the industry.

3. Purpose. The final essential laid out by Pink is purpose. Teams have a deep-rooted desire to understand how their work fits into the big picture. As an engineer, I want to understand why the software I’m building matters. We need a reason, and a pur-pose. As a leader in your organization, find ways to ensure that your team understands how the value it produces is contributing to the business. Communicate the importance of new features delivered in the last sprint. Show them delighted customers benefiting from their solutions. Too often we disconnect our development teams from the business and from customers. We do this because we think they don’t care, or we’re worried that we’ll distract them. However, more often than not we end up alienating them and destroying their sense of purpose.

Less Is MoreThe second key to creating a healthy environment for Agile is to eliminate waste and unnecessary steps in your process. I’m talking about those things you’ve done forever, but nobody is really sure why. I often refer to them as taxes, because more often than not, doing these things feels like paying taxes. They are things that “must” be done (at least according to some handbook or list of rules somewhere), and yet they are things the team rarely understands, likely cares little about and receives very little value from. To the team, these tasks feel like a black hole. High taxes will kill an Agile team.

If you’re part of the leadership team in your organization, this is where you take a long look in the mirror. What taxes are your teams subjected to? Why are they necessary? If you’re having a hard time coming up with a list, I can guarantee that if you walk up to any member of your team and ask for a few suggestions, you’ll receive a lengthy list. Most lists like this are filled with steps designed to reduce risk. Don’t get me wrong: I’m all for managing and minimizing risk. It’s absolutely necessary to ship high-quality software on time. However, risk-management techniques can quickly lead to a high-tax environment.

I’ve found in all the organizations I’ve worked for that the process the organization follows tends to “snowball” over time. You pick up a new guideline or rule in each release, and before you know it your teams are spending so much time checking all the boxes on the release checklist that they end up with little time to create value for customers. The goal should be to create an environment where your team members can maximize the value they produce. The process should be as absolutely simple and streamlined as possible. Try eliminating a few of the taxes on your teams and see what happens. If they prove necessary, add them back; or better yet, engage the team on how to solve the problem long-term. Whatever the case, ensure that you’re not burdening your teams with unnecessary or outdated taxes. A simple process is always a better process.

Page 25: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-5 1 2/29/12 2:14 PM

Page 26: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

20 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Agile PlanningCOVER STORY

Steps to Becoming AgileNow that we’ve established a few key principles to building an envi-ronment for Agile to succeed, I want to outline a few clear and concrete steps you can take in your own Agile transformation. With the popularity of Agile increasing, there has been a corollary increase in the amount written on the topic. The fact that you’re reading this article proves that point. However, among all that

“guidance” it’s often difficult to understand where to start. How do you actually put any of this into practice? The statements from the Agile Manifesto sound great, but what steps can you take to make them a reality? In the sections that follow I hope to lay out some practical guidelines you can use in your own shift toward an Agile approach to software development.

The Finish LineThe first step is to establish a clear finish line for everything your organization is doing. A finish line can never be crossed if it doesn’t exist or is constantly changing. How gratifying would it be in a foot race if each time you approach the end of the race, someone ran out and informed you that the line had changed and was now another half-mile down the road? Crazy, right?

Things are no different with software teams. It’s absolutely neces-sary that everything a team works on has a clear definition of “done” (or finish line). This doesn’t just apply to project milestones or even iterations of work. It applies to everything from daily tasks to the completion of user stories from the backlog.

Try this exercise. Sit with your teams and talk about what “done” means for everything they do. When is a task from the backlog done? Is checking in the code enough? Does it require a code review by another peer? How about testing? Likewise, what does the finish look like for the next iteration of your current project? Does it include setup and upgrade logic? What about end-to-end testing? How about support and documentation?

This is important because, without a clear finish line, you won’t have any semblance of predictability on your projects. Most of us are very good at creating and doing work. Finishing work is a lot harder. There are countless examples of projects that were started flawlessly but never finished because there was never a clear finish line.

Shorten Your IterationsThe next step to becoming more Agile is to shorten the iterations in which your teams work. I don’t think there’s a “one size fits all” itera-tion that works for every organization, so it’s up to you to figure out the correct length based on your circumstances. There’s no doubt, however, that shortening your iterations can greatly benefit your team.

For starters, shorter iterations help a team develop a habit of fin-ishing what they start (see the previous section). Finishing a one-mile run is a lot easier than finishing a marathon. The problem is we often send our teams off to run marathons instead of more realistic dis-tances. Start your teams with a few 100-yard dashes before advancing to longer races. The point is, you want your team and your organiza-tion to have an ingrained sense of the importance of finishing. Value can’t be delivered until you’re done.

Second, shorter iterations aid in achieving a higher yield on time spent planning. A traditional approach to planning requires spending large amounts of time up-front studying requirements, architecture and design options. This is done to produce a plan that will guide you to success. Without the correct initial plan, the project won’t succeed.

Agile teams think differently. An Agile approach to planning also involves studying requirements, architecture and design—but an Agile approach puts a stronger emphasis on getting started with the well-known and well-understood requirements and architecture over continued planning. The expectation is that the team will derive greater value from starting on the known requirements than it will from continuing to invest in additional planning. Said differ-ently, the value of any learning that results from getting started will have a greater return on investment (ROI) than the value from continued planning.

Figure 2 and Figure 3 illustrate this point. Notice how in Figure 2 ROI begins to diminish over time. This is because continued planning is based completely on assumptions made in the early stages of planning.

Figure 3 shows an Agile approach. Planning begins in the same manner, but shortly after the planning starts it’s stopped in order to begin execution. Why? Because the team anticipates learning more from getting started than it would learn from continued planning. After the team has executed on the well-known and well-understood, it returns to planning. This process continues throughout the duration of the project.

Try shortening the iterations on your teams and see if you don’t see immediate results when it comes to your investment in planning. George Patton said it best: “A good plan executed violently today is better than a perfect plan executed next week.”

Use the Front DoorBefore a team can execute and finish work, they have to receive it. For an Agile team, the only way to receive work is through the product backlog. I call this the Front Door Principle, and it’s absolutely critical to becoming Agile. Start by thinking of teams as occupying houses on a city street. The street represents the organization; the houses represent the teams. Each team member lives in a house on the street, and every

Figure 2. Traditional development processes see a high ROI early, but it quickly tails off.

VALUE

TIMEHigh ROI at the earlystages of planning...

But ROI diminishesquickly over time

Figure 3. Compared to Figure 2, Agile development ROI remains high throughout the process, resulting in more efficient production.

Short term planningROI is maximized...

VALUE

TIME

Page 27: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-7 1 12/8/11 3:10 PM

Page 28: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

22 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Agile PlanningCOVER STORY

house has a front door. There are additional openings on the house, just like a physical house—windows, back door, garage and so on.

The front door represents the only way a team can receive new work. In Agile terms, the front door is the product backlog. When new work is created, it’s placed on the product backlog and prioritized with all other known work. This helps protect the team from a few common distractions:

■ New requirements can’t be thrown at the team mid-iteration. If something new pops up that requires the team’s attention, add it to the next sprint. If that’s too long to wait, you’re probably building good evidence to shorten your iteration length. The team should not be distracted from its commitment by new requirements.

■ Second, the team is protected from wasting time on poorly groomed or incomplete stories. Every story (requirement) the team works on must be prioritized and groomed on the product backlog. There should be no exceptions to this rule. An incom-plete or poorly groomed story almost always results in waste.

■ Finally, using the front door helps build trust between the team and leadership.

There’s nothing worse to the team than conflicting priorities, and when new work and new priorities start to appear through side doors, the teams starts to lose trust in their relationship with leadership.

Pay Down Your DebtBecoming Agile requires a commitment to getting out of debt. Not financial debt, obviously, but bug debt. It seems the software industry has fallen into a bad habit in which carrying weeks—if not months—of debt has become an acceptable practice. If you’ve followed the global economy over the past decade, you understand clearly the negative effects of carrying large amounts of debt. One of my col-leagues here at Microsoft, Mario Rodriquez, coined a phrase during our own Agile transformation that has stuck with me: “quality for agility.” Said differently, you can’t be Agile until you’ve got quality under control. Simplified even more, it’s imperative that your teams and products aren’t dragging a mountain of bug debt behind them.

The traditional project management triangle we all know and love recognizes three constraints that apply to all projects: time, cost and scope. Shifting one impacts the other. Problems arise, however, when you introduce a fourth constraint: quality. It’s very difficult to deliver value to customers when your features are littered with bugs. Quality should never be adjusted to meet time (schedule), cost (budget) or scope. Pay down the debt and fix the bugs. Your customers will thank you, and you’ll be in a better position to move on to the next thing in your backlog.

Fine-Tune and AdjustFinally, becoming Agile requires a desire by the team to improve over time. Agile teams use retrospective meetings to achieve this goal. Retrospectives aren’t new to the software industry; they’ve existed as an improvement mechanism for years. A team holds a meeting at the end of a project or milestone to discuss successes and failures, then looks for ways to create more success and less failure in future projects or milestones. It’s a fairly simple concept.

Agile teams in particular have embraced retrospectives as a way to drive continuous improvement into the team and the process. As stated in one of the 12 principles behind the Agile Manifesto, “At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.” Let’s examine this phrase in a bit more detail.

The first key statement in the principle is about regularity of reflection. The principle states up front that a team will reflect on being more effective at regular intervals. If the team “looks back” at random times in the product cycle, or only at the end of a long release, the value of any learning from the retrospective is dimin-ished. I’ve participated in numerous retrospectives at the end of long release cycles that achieved nothing more than the creation of a long list of items that everyone wishes had been done differently (you might have these lists hanging in your offices, too). The problem with this type of reflection is that the scope is so large and so broad that very little of the learning is actionable. In contrast, regular time for reflection helps to establish an environment of natural, continuous improvement.

Scrum prescribes that teams perform retrospectives at the end of every sprint. The idea is to instill in the team that “becoming more effective” is a natural part of the team’s behavior. Whether the sprint is one or four weeks long, the team reflects at the end of the sprint on how it can become more effective.

The second statement in the principle is a clear action item: the team will tune and adjust. It doesn’t say the team will start over, and it doesn’t say the team will experiment or radically change its approach. These two words (tune and adjust) have particular significance because they imply a precise set of actions.

If you have a music background, you know tuning an instrument takes a well-trained ear. It’s a precise action. You tune with precise movements and careful actions to ensure that the instrument pro-duces the required pitches. To this end, a retrospective should produce a set of precise changes for the team. A retrospective should not result in drastic action that fundamentally changes how the team operates. Too much change, or too big a change, will only disrupt the team and get in the way of producing value for the customer.

Finally, and perhaps most important, the last few words in the principle state that the team will tune and adjust its behavior. It says nothing of the behavior of other teams; it says nothing of the behavior of the organization as a whole; and it says nothing of the behavior of anyone outside the team. This is a statement of personal responsibility. The team changes its own behavior. Be careful to avoid identifying all the external problems to your team. It’s easy to blame poor execution on factors outside the control of the team. There is benefit to understanding those factors, but a common trap many teams fall into is blaming all their difficulties on those around them. Be sure to keep the retrospective focused on those things that are within the team’s control.

It’s clear that Agile methodologies and practices are no longer just buzzwords in the software industry. They’ve entered the mainstream and are helping teams realize the goal of producing more value for their customers. As you embark on your own Agile journey, remem-ber that all this “Agile stuff ” is very easy to say (or write about), but much more difficult to follow through on. That’s not to say it can’t be done; it can and is being done by software teams around the world. Start small, fine-tune and adjust as you go, and reflect regularly to ensure that you’ve got an environment built for success. VSM

Aaron Bjork is a principal program manager at Microsoft working on Agile experiences and tooling within Team Foundation Server (TFS). Prior to joining TFS in 2008, Bjork worked as a software engineer and development lead in Visual Studio. He is passionate about Application Lifecycle Management solutions and has a strong desire to see teams improve their software engineering practices. Follow Bjork on his blog at blogs.msdn.com/aaronbjork. 

Page 29: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

The Altova MissionKit includes intelligent tools for

creating, mapping, and publishing XBRL:

Experience how the Altova MissionKit®, the integrated

suite of XML, database, and data integration software,

delivers all the tool you need to work with XBRL –

without breaking your budget.

Ease into XBRL

compliance with

the complete set of

tools from Altova®

Download a 30 day free trial!

Try before you buy with a free, fully functional,

30-day trial from www.altova.com.

XMLSpy® – the leading XML editor with XBRL support

XBRL and XBRL Dimensions validation

Graphical XBRL taxonomy creation and editing

MapForce® – any-to-any, graphical data mapping

& conversion tool

Drag & drop generation of XBRL filing reports

Mapping to all major databases for in-depth analysis

Java, C#, C++ code generation, plus COM & Java APIs

StyleVision® – stylesheet design & report publishing tool

Publication of XBRL financial reports in HTML,

PDF, Word – simultaneously

Intelligent table wizard for easily presenting renderings

of XBRL data

Chart wizard for advanced XBRL presentation

f

Scan to learn

more about

Altova MissionKit

XBRL tools.

New in Version 2012:

Untitled-3 1 2/29/12 1:46 PM

Page 30: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

BIG CODE IN THEBIG APPLE

YOUR MAP TO THE .NET DEVELOPMENT PLATFORM

Intense Take-Home Training for Developers, Soft ware Architects and Designers

SUPPORTED BYPLATINUM SPONSOR

Untitled-4 2 2/29/12 2:19 PM

Page 31: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Brooklyn, NYMay 14-17NY Marriott at the Brooklyn Bridge

vslive.com/newyork

Register Before April 11 and Save $200!Use Promo Code APRAD

Bright Lights, Big City!Visual Studio Live! is thrilled to be back in New York! Join developers, software architects and designers in Brooklyn for 4 days of unbiased and cutting-edge education on the Microsoft Platform.

Scan this code to register and learn more about what Visual Studio Live! New York has to offer.

PRODUCED BY MEDIA SPONSOR

“ Excellent talks and very knowledgeable speakers. Cutting-edge information was presented and old concepts were reinforced. Great conference!”

Chris Dundon, Visual Studio Programmer, ISI Telemanagement Solutions

“ As a one-man development team, using blogs and coding sites only help so much. Being able to get real-life training and talk to people who work in the industry are important. VSLive has off ered a good opportunity to do just that, with a good range of technology areas and interests.”

Kevin Dietrich, Owner/Developer, Kdietrich LLC

Untitled-4 3 2/29/12 2:20 PM

Page 32: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Track: Cloud ComputingSession: Building Scalable Apps in Windows AzureYou will learn:

Patterns for making cloud applications scalable Patterns for making cloud based applications fault tolerant Cost-based design

Track: Cross Platform MobileSession: W16 ASP.NET MVC for Mobile DevicesYou will learn:

How to create an MVC3 application capable of targeting multiple device types How MVC4 enables multi-platform targeting How to leverage Razor layouts and views for various display types

Track: Data Management Session: T-SQL Enhancements in SQL Server 2012You will learn:

New T-SQL features in SQL Server 2012 The 22 new T-SQL functions, including 8 new analytic windowing functions OVER, THROW, OFFSET, metadata discovery, and contained databases

Track: HTML5Session: Upgrade Your Website to HTML5You will learn:

How to upgrade your current website with HTML5 How to use advanced HTML5 APIs which gracefully degrade How to enhance your website with the latest HTML5 goodies

Track: Silverlight / WPFSession: Building Extensible XAML Client AppsYou will learn:

How to leverage MEF, MVVM, and Prism to build extensible applications How to compose parent-child relationships in views so that you can plug in new user interface elements without the parent being coupled to the child views How to add whole new sets of functionality by plugging them in with Prism modules and regions

Track: Visual Studio 2010+ / .NET4+Session: What's New in the .NET 4.5 BCLYou will learn:

An understanding of the new APIs available to .NET developers What's been changed in 4.5 that may affect current code How to use this knowledge to move effectively into the next version of .NET

Track: WebSession: Fast, Faster ... Async ASP.NETYou will learn:

Load Testing ASP.NET Applications Asynchronous operations in ASP.NET WebForms Asynchronous operations in ASP.NET MVC How to use the new async/await in Web Applications

Track: Windows 8 / WinRTSession: Lap Around the Windows RuntimeYou will learn:

An overview of the Windows Runtime in Windows 8 How to use the Windows Runtime from .NET, HTML + JS, and C++ Comparisons to existing frameworks and discussion of how to port existing code

Track: Windows Phone 7Session: Building Windows Phone Applications Using the Fast Lane: Using RIA Services on Azure as Your BackendYou will learn:

How you can use RIA services as the service layer beyond the Silverlight client How you can secure your service and push it to the cloud How easy it is to build your RIA service in Azure and hence scale with the success of your phone app

Check Out What You’ll Learn at Visual Studio Live! New York:

Register at vslive.com/newyorkUse Promo Code APRAD

Untitled-4 4 2/29/12 2:20 PM

Page 33: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VISUAL STUDIO LIVE! NEW YORK AGENDA AT-A-GLANCE

Visual Studio Live! Pre-Conference Workshops: Monday, May 14, 2012 (Separate entry fee required)

WK1 Workshop: Creating Today’s User Experiences - An Entry Point for Developers

Billy Hollis

WK2 Workshop: SQL Server for Developers Andrew Brust & Leonard Lobel

WK3 Workshop: Full Application Lifecycle with TFS and CSLA .NET

Rockford Lhotka & Brian Randell

Visual Studio Live! Day 1: Tuesday, May 15, 2012Keynote Microsoft To Be Announced

T1 A Lap Around WPF 4.5 Pete Brown T2 Microsoft To Be Announced T3 HTML5/jQuery On-Ramp Rich Dudley T4 Microsoft To Be Announced

T5 WPF Validation - Techniques & Styles Miguel Castro

T6 Get Started with XAML Development on Windows 8 Pete Brown

T7 Upgrade Your Website to HTML5 Rajesh Lal

T8 The LINQ Programming Model Marcel de Vries

Lunch

T9 What's New and Cool in Silverlight 5 Pete Brown

T10 Building Windows 8 Applications with HTML5 and jQuery Rich Dudley

T11 HTML5 Marcel de Vries T12 Microsoft To Be Announced

T13 In nite Whitespace: Implementing Viewport Navigation

in XAML Billy Hollis

T14 Lap Around the Windows Runtime Rockford Lhotka T15 Microsoft To Be Announced T16 Microsoft To Be Announced

T17 Building Extensible XAML Client Apps Brian Noyes

T18 A look at Windows 8 Metro Apps and WinRT Internals Vishwas Lele T19 Microsoft To Be Announced T20 Developing Apps for Nokia

Windows Phone Rajesh Lal

Exhibitor Reception

Visual Studio Live! After Dark

Visual Studio Live! Day 2: Wednesday, May 16, 2012

Keynote: The Developer of the Future Gabriel Torok, CEO PreEmptive Solutions and Justin Marks, Senior Program Manager for Microsoft's Team Foundation Server

W1 Get Connected with Kinect Brian Peek

W2 Build Portable XAML Client App Logic and Resources

Brian Noyes

W3 Windows Azure Platform Overview

Vishwas Lele

W4 Building Windows Phone Applications Using the Fast Lane:

Using RIA services on Azure As Your Backend Marcel de Vries

W5 Securing and Personalizing Silverlight 5 Client Apps Brian Noyes

W6 Building Metro Style Apps: Getting the UX Right Brian Randell

W7 Building Scalable Apps in Windows Azure Vishwas Lele

W8 Visual Studio for Mobile Apps on iOS, Android and WP7 Miguel de Icaza

Birds-of-a-Feather Lunch

W9 Learn to Behave - Extend Your XAML with Behaviors Brian Noyes

W10 ASP.NET and Visual Studio vNext Robert Boedigheimer

W11 Windows Azure VM Role Eric D. Boyd

W12 Advanced XNA Games for Windows Phone Brian Peek

W13 Build Common Business Code for Windows Forms, WPF, Silverlight,

WP7, and WinRT Rockford Lhotka

W14 MVC For WebForms Developers: Comparing and Contrasting

Miguel Castro

W15 Storage Strategies in Windows Azure

Eric D. Boyd

W16 ASP.NET MVC for Mobile Devices Rob Daigneau

W17 MVVM in Practice aka "Code Behind" - Free WPF Tiberiu Covaci

W18 Using jQuery to Replace the Ajax Control Toolkit Robert Boedigheimer

W19 SQL Azure Intro and What's New Eric D. Boyd

W20 LightSwitch Onramp Rich Dudley

Visual Studio Live! Community Night (Open to all VSL New York Attendees)

Visual Studio Live! Day 3: Thursday, May 17, 2012TH1 Extending XAML To Overcome

Pretty Much Any Limitation Miguel Castro

TH2 Advanced Debugging of ASP.NET Applications

Tiberiu Covaci

TH3 SQL Server 2012: A Demo-Heavy Developer Brie ng

Roger Doherty

TH4 What’s New in Visual Studio LightSwitch?

Rich Dudley

TH5 Azure Peter Laudati

TH6 Improving Web Site Performance and Scalability While Saving Money

Robert Boedigheimer

TH7 Introducing SQL Server Data Tools (codenamed “Juneau”)

Leonard Lobel

TH8 What's New in the .NET 4.5 BCL Jason Bock

TH9 What's New in WCF 4 Ido Flatow

TH10 Fast, Faster ... Async ASP.NET Tiberiu Covaci

TH11 T-SQL Enhancements in SQL Server 2012 Leonard Lobel

TH12 Static Analysis in .NET Jason Bock

Lunch

TH13 What's New in WCF 4.5 Ido Flatow

TH14 ASP.NET MVC, Beyond the Basics Rob Daigneau

TH15 Microsoft's Big Play for Big Data Andrew Brust

TH16 Writing Asynchronous Code Using .NET 4.5 and C# 5.0 Brian Peek

TH17 Monitoring and Troubleshooting WCF Services

Ido Flatow

TH18 Creating a Data Driven Web Site Using WebMatrix and ASP.NET Razor

Rachel Appel

TH19 How to Take WCF Data Services to the Next Level

Rob Daigneau

TH20 Going Beyond F11: Debug Better and Faster with Visual Studio

Brian Randell

Conference Wrap-Up Panel with Q&A

HTML5 Web Visual Studio 2010+/.NET 4+

Cloud Computing

Data Management

Silverlight / WPF

Windows 8 / WinRT

Windows Phone 7

Cross Platform Mobile

For the complete session schedule and full session descriptions, please check the Visual Studio Live! New York web site at vslive.com/newyork*Speakers and Sessions Subject to Change.

Untitled-4 5 2/29/12 2:20 PM

Page 34: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

28 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

ILLU

STR

ATI

ON

BY

RYA

N E

TTER

FEATURE

Released in January, version 1 of the Bing Maps Windows Presentation Foundation (WPF) Control allows you to integrate mapping functionality directly into WPF applications. The downloadable SDK (bit.ly/nuunZs), which contains the library binaries and programming reference, provides some good examples to get you up and running, but moving beyond the sample code requires a bit more effort. In this article, I’ll present additional examples that you can adapt to produce beautiful, interactive visual-izations of geographical data.

The best way to see where I’m headed is to take a look at Figure 1(p. 30). It shows a demo WPF application with a Bing Maps Map control, three Button controls and a ListBox control. After the application launched and the embedded Bing Maps map object was initialized to a view of the entire globe, I clicked on the first button labeled Center-Zoom. This programmatically centered the map to latitude 47.6421 and longitude -122.1420 (which is the location of the building where I work in Redmond, Wash.) and then zoomed the map view in to a level of 17.

Next, I double-clicked on the map in the traffic intersection near the middle of the map. Behind the scenes the application fetched the XY coordinates of the mouse click within the WPF application window, computed the XY coordinates within the map, and deter-mined the corresponding latitude and longitude of the click. Then the application placed a red marker dot on the map at the exact location of the double-click, and two blue marker dots to the right of the double-click. As each dot was added to the map, the latitude and longitude coordinates were stored with it. Then the application connected the first red dot to the two blue dots using a solid orange straight line and two dashed purple curved lines.

Next, I clicked on the button labeled Display Data. The code in the associated event handler read a tiny data source of three items

that had latitude and longitude information, and then displayed those three data items as yellow marker dots. Notice that my mouse is hovering over the top-most yellow dot (the mouse pointer wasn’t captured by my keyboard PrtScn so I pasted in a fake icon image) and the location of the dot is displayed in a ToolTip box.

In the sections that follow I’ll walk you through the code that produced the screenshot in Figure 1. I’ll also offer some advice on when to use WPF and when to use a Web-based approach. With this knowledge, you’ll be able to extend my demo program and create sophisticated visualizations using your own geographical data.

Setting up the ApplicationTo begin, launch any version of Visual Studio that contains the Microsoft .NET Framework 4 and the Windows SDK. You might need Administrator privileges, depending on your environment. If you’re currently using an older version of Visual Studio, you can download a free edition of Visual Studio 2010 Express, which contains these prerequisites. Your development machine must be able to connect to the Internet so the map control in your WPF applica-tion can access the Bing Maps servers. You also need a Bing Maps key; you can get one for free from the Bing Maps Account Center at bingmapsportal.com. Finally, you need the Bing Maps WPF Control from the Microsoft download site. A default installation will likely place the single library DLL in the C:\Program Files (x86)\Bing Maps WPF Control\V1\Libraries directory, but you can place the DLL elsewhere if you wish.

After Visual Studio launches, click File | New | Project and then select the C# WPF Application template and specify a Location (such as C:\BingMapsAndWPF) and a Name (such as Demo). Make sure you have the .NET Framework 4 library selected from the dropdown menu at the top of the New Project dialog box. After your project is created, right-click on the bolded project name in the Solution Explorer window, select Add Reference from the context menu, and then use the Browse tab to go to the Microsoft.Maps.MapControl.WPF.dll library and click OK.

Bing Maps moves beyond Silverlight and AJAX with the new native WPF Control, which enables you to build interactive tools for visualizing geographical data on the desktop. BY DR. JAMES MCCAFFREY

Map Your Apps

Page 35: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

www.DevExpress.com

DXv2 is the next generation of tools that can take your applications to a whole new level. Your users are ready—what will you build for them?

Download your free 30-day trial at www.DevExpress.com

devvelopment skkills to tap into the groowingg ddemand for stunning tablet & touuch--enabled appsacrooss all platforrms, including WinForms, WWPF annd ASP.NET. Build for todaay ass you begin to

re-imagine busineess applications for thhe Winddows 88 Metro design aesthetic. DXXvv2 delivers thegestures, themes,, andd ccontrolss to put Touch within yourr reeaach, right now.

Copyright © 1998-2011 Developer Express Inc. ALL RIGHTS RESERVED. All trademarks or registered trademarks are property of their respective owners.

Untitled-13 1 12/9/11 3:47 PM

Page 36: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

30 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

FEATURE Map Your Apps

In the file MainWindow.xaml, add the following XML namespace reference below the template-generated xmlns namespace entries:

xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=

Microsoft.Maps.MapControl.WPF"

Next, increase the size of the overall WPF Window by setting the Height attribute to 600 and the Width attribute to 1,000. Now you can insert the Bing Maps map by placing this code between the <Grid> and </Grid> tags:

<m:Map x:Name="myMap" CredentialsProvider="YourKeyGoesHere" Mode="Aerial"

Margin="300,0,0,0"/>

The x:Name attribute can be any legal identifier, but “myMap” is a reasonable choice. Notice that I set a Margin of “300,0,0,0” to provide 300 pixels of non-map control space on the left edge of the main WPF window. I changed the default background color of my Grid container by adding a Background=“Wheat” attribute. At this point you should test your application by hitting the F5 key to build and launch the app; a lot can go wrong and it’s always better to find errors sooner rather than later.

To finish setting up the application, drag three Button controls from the Toolbox window onto the WPF design surface. Change their Content properties to Center-Zoom, Display Data and Clear Map. Drag a ListBox control onto the design surface and resize it so that it’s large enough to display messages.

Changing the Map PropertiesYou can dynamically change several Bing Maps WPF map control properties, including the Center Location, ZoomLevel and View Mode. In the design view of MainWindow.xaml, double-click on the button1 control to automatically generate the control’s click handler and switch your view to the code view of the MainWin-dow.xal.cs file. First, modify the MainWindow constructor:

public MainWindow()

{

InitializeComponent();

myMap.MouseDoubleClick += map_MouseDoubleClick;

listBox1.Items.Add("Bing Maps control initialized");

listBox1.Items.Add("");

}

If you refer back to Figure 1, you’ll see that the program can capture double-click events, so you must add a custom event handler. At this point Visual Studio will complain that method map_MouseDoubleClick doesn’t exist, so go ahead and add it:

private void map_MouseDoubleClick(object sender, MouseButtonEventArgs e)

{

// TODO

}

A key concept when working with the Bing Maps WPF control is the Location class. In order to access it in your program, add the following code to the list of using statements in file MainWindow.xaml.cs:

using Microsoft.Maps.MapControl.WPF;

The essential thing to remember about a Location object is that it has a Latitude property and a Longitude property, in that order. Latitude values range between -90.0 and +90.0 and correspond to Y values (up-down). Longitude values range between -180.0 and +180.0 and correspond to X values (left-right). Location objects also have an Altitude property (which you can ignore).

Next, add the following code to the button1 click handler:private void button1_Click(object sender, RoutedEventArgs e)

{

listBox1.Items.Add("Center-Zoom button clicked");

listBox1.Items.Add("Centering map to 47.6421, -122.1420");

listBox1.Items.Add("Setting zoom level to 17.0");

listBox1.Items.Add("");

myMap.Center = new Location(47.6421, -122.1420);

myMap.ZoomLevel = 17.0;

}

Remember that myMap is the x:Name of the Map control. Setting the Center and ZoomLevel properties should be self-explanatory. Other useful properties are the Mode, so you can switch between AerialMode and RoadMode, and Heading, so you can adjust the map orientation. At this point you can test your app to verify the button1 control event handler works as expected.

Placing Marker DotsThe Bing Maps WPF Control documentation shows you how to place pushpin controls onto a map. You can use pushpins to repre-

sent geographical data points and, often, that’s a good choice. However, there are many situa-tions where you’d just like a sim ple dot. Listing 1 (p. 32) pres-ents code to place a colored marker dot on a Map control.

The helper method accepts a Location that indicates where to place the center of a marker dot, and a Color for the dot. The method begins by creating a blank Ellipse object. One of the neat things about combining Bing Maps and WPF is that you have access to a wide range of shapes such as the Ellipse class. Here the dot radius is hardcoded to 12 pixels; you might want to parameterize that value. The method uses a ToolTip object to store the location of the dot so Figure 1. A new control/library allows developers to add Bing Maps functionality to a WPF application.

Page 37: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-10 1 1/31/12 4:25 PM

Page 38: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

32 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

FEATURE Map Your Apps

that when a user hovers the mouse over the dot, the location infor-mation will automatically pop up. Nice and easy! Next, the PlaceDot method uses the LocationToViewportPoint method to convert a Location to a Point. The resulting Point is used to create a second Point that’s moved to the left and up. The idea is that Ellipse objects are displayed using the upper-left corner of the object’s bounding box, so by offsetting by a factor of the radius, the Ellipse will be centered at the location parameter. The ViewportPointToLocation method creates the modified location. To actually place the dot on the map, the static MapLayer.SetPosition method and the instance Children.Add method are used. The paradigm to place a shape on a map seemed a bit odd to me at first, but I quickly got used to it.

Drawing Straight LinesIn some scenarios you might want to draw a straight line between two locations on a map. One way to do it is shown in the following code:

private void DrawLine(Location start, Location finish)

{

LocationCollectioncoll = new LocationCollection();

coll.Add(start);

coll.Add(finish);

MapPolyline line = new MapPolyline();

line.Stroke = new SolidColorBrush(Colors.Orange);

line.StrokeThickness = 3.0;

line.Locations = coll;

myMap.Children.Add(line);

}

The DrawLine helper method accepts start Location and finish Location parameters. When you’re dealing with Map controls, it’s gen-erally best to work with Location objects rather than Point objects (as you normally would in WPF applications). The Bing Maps WPF Control library provides you with a MapPolyline class that works with Location objects. You can think of MapPolyline as a cousin to the WPF Polyline class that works with Point objects. DrawLine has hardcoded values for color and thickness; you might want to parameterize them.

Drawing Curved LinesDrawing a curved line between two locations on a map is quite difficult. The approach I prefer is to use Bezier curves. Listing 2 pres-ents a fairly sophisticated method that will draw a curve between two Location objects on a map.

A complete explanation of Bezier curves could fill an entire article, but there are only a few things you need to know to modify my code to meet your own needs. For the StrokeDashArray property values I use { 5, 2 } to draw a dashed line where the dashes are 5 pixels long and the space between dashes is 2 pixels long. Much of the code in method DrawCurve uses the start Location and the finish Location to compute a so-called control point that determines the curvature of the Bezier curve. If you experiment with variables xScale and yScale you’ll affect the curvature—larger values of xScale produce more left-right bend and smaller values produce less left-right bend. The yScale variable controls up-down bend.

The method constructs a curve as a set of straight lines. The number of line segments is specified by variable numSegments, which is hard-coded to 31. More segments produce a smoother curve at the expense of performance. Notice that the for-loop in Listing 2 works with type double. In order to keep my code simple I don’t perform robust computations, and because of rounding errors, some values of numSegments (for example, 20) will cause the Bezier curve to stop slightly before the specified finish Location. If

Listing 1. Code that places a marker dot on a map.

private void PlaceDot(Location location, Color color){ Ellipse dot = new Ellipse(); dot.Fill = new SolidColorBrush(color); double radius = 12.0; dot.Width = radius * 2; dot.Height = radius * 2; ToolTip tt = new ToolTip(); tt.Content = "Location = " + location; dot.ToolTip = tt; Point p0 = myMap.LocationToViewportPoint(location); Point p1 = new Point(p0.X - radius, p0.Y - radius); Location loc = myMap.ViewportPointToLocation(p1); MapLayer.SetPosition(dot, loc); myMap.Children.Add(dot);}

Listing 2. Drawing an arc using a Bezier curve.

private void DrawCurve(Location start, Location finish){ MapPolyline curve = new MapPolyline(); curve.Stroke = new SolidColorBrush(Colors.Magenta); curve.StrokeThickness = 3.0; curve.StrokeDashArray = new DoubleCollection(new double[] { 5, 2 }); curve.Opacity = 1.0;

LocationCollection coll = new LocationCollection();

// Compute control point Point p1 = myMap.LocationToViewportPoint(start); Point p2 = myMap.LocationToViewportPoint(finish);

double boundingBoxHalfWidth = (p2.X - p1.X) / 2.0; double boundingBoxHalfHeight = (p1.Y - p2.Y) / 2.0;

double centerX = (p1.X + p2.X) / 2.0; double centerY = (p1.Y + p2.Y) / 2.0;

double xScale = 1.0; double yScale = 1.0;

double controlX = centerX - (xScale * boundingBoxHalfWidth); double controlY = centerY - (yScale * boundingBoxHalfHeight);

Point controlPt = new Point(controlX, controlY); Location controlLoc = myMap.ViewportPointToLocation(controlPt);

// Compute intermediate Locations using the control point int numSegments = 31; doublet Delta = 1.0 / numSegments; for (double t = 0.0; t <= 1.0; t += tDelta) // Danger! { // x coordinate (longitudes) double a = (1.0 - t) * (1.0 - t) * start.Longitude; double b = 2.0 * (1.0 - t) * t * controlLoc.Longitude; double c = t * t * finish.Longitude; double Blon = a + b + c;

// y coordinate (latitudes) a = (1.0 - t) * (1.0 - t) * start.Latitude; b = 2.0 * (1.0 - t) * t * controlLoc.Latitude; c = t * t * finish.Latitude; double Blat = a + b + c;

coll.Add(new Location(Blat, Blon)); }

curve.Locations = coll; myMap.Children.Add(curve);}

Page 39: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Create accurate PDF documents in a fraction of the time neededwith other tools

WHQL tested for all Windows 32 and 64-bit platforms

Produce fully compliant PDF/A documents

Standard PDF features included with a number of unique features

Interface with any .NET or ActiveX programming language

High-Performance PDF Printer Driver

Edit, process and print PDF 1.7 documents programmatically

Fast and lightweight 32 and 64-bit managed code assemblies for Windows, WPF and Web applications

Support for dynamic objects such as edit-fields and sticky-notes

Save image files directly to PDF, with optional OCR

Multiple image compression formats such as PNG, JBIG2 and TIFF

USA and CanadaToll Free: 1 866 926 9864Support: (514) 868 9227

Info: [email protected]

EuropeSales: (+33) 1 30 61 07 97Support: (+33) 1 30 61 07 98

Customizations: [email protected]

All trademarks are property of their respective owners. © 1999-2010 AMYUNI Technologies. All rights reserved.

www.amyuni.com

OCR Module availablewith royalty-free licensing!

PDF Integration into Silverlight Applications

More Development Tools Available at:

v4.5!

v4.5!

New!

PDF Editor for .NET, now Webform Enabled

Server-side PDF component based on the robust Amyuni PDF Creator ActiveX or .NET components

Client-side C# Silverlight 3 control provided with source-code

Optimization of PDF documents prior to converting them into XAML

Conversion of PDF edit-boxes into Silverlight TextBox objects

Support for other document formats such as TIFF and XPS

The new OCR Module from Amyunienables developers to:

Convert non-searchable PDF files intosearchable PDFs

Create searchable PDF documents outof various image formats such as multi-page TIFF, JPEG or PNG while applyingtext recognition

Compress image based PDF documentsusing high compression JBIG2 or morestandard CCITT, JPEG and PNGcompression formats

The Amyuni OCR module is based on theTesseract Library with the Amyuni PDFtechnology being used to process andcreate the PDF documents.

Learn more at www.amyuni.com

Untitled-6 1 4/11/11 12:56 PM

Page 40: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

34 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

FEATURE Map Your Apps

you use my code in a production setting and modify the value of numSegments, be sure to check that you get correct behavior.

Handling Double-Click EventsWith helper methods to place marker dots, draw straight lines and draw curved lines in hand, you can handle double-click events as shown in Figure 1. You already set up the skeleton of the double-click event handler but did not supply the implementation. The code is presented in Listing 3.

Setting e.Handled to true disables the default map double-click behavior, which is to zoom in. Because this is a custom event handler, the GetPosition method returns the XY screen coordinates of the double-click relative to the main WPF window, not the Map control. Therefore you have to subtract 300 pixels from the X coordinate to take into account the left margin of 300 pixels. After placing a red marker dot at the exact location of the double-click, a blue marker dot is placed 150 pixels to the right and 100 pixels down from the red dot. Then a second blue dot is placed to the right, but higher than the red dot. The DrawLine method places a solid orange line between the red dot and the first blue dot. The DrawCurve method is used to draw two dashed curves between the red dot and the second blue dot. Notice that by changing the start-finish order of the Location param-eters to DrawCurve, you can produce a curve that bends up or down.

Displaying Multiple Data PointsIn Visual Studio, switch back to the design view of the Main-Window.xaml file and double-click on the Button control labeled Display Data. This will generate the skeleton for the button’s click event handler and bring you to that code in the file MainWin-dow.xaml.cs. Edit the code to get:

private void button2_Click(object sender, RoutedEventArgs e)

{

listBox1.Items.Add("Display Data button clicked");

listBox1.Items.Add("Placing yellow dots from data source");

double[][] data = new double[3][];

data[0] = new double[] { 111, 47.643, -122.140 };

data[1] = new double[] { 222, 47.642, -122.140 };

data[2] = new double[] { 333, 47.641, -122.140 };

for (int i = 0; i <data.Length; ++i)

PlaceDot(new Location(data[i][1], data[i][2]), Colors.Yellow);

}

This code is intended to illustrate how you can display geographical data from a data source. Here, the data source is a set of three dummy arrays where the first value is an ID of some sort, and the second and third values are latitude and longitude. In a realistic scenario your data source would likely be a text file or a SQL table. Notice that, for clarity, I don’t perform any error-checking such as verifying that latitude values are between -90.0 and +90.0 and so on.

To finish up the demo program shown running in Figure 1, double-click on the Button control labeled Clear Map and edit the event handler code to produce the following:

private void button3_Click(object sender, RoutedEventArgs e)

{

listBox1.Items.Add("Clear Map button clicked");

int ct = myMap.Children.Count;

myMap.Children.Clear();

listBox1.Items.Clear();

listBox1.Items.Add("Clearing " + ct + " items from map");

listBox1.Items.Add("");

}

This code should be pretty clear to you. The Children.Clear method will zap away all the UI elements that you’ve added to your map. The Children collection can also be accessed by index if you want to clear only some UI elements.

Working with Large Data SetsThe two main alternatives to Bing Maps with WPF are Bing Maps AJAX in a Web application and Bing Maps Silverlight. I’ve used—and like—all three approaches, but I really like Bing Maps with WPF. It gives you the combined power of Bing Maps and the WPF programming model, with the convenience of the C# language.

I’ve found Bing Maps with WPF especially useful when I have to deal with very large data sets. In those scenarios, Bing Maps with WPF was much faster than Web-based alternatives, and it allowed me to effectively handle SQL databases with millions of records, and to display thousands of data points in real time. Bing Maps with WPF is likely to be less manageable than a Web-based approach if you want your visualization program to be accessible to users throughout your enterprise. All in all, Bing Maps with WPF is a powerful new tool for visualizing geographical data. VSM

Dr. James McCaffrey works for Volt Information Sciences Inc., where he manages technical training for software engineers working at the Microsoft Redmond, Wash., campus. He’s worked on several Microsoft products, including Internet Explorer and MSN Search. Dr. McCaffrey is the author of “.NET Test Automation Recipes” (Apress, 2006), and can be reached at [email protected].

Listing 3. Handling the double-click event.

private void map_MouseDoubleClick(object sender, MouseButtonEventArgs e){ e.Handled = true; listBox1.Items.Add("Map double-click occurred");

Point p0 = e.GetPosition(this); Point p1 = new Point(p0.X - 300, p0.Y); Location loc1 = myMap.ViewportPointToLocation(p1);

listBox1.Items.Add("Click window XY = " + p0.X + "," + p0.Y); listBox1.Items.Add("Click map XY = " + p1.X + "," + p1.Y); listBox1.Items.Add("Click lat-lon = " + loc1.Latitude.ToString("F4") + "," + loc1.Longitude.ToString("F4")); listBox1.Items.Add("");

PlaceDot(loc1, Colors.Red); listBox1.Items.Add("Placing red dot at mouse-click");

Point p2 = new Point(p1.X + 150, p1.Y + 100); Location loc2 = myMap.ViewportPointToLocation(p2); PlaceDot(loc2, Colors.Cyan); listBox1.Items.Add("Placing cyan second dot to right and lower");

Point p3 = new Point(p1.X + 150, p1.Y - 100); Location loc3 = myMap.ViewportPointToLocation(p3); PlaceDot(loc3, Colors.Cyan); listBox1.Items.Add("Placing cyan third dot to right and higher"); listBox1.Items.Add("");

DrawLine(loc1, loc2); listBox1.Items.Add("Drawing solid line from first to second dot"); listBox1.Items.Add("");

DrawCurve(loc1, loc3); DrawCurve(loc3, loc1); listBox1.Items.Add("Drawing dashed curve from first to third dot"); listBox1.Items.Add("Drawing dashed curve from third to first dot"); listBox1.Items.Add("");}

Page 41: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Visit vslive.com/redmond or scan the QR code to register and for more event details.

Visual Studio Live! Redmond is where developers, software architects and designers will connect for ve days of unbiased and cutting-edge education on the Microsoft platform – all on the Microsoft Campus! Join us for sessions on Visual Studio 2010+ / .NET 4.0+, HTML5, Cloud Computing, Windows 8, Silverlight / WPF, Windows Phone 7 and more!

PRODUCED BY MEDIA SPONSORSUPPORTED BY

Redmond, WA | August 6-10 | Microsoft Headquarters | vslive.com/redmond

CODE ON CAMPUS

YOUR MAP TO THE .NET DEVELOPMENT PLATFORM

Register Before

June 1 and Save

$400!Use Promo Code

REDAPR

Microsoft Campus, Redmond, WA

Untitled-3 1 2/29/12 1:47 PM

Page 42: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

36 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

</Language Lab>YO U R CO D E S O U R C E

IN THIS SECTION: Practical .NET · 36 // C# Corner · 42 // Mobile Corner · 45 /////////////

Integrating Validation with the Entity FrameworkValidation should begin as close to your database as possible: in your Entity Framework entities. Here’s how you can integrate validation code into both the entities the Entity Framework generates and the ones you write.BY PETER VOGEL

You tell your client that you have an application with a one-second response time but, possibly, data-integrity issues. Or you tell your client that the application has a five-second response time with rock-solid data integrity. Which application gets turned on and which gets shelved? I’d bet on the one

that has the longer response time but guarantees its data integrity. It’s a rule: In business applications, the data matters. And the natural place to put your data integrity rules is as close to your data as possible—in your Entity Framework entity classes.

In this column, I’ll show you how to create Entity Framework entities that protect themselves from bad data, in both Model First and Code First approaches. You’ll see how to use Entity Framework-specific validation frameworks and leverage the other Microsoft .NET

Framework validation tools (including how to use Data Annotations in environments where they aren’t directly supported). You’ll also get a look at some new technology that Microsoft is starting to roll out to support declarative validation in the Entity Framework.

Validation with Model First Entity FrameworkYou might think that using Model First (or database-first) development will inherently restrict what you can do with your business entities, because the Entity Framework is responsible for generating your entity class code. That’s not the case in the Entity Framework 4—you can use any of the.NET Framework validation frameworks by taking advantage of some Entity Framework-specific features.

When the Entity Framework generates code for your entities, your entities’ properties include a call to a method named OnPropertyNameChanging that you can use to integrate your custom validation code. Listing 1 shows an example of the code that the Entity Framework generates for the City property on the Northwind database Customer class; you can see the call to OnCityChanging made before the property’s backing field is set.

The OnCityChanging method is implemented as a partial method further down in the Entity Framework-generated code:

partial void OnCityChanging(global::System.String value);

If you create a partial class for Customer (in the same namespace as your Entity Framework model), you can replace this partial method with your own implementation. The Changing method is passed the value that will be used to set the property’s backing field so you can check that value to determine its validity. The Changing methods don’t provide any mechanism for reporting errors, unfortunately, so the simplest way to handle the error is to throw an exception. Listing 2 (p. 38) shows what happens when the City name is too long.

{ PRACTICAL .NET }

En

tity

Fra

mew

ork

WHY YOU SHOULD (AND SHOULDN’T) BE ADDING VALIDATION TO THE ENTITY FRAMEWORKJust because you’ve applied validation rules at the UI, don’t think you don’t need them in your Entity Framework entities. In any application, putting validation code in your entities protects you against implementation errors and omissions by the developers building the UI. Plus, if you intend to reuse your entity classes among applications (a good idea), incorporating validation rules into your data entities ensures consistency in applying those rules across the enterprise.

But you do need to have reasonable expectations about what validation you can do in your Entity Framework entities. Validation rules that apply to individual properties (is the date in the future?) or crosschecking among the values on an entity (is the hire date after the employee’s birth date?) can reasonably be implemented in your Entity Framework entities. Validation rules that require checking among multiple objects (is the hire date for all of the employees in this group the same?) or require fetching data already in the database (does this customer exist?) are best enforced in the business-tier objects. — P.V.

Listing 1. Entity Framework-generated code for the City property.

public global::System.String City{ get { return _City; } set { OnCityChanging(value); ReportPropertyChanging("City"); _City = StructuralObject.SetValidValue(value, true); ReportPropertyChanged("City"); OnCityChanged(); }}

Page 43: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

ement1); areaSeries Add(seriesElement2); areaSeries Add(seriesElement3); // Add series to the plot area plotArea Series Add(areaSeries); //page Elements Add( new LayoutGrid() ); // Add the page elements to the page AddEAement1); areaSerieies.AAdd(se(s rriesElement2t2); a) reaSeries.AdA d(seriesElement3); // Add series to the plot area plotArea.Series.Add(areaSeries); //page.Elemenem ts.Add( ddd( new ne LaLayyoutGrid() ); // A/ dd the page elements to the page AddEA

s, 240, 0); AddEAN1AN 3SupSup5(pa5(p ge.Elemeentnts, 480, 0); AdddUPCVersionA(page.Elemene ts, 0, 135); AddUPCVersionASup2(page.Elements, 240, 135); AdddUPCddUPCd CVerssionAionAo Sup5((page.Elemennts, t 480, 135); AddEAN8(page.Elements, 0,

.Elements, 480, 2270);; AddddUUPCVersionE(papage.Elementts, 0, 405); AddUPCVersionESuE p2(page.Elements, 240, 405); AddUPCVersionESup5(pageage.Ele.Elelemmments, 4s, 48800, 4405); // AAdd the page toe t the document document.Pages.Add(pa

CaptionAndRectanga lee(elemeements, “EAN/JA/JAN 13 Bar Codde”, x, y, 204, 99); BarCode barCode = new Ean13(“123456789012”, x, y + 21); barCode.ode.X +=X +X +=X + ((2004 -4 - baarCoode.GettSymbolWidth()h ) / 2; elements.Add(barCode); } private vovo

dRectangle(elemente s,, “EANEAN/JAN 13 Bar Car Code, 2 digit supplement”, x, y, 204, 99); BarCode barCode = new Ean13Sup2(“12 234556789678 0121212”, 2”, x, yy + 2+ 211); 1); barCoode.XX += (204 - barCode.GetSymbolWidth()) / 2; elements.Add((barC

ts, float x, float yy) { A{ AddCaCaptionAndRectanangle(elements, “EAN/JAN 13 Bar Code, 5 5 digit supplement”, x, y, 204, 99); BarCoa C de bbarCoarCCode =de = newn EEanEan113SuS pp5(“12234556789001212345”, x, y + 21); barCode.X += (204 - barCodee.Get

ddUPCVersionA(GrouGroup elemenem ts, float x, floatfloa y) { AddCaptionAndRectangle(elemente s, “UPC Version A Bar Code”, x, y, 2y, 204, 99);9)99);9) Bar BarB rBa CodeC barbarCCode = neew UpcVepcVersionAA(“12345678901”, x, y + 21); barCode.X += (204 - baarCo

ddUPCVersionASSup2(up2 Grououpp elements,, floatoa xx, float y) { AddCaptionAndRectangle(ele( ments, “UPC Version E Bar Code, 2 digit git supsuppsuppup lement”nt”, x,x, x y, 204, 999); BaarCodde barCCode = new UpcVersionASup2(“123456787 90112”, xx, yx, y +

s.Add(barCode); } } pprivate te vooid AddUPCVPCVersiers onASup5(Group elements, float x, floato y) { AddCaptionAndRectangle(eleementmmentm s, “s, “UPC UPC VerVersion EE Bar Code, 5 diggit suupplemment”, x, y, 204, 99); BarCode barCode = n ew UpcVeeersio

ode.GetSymbolWWidth(dth )) / 2; 2 elements.AddAdd(bar(ba Code); } privatee voi v d AddEANEAN8(Group p elements, float x, float y) { AddCddCaptitionAnonAn dRecReccecttaangle(elemments, “EANN/JANN 8 BBar Codde”, x, y, 204, 99); BarCode barCode == newn Ean8(“123434

g(); fileDialog.Title =le = “Op “Open Fen File Dialogg”; filfi eDialog.Filter = “AdAdobe PDFF fileses (*.pdf)f)|*.pdf|All Files (*.*)|*.*”; if (fileDieDialog.log.ShSSShowwDDiallog()og == DialoggResult.OK) { pdfVieweewer.OppenFile(fileDialog.FileName, “”); } SaveSav FileF Diallog saavaveFa

File Dialog”; s saveFveFileDialoal gg.Filter = “AdoAdobee PDF files (*.pdf)f)|*.pdf|All Files (**.*)|*.*”; if (saveFileDialog.ShowDowDialoialoa g()=g()==DiaDi=DiaDi logResulsule t .OOK) {{ pdfVfVieweewerr.SaveAs(saveFileDiaDialog.FileNamee); ); } } if (p( dfVidfV ewewer.PPagP e

WithDialog(); } e else se { MessMe aageBox.SShow(w “PPlease open a fifile tto printt”); } OOpenFileF Dialog fileDiD aloglog = n = nnnew Oew Oe pepenpenFileDDialog(); fifile Dialog.Tiitle = “Open File Dialoog”; filleDialog.InitialDirecectoory = @”c:\”:\ ; fi fileDleDialoglo .Filterter = “= “All F

) == DialogResules t.Ot.OK) { Dy D nnamicPDFFViewewerrClass test = new Dew DynammicPDFVieewerCr lass(); PDFDFPrinPrintter prinprinninterter er = = test.OpenFpe ileForPorPrinnter (file(fileDiaalog.FileName); pprinnter.PrintQuieQuiet();() } bytbybytby ee[] contcontentst =

pServices; GCHGC andandle gcchh = GCHandled .AllAl occ(contents, GCHHandndleTypType.Pinnedd); IntIntPtr contcontentsentsIntPtr ===gcch.ch.h.AAAddrOfPinnednn Objeect()ct ;ppdf Viewer.O.OpenBpepe ufffefeuff r(cor(r(cor( ntentsIntPtrt ,

kmark Page Elemelement:”, x,x, y); y); p pageEleementen s.AAdd(new Bookkmarrk(“( BBookB marked Text”x , x , x + 5,+ 5, y + 20,0 parpareenenttOe utline)); pageElg emennts.Ats.Add (new Label(“This tes texxt is bookmaokmaokmarkedrked ”, .”, xx + 5, y + 20, 2

ageElements, fls, float a x, float at y) {{ // Addsdss a circltt to the pageEllemeents AddCaptioonnAndRAndRectaectangle(paggpagpaggeEleeEl mentmen s, “Circle PPaage Elemment:ent:”, x, y); pageElgeElements.As.Add(ndddd(ndd ew CCircle(x (x + 112.5f2 ,

shLarge)); } pprivavate te void AddFAd orormattedteede TextArrea(Group pp ageeEg lemennts, float x,x, floafloat yt y)t { /{ / AdA dsds ads a for forfofoo matttedd text area too tthepageEeElle ments strring formattm edHtedHtml = “<p“<p><<i>Dynamic</i><b>PDb>P F</bb>&tm>&tmmtm; Generaeraaator oro v6.0 foror .NE

matting suppoort for or text thath t aappears s in the ddocument. Yt. Youuu havve “ + “comcompletetple e cooontrorol ovovovovver 8r 8e parar agraph pph properties: ssppacing befoeforee, spacingg after, firfirst liine “ + “indentantation, left indentatitation, righr t ininndentdentdentntatiotionn, a, aaliignment, alalllowi

<font face=’Tim’Times’es’>fontt fac f e, </fonnt>t>><f> ont ppoino tSizSize=’6’>fffont “ + “““size, </</fonfonntn ><fo<f nt ct coolorloolorlol =’FF000000 ’>>coloor, </font>><b>b<b> old, </b</b><<i>italic aannd </i><<u>uunderline</u>>; “ + “and 2 line proopertrties: leaeadingng, anndd leleeeaadinaad g type. Text

extArea = neew FoFormatrm tedTdTextAArea(fororrmmattedHHtmtml, x + 5, y +++ 20,, 21555, 60, F, FontontFamilmmi y.HeHeelvvelveteticaica, 9, ffalse)e); // SSets the the indent properoperty foformatteatt ddTextAreeaa.Styyle.PParagrapph.Inndent = 18; AddCCapttionAndRectRectanglgle(pae(papa(paapae geEgeElements, ts, “F

ageElemem ntts, “Fo“FormmattedTdTextAtArea OOvvverflow flow TText:”, x + 27999, y); pagpaggeEleeEleementmen ss.AdAdAdd(fod(foodd ormrrmatrmatmatatttedTextAtArea)); // CCreate e an oa verflow formatteded t text art a ea for tr the ooverflflow textt FoormattedTextArea ova oveerflowForFormattma edTeTTeextArxtArxtArtxttArea =ea =e formatte

a(x + 284, y + 20)20); pap geEElemenements.Adddd(o(overflverflowwFowFoow rmatarm tedTeextAe rrea); } privprivate ate vvooidov AddAddA dA Imagmagmagmage(Group up paggeElememeents, float x, float y) { // A/ dds an in magee tto thhe paageElemmenents AddCaptionAndRedRectangle((pagpageElemmmentsenntstsnts, “Imagegee Pag

es/DPDFLoogo.pn.png”), x ++ 1112.55f, y ++ 550f,50f, 0.20.244f);4f // Image is sizeed annnd centeenteredd in tn tthe rrrrectataec nglengle imam ge.SetBoB unds(215, 60); image.VAlign = VAlign.Cenenterr; imaage.Alignn = Align.Center; paggeEeElements.Ad.Addd(imaggee)g ;; } } privvate ate vvoidv A

pageElemennts AdAddCapdC tiononAndRectaannglengle(pag(paggeeEleeElements, “LLabell & PPagePageNumbeerinerine gLgLabg bel PPage ElememE entts:”, x, y); string labelText = “Labels can be rottaated”; strring numbermbe Text = “PageNummbeeringLabelsels contcontaiain ppage nummbeerib ngTT

xt, x + 5, y + 12+ 12, 22220, 80, F0 ontt.TimemessRomRoman,an, 12, TextAlign..Cennter);; l lababel.AngAngglle = 8; 8; 8; PagePageeNNumNumbN erinri gLagLabel pageNumLabel = new PageNumberb ingLabelab (nnumbberText, x +x + 5, y + 55, 220, 880, FFont.TimesResRoman, 1212, TextAltAligignign.n Ce

mem nts.Add(labeabel); l); } private voe id AAddLdLinne(Gne(Groupp pageElemennts, flflfloat x, floaoat y) {{{) { / // Addss a l a lla inne to the phe pageEag lements AddCaptionAndRectangle(p( ageElemee nnts, ““Line Paage Element:”, x, y); ppageeElemennts.As.Add(neew Lw ine(x +x + + x 5, y5 +

w Liw ne(xx + 2+ 220, y + 20, x + + 5, yy + 8 + 0,0, 30, 3, Rg, RgbCoolor.Green)); } prprivivaate vvoid Ad AddLiinknk(Groupup p pagpap eElementments, float x, float y) { // Adds a link to the ppageElemeem ntts Foont font == Foont.TimesRoman;; st string text = “TThisT iss s a lia nk tnk tk o o Dynaamic

mentm :”, x, y); Label label == newne LaLabbbel(textt, x + 5, y + 20, 2155,5, 800, fonnnnt, 1t, 2, R2, RgbbColor.or.BBluelu ); l; abel.UndUndererline = true; Link link = new Link(x + 5, y + 20, font.on GGetTeextWidthh(texxt, 12), 12 - font.GGetDDescendder(1r(12), neeww ee UrlUrlAlAction(“n(“hhttp

EleE mennts.Add(li( nk);; } p } privavate ve voidd AAddPath(ath Grroup pageElemmentts, floatoatfl x, floatt y) y) {{ // AddAd s a s pathh to the pageElements ceTe.DynamicPDF.PageElementen s.Pathh path = nneww ceTe.DynamicPDPDF.PF.PageElemenmennnts.Ps.Paaath(h(x + x + 55, y, y + + 2+ 20, R

PathP s.AAdd(new LineeSubPatPa h(xx ++ 2215, y + 4+ 0))); path.Suh.S bPatths.Ahs.AAAdddd((new CurvurveeToSubPatPa h(x h(x + 1008, y + 80, x + 160, y + 80)); path.SubPaths.Add(neww CCurvveSuubPath(x + 55, y + 40, x + 65, 6 y + y + 80, x + 5, y5, yy + + 60))); AddAddCCaCaptC ionAAnd

AAdd(ppaaath); } privatee void AAddRReccttaangle(GrG oupp pageeEElemennnts, flflflofloatat x, float yat y)) oorderee dLisdL t = t = ordderedList.GetOverFlowList(x + 5, y + 20); AddCaptionAnAndRRectaanggle(pagge.Elements, “Orderr ed Led List Pagegee Ele EleEl mentttn OOOve Ovev rflowrfl :”, x, y, 2

88; /8; // C/ Create an unoordereedd list UUnnornorderede List uunorderere edListt =t =stt neeew UUnonorderrderedLLied st(xx + 55, yy + 20+ 20, 400, 90, Font.Helvetica, 10); unorderedList.Items.Add(Add(“Fruits””); uunorderedere List.Items.Add(“d “VegeVegeg tablees””); UnU U ordeeer redSreedSd ubbList unord

tt((); (); unorderedSubList.Items.ms.Add(“dd((““ Citrus”); unordorderededederedSuSubLiist.Iteeemss.AdAddd(“ Nonn-Citrt us”)s” ; AdAddCCaptionAndRectangle(page.Elemennts, “Unordered Lisst Pagee Elemmente :”, x, yx, y, 225, 110); Unonn rddereedSubLisbLisst ununnu ordederedSredSdredSdd ubLiub st2 = uno

rederer SubbbList2.Items.Add((“PoPotato”); unorderedSSubLiiubLisstt2.Itemmms.Addddd(“BBeans”); Unorno derederedSubdSubLisst subUnorderedSubList = unorderede SubLS ist.Items[0]].SuubLists.AAddddUnorderrde edSubList(); subs bUnorUnorderedSubdSSubbLListLLL .Iteteeems.Ams.Am Addd(“Lime”); s

LList subbbUnorderedSSubList2st = unorderedSubLbLS iist.ist.Itemss[1].SuubLissts.AAddUnordeeredSuedS bLisbL t();t() suubUnorderedSubList2.Items.Add(“Mana go”); subUnorrdereedSSubList2.It2 temms.AAdd(“Banana”); ); UnUnordderedSSuSubdS ListLissLis sububUnorn derede dSubList

tt(()(); subUUnordereddSSubList3.Items.Add(“SweSweew t PoPotato””); Unoorderred dSSubList subbUnorUno dereer dSubdSubListList44 = unorrderedSubList2.It2 ems[1].S].SubLists.AddUnoordeereddSubbList(s ); subUnubU orderedSubLibubListst4.s Iteems.AdAdAdA d(“Sd(“S“Strining BeeBeean”)an” ; subUnoU rde

AAdddd(“Kiddney Beanean”); x += 279; paga e.Elemeements.Addd(ud nnordereedLisst); uunorderedListLis == unordnorderedere List.GetOvere FlowList(x + 5, y + 20);) AddA CaptionAndRecctanngle(ppageag .Elemeents, “UnorUnorderederer d Lid st PPage e ElemElemmmeent ee Oveverve flow:flow:flo ”, x, y, 225

ooiddd AdddTedTextFxtField(Group pageElemenme ts, , flofloat x,, flooat y)) { TexxtField txtt = new TextFixtF eeld(“txt“t fnafname”, x + 20, y + 40, 120, 20); txt.Defaulu tValue = “This iis s a Scrrollabble Te extFFieldd”; txt.BordederColrColC or =o RgbRgbCColoor.Br.Br.Br.Black; txtxttxtxt.BacackgrokgroundCun o

(td(d xt); TTexTextField txt1 = new TextFiField(ld “txxtf1naf1 me”,me” x + 175, yy + 440, 120, 20); txtt1.DefDe aultu Valualue = “TextField”; txt1.Password = true; ttxt1.MaxLength = = 99; txtt1.BoordderColor = RgbCollor.BBor.Black; txt1.B1.Backgckgrounou dCololor =oror =or = RgbRgbR ColoColor Alr.Al

eree ies(); pieSeries.DataLabel == da;a;da plop tAreAreaa.Sea riesrie .Add(pieSSeriess); ppieSeries.Elemelementss.Add(Add(27,27, “Website A”); pieSeries.Elements.Addd (19, “Website BB”)); pieSerrieses.Elementmen s.Add(21d(21, “WWWebsiseb te Cee ”); ”); ); pieSpieSp eries.ElElemenmeements[0ts[0s[0s[0].Co].C lor or == a

esess.Elements[2].Color = aututograog diendientt3;”RgbCRgbColoor.AliceeBlue; txt2.Too.ToolTip = “Multilinnee”; pagepageElElements.Add(txt2); AddCaptionAndRectangle(pageElememennts, “TexxtFiField Formorm PagPage Ele Elemenemenemennnt:”,:”, x, y, 5, 5y 0404, 85);5) } p} rivaate ve ve ooid oid AddCdCombomb

CombCCC ooBox(“cmmbnambna e”, e”, x + x + 51, 51, y + y + 40,40, 150,15 220); cb.BBorderColoor = RgbColor.BlacBlack; ccb.Bab.BackckgroundColor = RgbColor.AliceBlue; cb.Font = Font.Helveelveticaa; cbb.FonFo tSizzSizze = e 12; cb.Icb.Itemsstemsstems.AddA (“Item 1eme ”); ); cb.cb.Itemstems.AddAdAd.Add(“It(“It(“It( Item 2em ”); ”); cbcb

didd table””)”); cb.Itemms[s[“[“Editaabble”].Selectcteded = true; c; cb.Editable = truue; ccb.ToolTip == “Edi“Ed tablab e CoC mmbo Box”; pageElements.Add(cb); ComboBox cb1 = new Cew omboombbb Box(B x(“cmbmb1nammee”, x + 303,3303, y + y + 40, 150, 20 20); c); cb1.BBb1 ordedederderrColor == R

= F== ont.HHHelveticca;a; ca; cbb1.FontSnt ize = 122; cb1.Itemss.AAdd(“IItem 1”); ccb1.Ittems.Add(“It“Item 2em ”); ”) cb1.cb1.ItItems.Add(“Item 3”); cb1.Items.Add(“Item 4”); cb1.Itemss.AAddd(“Noon-Ediditabtablee”);); c cb1.Items[““[“Non-Non-EditEditableable”].S”].Seelected = tr= ue; ue; cb1.1 Edita

ntnntts.Ads dd(cb(cb(cb1); Converter.CoC nvert(“http://www.gogoogogle.ccom”, “Outputt.pdf”);Convertve er.Cer.Conveonvert(GetDocPath(“DocumentA.rtf”), “Output.pdf”);System.Diaiagnooosticscss.ProoPP cesssess.SStart(“Outptput.pput.pdf”)df”); As; AsyncCncConverterrt aCooCoonnvenverteer = new A

errr((aC(aCo( nverrter_Converted); aConverter.ConversionErroor += nnew ConnversionErrorEvventHtHandler(aConverter_ConversionError); aConverter.Convert(@”C:\tC:\ emmp\mpmm DDocummenmenttAA.rtf”, @”C:\tememmmp\Oup\OutputtputA.pdA.pdf”);f”);) aConverv rter.ter.Coonvert(@”C

verve t(@”C:\temp\DocumentC.rtf”, @”C:\temp\OutputCC.pdf”)); aCoonveerter.Convert(e “hhttp://p://www.yahoo.com”, @”C:\Temp\yahoo.pdf”); ConversionOptionsoni ooptop ionnsnsns = = new CConversiosionOptnOpttionsions(720(720, 72, 720, 72, ttrue); ceeTe.DTe. yynamicPDF

tempte \\ooutput.pdf”, options); ceTe.DynamicPDF.Conveersion.Connvertter.Convert(“C:\\\teemp\\Document2.docx”, “C:\\temp\\output.pdf”, options); string sg ammmpamplmpam eHtmH ml = l “<hth ml><ml><bodybody><p>><p>pp TThis is a very ssimplm e HTML ML strring includ

<tab<t le bborder=\”1\”>1 <tr><td>100</td><td>200</td>”” + “<ttd>3300<</td></tr><tr><<td>>400</td><td>500</td><td>600</t< d></tr></table><></bod/body><y><//</</hhthtmhtmlhtmhtm >”;Conveveo rsion.Con.CoCC nvernverter.ter.CConvvertHtmlString(saamplempleHtmll, “C“C:\\\temp\emp\\Sam\Sam

ererNamee”, Path.Combo ine(GetPath(), “LetterPortrait.pdff”)); prrintJoob.DDocumentNamee = “LettLetter Pe ortrait”; if (printJob.Pob. rinter.Color) prinprinprinprinpri tJobtJob P.PrintOpntOn tions.Cos. lor o = trtrue; ue; if (if (prinprinri tJobtJo .Printer.ColC late) printJob.Pb.P.PPrrintr OOptiOptip ons.ons.onons CoCoollollate at = tr= tr= uurr

innt

;ppd

t:: ,

Untitled-1 1 9/8/11 12:41 PM

Page 44: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

38 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

En

tity

Fra

mew

ork

</Language Lab>

{ PRACTICAL .NET }

Avoiding ExceptionsIf you don’t want to throw an exception, the .NET Framework provides a standard interface (IValidatableObject) that supports returning collections of errors and a class (ValidationResult) for reporting errors. To use them, the first step (after adding the interface to your class) is to declare a collection to hold your errors:

List<ValidationResult> Errors = new List<ValidationResult>();

In your Changing event, instead of throwing an exception, create a ValidationResult object passing the error message you want to display and the properties with which the message is associated. After creating the error, add it to your errors collection:

partial void OnCityChanging(string value)

{

ValidationResult vr = new ValidationResult(

"City name must be less than 25 characters ",

new string[] {"City"})

Errors.Add(vr);

}

The IValidatableObject interface adds a method to your class that you should use to return your collection of ValidationResult objects:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)

{

return Errors;

}

In your application, you’ll need to check the Validate method for errors and then do something with the results (some of the .NET Framework data-binding environments will do that automatically

if you expose your class to them). The code in Listing 3 checks for errors. If any are present, it adds them to some listing control; if no errors are found, the code saves the changes to the model.

Using the Validate method like this provides an excellent place to put cross-property checks, because the Validate method will typically be called after all the entity’s properties have been set. However, unlike throwing an exception in the Changing method, using the IValidatableObject interface allows the property to be set—which might cause an Exception to be thrown. And if the developer using your entity doesn’t check the Validate method, the property settings can make their way into the database.

Any of the .NET Framework validation interfaces—discussed in my March Practical .NET column, “Exploiting the .NET Validation Frameworks”—can be applied by adding them to a partial class.

Integrating Data AnnotationsYou can also use Data Annotations on your entity class, even when the Entity Framework is generating your code. You need to add the MetadataType attribute to your partial class and point that attribute at a “buddy class” that applies DataAnnotations to your entity’s properties. This example ties the Customer partial class to a class called CustomerWithMDT, which, in turn, applies a Data Annotation to the City property:

[System.ComponentModel.DataAnnotations.

MetadataType(typeof(CustomerWithMDT))]

public partial class Customer

{ }

public class CustomerWithMDT

{

[System.ComponentModel.DataAnnotations.StringLength(25,

ErrorMessage="City name must be 25 characters or less")]

public object City { get; set; }

}

In a data-binding environment that supports Data Annotations (for example, ASP.NET MVC or Silverlight) that’s all you have to do to get your messages to the UI. In an environment that doesn’t support Data Annotations (such as ASP.NET), you’ll need to add some code to your property’s Changing event to process the Data Annotations on your buddy class.

I use a method I’ve called InvokeDataAnnotations, passing the name of the property being checked and the value passed into the Changing method:

partial void OnCityChanging(string value)

{

InvokeDataAnnotations("City", value);

}

In my InvokeDataAnnotations method, shown in Listing 4 (p. 39), I first retrieve the attributes on my entity class. This gives me access to the MetadataType class that points to my buddy class.

Using the reference to my buddy class, I retrieve the PropertyInfo object for the property being changed. And, once I have the property’s PropertyInfo object, I can retrieve all the Data Annotations applied to the property:

PropertyInfo prop = mdt.MetadataClassType.GetProperty(Name);

var atts = prop.GetCustomAttributes(typeof(ValidationAttribute), true);

For each of the Data Annotations on the property, I can call its Validate method, passing the name of the property and the value the property is being set to. If the value isn’t valid, the Validate method will raise an exception using the error messages specified on the Data Annotation:

Listing 2. Throwing an exception for a Changing method.

namespace northwindModel{ public partial class Customer { partial void OnCityChanging(string value) { if (value.Length > 25) { throw new Exception( "City name must be less than 26 characters long"); } } } }

Listing 3. Checking the Validate method for errors.

Customer cust;...retrieve Customer object...cust.City = newCity;cust.Address = newAddress;...more property settings...

System.ComponentModel.DataAnnotations.IValidatableObject ivo = cust;if (ivo.Validate(null).Count() > 0){ foreach (System.ComponentModel.DataAnnotations.ValidationResult vr in ivo.Validate(null)) { this.ErrorList.Items.Add(vr.ErrorMessage); }}else{ ne.SaveChanges();}

Page 45: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 39

{ PRACTICAL .NET }

foreach (ValidationAttribute att in atts)

{

att.Validate(value, Name);

}

With the IValidatableObject interface, you should be adding to the Errors collection instead of raising an exception. To support that, use the annotation’s IsValid method, which returns False if the value passed is bad. Then use the annotation’s ErrorMessage to create a ValidationResult object to add to the Errors collection:

foreach (ValidationAttribute att in atts)

{

if (!att.IsValid(value))

{

Errors.Add(new ValidationResult("errormessage", new string[] { "City" }));

}

}

Validation with Code First Entity FrameworkIf you’re using the Entity Framework 4.1 and Code First development, you can not only take advantage of all the Entity Framework features, but also have all the resulting error messages rolled into one package for delivery to the presentation layer. In fact, in the Code First mode, the Entity Framework provides two mechanisms for integrating validation code into your entity.

One mechanism provides an equivalent of the Validate method on each object. You implement this mechanism by overriding the ValidateEntity method when you define your DbContext class:

public class NorthwindModel: System.Data.Entity.DbContext

{

protected override

System.Data.Entity.Validation.DbEntityValidationResult ValidateEntity(

System.Data.Entity.Infrastructure.DbEntityEntry entityEntry,

System.Collections.Generic.IDictionary<Object, Object> items)

This method is called once for each entity being changed or added when the application calls the SaveChanges method on your DbContext object. The method is passed two parameters: the entity to be validated (entityEntry) and a dictionary containing additional information you might find useful in the validation method (I’ll ignore that parameter for this column).

Because you can embed validation code in your entity’s properties, the code you put in the ValidateEntity method should be validation code you can’t include in your entity properties (for instance, code that does cross-property or cross-entity checks). Alternatively, if you’re reusing your entity classes among several applications but creating your DbContext object on an application-by-application basis, you can use the ValidateEntity method for validation code that varies from one application to another.

For this example, I’m going to assume the second scenario: that in some applications, it’s all right for the unit price in a sales order detail to be negative. However, in the application that this model supports, the unit price can’t be negative, so the validation code that prevents that belongs in the DbContext object for this application rather than embedded in the sales order detail class.

The first thing to do is create a collection to hold any errors that the entity generates. Because the ValidateEntity method returns a DbEntityValidationResult object, the following code creates a collection (called Errors) to hold those DbEntityValidationResults:

Entity.Validation.DbEntityValidationResult Errors =

new Entity.Validation.DbEntityValidationResult(

entityEntry,

new list<Entity.Validation.DbValidationError>());

A DbEntityValidationResult object has a key and a value: The key is the item being validated (the entityEntry object passed to the method) and the value is a List holding all the errors for that item (each error is a DbValidationError object). When creating the DbEntityValidationResult, pass the entityEntry object the method received and a List that can hold any DbValidationError objects you might create as you validate the entity.

Because this method will be called for any entity being added or changed, the next step is to check the entity type (if you wanted to tailor your validation code depending on whether the object is being added or modified, you could also check the entityEntry’s State property). Once you determine the object’s type, cast the entityEntry to the right type to simplify the validation code:

if (typeof(entityEntry.Entity) is OrderDetail)

{

OrderDetail od;

od = (OrderDetail) entityEntry.Entity;

You’re now ready to start validating this OrderDetail object. If you find a problem, add a DbValidationError to the Errors object. A DbValidationError object accepts two parameters when it’s created: the name of the property that the error is associated with and the error message itself. This code creates the error and adds it to the list of errors in the DbEntityValidationResult object:

Entity.Validation.DbValidationError dve;

if (od.UnitPrice < 0)

{

dve = new Entity.Validation.DbValidationError(

"UnitPrice",

"Unit Price must be greater than zero.");

Errors.ValidationErrors.Add(dve);

}

A DbValidationError object accepts two parameters when it’s created: the name of the property that the error is associated with and the error message itself.

Listing 4. Retrieving attributes for the entity class.

using System.ComponentModel.DataAnnotations;using System.Reflection;

private void InvokeDataAnnotations(string Name, object value)

{

object mdtObj = this.GetType().GetCustomAttributes( typeof(MetadataTypeAttribute), true).FirstOrDefault(); if (mdtObj != null)

{

MetadataTypeAttribute mdt = (MetadataTypeAttribute) mdtObj;

En

tity

Fra

mew

ork

Page 46: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

40 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

En

tity

Fra

mew

ork

</Language Lab>

{ PRACTICAL .NET }

At the end of the code, you can determine if any problems were found by checking the length of the List of errors in DbValidation-Result. If any errors are found, return them; if no errors are found, call the base method and return its value:

if (Errors.ValidationErrors.Count > 0)

{

return Errors;

}

else

{

return base.ValidateEntity(entityEntry, items);

}

The second mechanism means that you’re not restricted to putting all your code in the ValidateEntity method. In the DbContext object, you can attach validation rules to properties while the Entity Framework is assembling your model’s components. The first step here is to override the DbContext’s OnModelCreating method and, using the Entity method on the modelBuilder parameter passed to the method, retrieve the entity to which you want to add validation.

Having retrieved the entity, you can call its Property method, passing a lambda expression that specifies the property you want to extend with additional validation rules. You can use any of the several extension methods that the Entity Framework provides to specify validation rules. This example, for instance, specifies that the City property have a maximum length of 25 characters:

protected override void OnModelCreating(DbModelBuilder modelBuilder)

{

this.modelBuilder.Entity<Customer>().

Property(c => c.City).HasMaxLength(25);

}

Accessing Validation ResultsIn your application’s code, you can access the results of all the validation you’ve added through the DbContext in a variety of ways. First, if any errors are raised during the SaveChanges

process, you can catch the resulting DbEntityValidationException and access its collection of EntityValidationErrors. There will be one entry in that collection for each entity that has any errors. Each entry, in turn, may have multiple errors, each listing the property name and message. In Listing 5, I just add each error message (with its property name) to some listing control.

The errors returned here will not only be the errors from your ValidateEntity method, but also any errors generated by any other validation mechanisms you’ve included in your entity classes (for example, any errors generated by DataAnnotations).

You can turn off the validation done during the SaveChanges process by setting the ValidateOnSaveEnabled property on the DbContext Configuration property:

dbc.Configuration.ValidateOnSaveEnabled = false;

Turning off error checking when SaveChanges is called isn’t completely crazy, because you can also check for errors on all the changed objects before committing your changes. Just call the DbContext GetValidationErrors method. The method returns the same collection of ValidationResult objects that you can get through the DbEntityValidationException object:

List<System.ComponentModel.DataAnnotations.ValidationResult> vrs =

new List<System.ComponentModel.DataAnnotations.ValidationResult>();

vrs = dbc.GetValidationErrors();

foreach(var vr in vrs)

{

// ...display errors...

You can even validate a single entity, though you must first convert it to a DbEntityEntry. The DbContext object’s Entry method will accept an instance of one of your entity classes and return the corresponding DbEntityEntry object. You can then call the DbEntity-Entry GetValidationResult method to check for errors on that entity. That’s what this code does before going on to display those results:

var od = (from ordl in dbc.OrderDetails

select ordl).First();

// ...update od...

Entity.Infrastructure.DbEntityEntry ent;

ent = dbc.Entry(od);

Entity.Validation.DbEntityValidationResult ers;

ers = ent.GetValidationResult;

foreach (var er in ers.ValidationErrors)

{

// ...display errors...

Looking Ahead to PEMThis section is an instance of the Impractical .NET column: Talking about technology that isn’t here yet. However, I’m sufficiently excited about Portable Extensibility Metadata (PEM) and what it can do to improve data integrity in Entity Framework models that I’m already starting to play with it—not something I usually do. The goal of this section isn’t to drag you through the details of PEM, but to describe what it will do for you and what it’s like to use.

PEM adds declarative validation to your Entity Framework model when you’re using the Entity Framework in Model First

Listing 5. Adding methods to listing controls.

NorthwindModel dbc = new NorthwindModel(...connection string...); // ...perform updates...try{ dbc.SaveChanges();}catch (Entity.Validation.DbEntityValidationException ex){ foreach (var vr in ex.EntityValidationErrors) { foreach (var er in vr.ValidationErrors) { this.ErrorDisplay.Items.Add(String.Format( "{0}: {1}", er.PropertyName, er.ErrorMessage)); } }}

PEM lets you declaratively add validation rules to your Entity Framework at two levels: for individual properties on an entity or at the entity level for multiple properties.

Page 47: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 41

{ PRACTICAL .NET }

mode—for example, whenever you use the Entity Framework designer. The technology is still plainly in a beta phase (though it’s well into its second version). Currently, the technology is available as a Visual Studio add-in and only generates code for C#.

To get PEM, go to the Tools menu, select Extension Manager, pick the Online Gallery and search for Portable Metadata. Install the package, let Visual Studio reboot, and you’re ready to use PEM with any new or existing Entity Framework model. Provided you don’t apply PEM to an Entity Framework model, it doesn’t impact the normal Entity Framework process, so you can leave PEM in place or back it out after you’ve finished experimenting with it. Using PEM on an existing Entity Framework model does have one side effect, but it’s fixable or something you can live with (more on that later).

PEM lets you declaratively add validation rules to your Entity Framework at two levels: for individual properties on an entity or at the entity level for multiple properties.

To add validation rules at the property level, select a property in one of the model’s entities in your Entity Framework designer. In the Properties window for the selected property, you’ll find a new entry called Validations. Using this property, you can add multiple validation rules to a property, specifying the type of the validation rule (for instance, range), parameters for the rules (such as 0 to 100, -10 to 10) and the error message to display (see Figure 1).

You can also specify the level of enforcement: Must/Must Not and Should/Should Not. The “Not” options make it easier to design rules where you want to exclude some values rather than specify the acceptable values. The “Should” options, presumably, allow the application to override the rule or present its violation as a warning rather than a prohibition. The obvious limitation in the current version of this feature is that it supports only two types of rules: Range and Required.

To add validation rules at the entity level, select an entity (rather than one of its properties) and then, from the entity’s Properties window, use its Validations property to add a validation rule. Here, you can choose from nine different rules; each rule can involve several different properties/columns. For instance, choosing the Equality rule and selecting two or more fields specifies that if any

one of the properties has a value, then all of the properties must be given values.

While the Validations property makes the necessary changes to your Entity Framework model, it doesn’t automatically generate the code that will enforce these rules. To have that code generated, you must right-click on the designer and select Add Code Generation Item. In the resulting Add New Item dialog, select PEM Validation Code Generator to add a new code-generator template file, with the .tt extension, to your project. The PEM template generates the same code as the standard Entity Framework template, but also throws in validation code based on the entries you made in the Validations properties. After adding the PEM Validation Code Generator template to your project, you’ll find a code file nested beneath it with your generated code.

In order to prevent your Entity Framework code from being generated twice (once by the standard Entity Framework code-generator

file and once by the PEM file), the PEM add-in sets the Code Genera-tion Strategy property on your Entity Framework .edmx file to None, preventing any code from being generated directly from your model. If you’ve used PEM and want to get back to your original Entity Framework code, you’ll want to delete the PEM .tt file and reset your Entity Framework model’s Code Generation Strategy back to Default (just click anywhere in your Entity Framework designer to display the Properties window with the Code Generation Strategy property).

On the other hand, you could just use the code generated by the PEM template in your applications going forward—it’s exactly the same code that the normal Entity Framework process generates.

Though it’s not related to validation, PEM also adds a Display property to the Properties window for both entities and entity properties. At the property level, the Display property lets you specify a prompt/watermark for input fields, group fields under a name, flag whether the property is editable or sortable, and provide a description of the property. At the entity level, the Display property lets you control which of the entity’s properties should be displayed and set their default order.

As I said, this section is an instance of the Impractical .NET column—this is new technology and, among other limitations, doesn’t always work as expected. (I found that, on some occasions, the PEM template didn’t generate any validation code, but I couldn’t figure out why.)

There’s also a paucity of documentation—really, just one comprehensive blog post. And, as yet, the code that’s generated doesn’t integrate into the existing .NET validation frameworks. However, none of these problems are particularly hard to resolve. My guess? You’re not using PEM now—but you will be.

Even ignoring PEM, the variety of options available for the Entity Framework makes it easy to put your validation rules where they belong: As close to your data as possible. VSM

Peter Vogel is a principal in PH&V Information Services, specializing in ASP.NET development with expertise in SOA, XML, database and UI design. His most recent book, “rtfm*” (PH&V Information Services, 2008), is on writing effective user manuals, and his blog on technical writing can be found at rtfmphvis.blogspot.com.

Figure 1. Portable Extensibility Metadata allows you to set validation rules declaratively on your Entity Framework entities through dialogs opened from the Properties window.

En

tity

Fra

mew

ork

Page 48: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

42 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

WP

F C

omm

and

s

</Language Lab>

Using Aspect-Oriented Programming to Initialize and Connect WPF CommandsSee how a simple interceptor can help reduce the amount of coding needed to initialize your Windows Presentation Foundation ICommand properties.BY PATRICK STEELE

As I was recently modifying an existing Windows Presentation Foundation (WPF) project, I grew tired of the repetitive code I was writing to initialize my ICommand objects. I decided that with a little bit of method interception, I could simplify some of this work.

The Magical Notify Property WeaverAs with most programmers, I don’t like writing repetitive code. While I’m working on a project, there’s usually a point where I find code that could be consolidated into some base class functionality or some other reusable paradigm.

The WPF INotifyPropertyChanged interface is one of those times where code can get extremely repetitive. I used to employ a base class, which had some utility methods that encapsulated property handling and the INotifyPropertyChanged interface. Then I found Simon Cropp’s Notify Property Weaver (bit.ly/bfQmSB).

This awesome little utility allows you to go back to using simple Microsoft .NET Framework auto-properties in your ViewModel. Cropp’s Notify Property Weaver is a post-build task that scans your assembly for classes that implement the INotifyPropertyChanged event. It then rewrites the intermediate language (IL) generated by C# auto-properties and inserts the necessary INotifyPropertyChanged implementation. My ViewModels are much simpler now, and I no longer need to rely on a base class for this functionality.

When I got tired of writing code to initialize my WPF commands, I wondered if there was something similar to Cropp’s approach that I could do—but to do it at runtime as WPF binds to my ViewModel.

The DelegateCommandI’m using the DelegateCommand that was made popular in the Microsoft Prism framework (bit.ly/ema2b). I won’t go into the details, but the DelegateCommand is an easy way to encapsulate

WPF ICommand functionality into a reusable class. If you’re using something different, this approach will still work; you’ll just need to modify some of the code.

Here’s a simple example of exposing some functionality in your ViewModel as an ICommand:

private ICommand showDateCommand;

public ICommand ShowDate

{

get { return showDateCommand ?? (

showDateCommand = new DelegateCommand(() => RunShowDate())); }

}

It’s not a lot of code, but it’s repeated a number of times through-out my code:

1. Define a variable for the ICommand.2. Create a property to expose the ICommand variable.3. If the variable isn’t initialized when the getter is called, create

a new DelegateCommand that points to the method to run when the command is executed.

The thing I don’t like about this is that I have to define both the private variable as well as the public property (along with the DelegateCommand initialization code). Thanks to the Notify Property Weaver, all of my other properties have moved back to being simple auto-properties; I wanted to move my ICommands back to being auto-properties, too. But that means I’d need to somehow “intercept” the WPF calls to my ICommand properties and instantiate the DelegateCommand automatically.

Intercepting MethodsThe open source Castle Project (bit.ly/OCb2) contains a project called “Dynamic Proxy.” This project allows you to dynamically create a proxy for any non-sealed type. This proxy sits “in between” your calling code and the class instance being called. As you would expect, this is the perfect place to add method interception.

Without going into too much detail, Dynamic Proxy creates a subclass of the type you want to proxy (hence the requirement for non-sealed types) and overrides any virtual members on that type (meaning you can’t intercept non-virtual methods).

In effect, the proxy is simply a wrapper around your class. All calls to the wrapper (for example, the proxy) are, by default, directed to the base class implementation (the class you’re wrapping). However, we can give Dynamic Proxy an interceptor that will run each time a method is executed.

Dynamic Proxy defines an IInterceptor interface with a single method: Intercept. The first thing I did was create a simple

{ C # C O R N E R }

Simon Cropp’s Notify Property Weaver is an awesome little utility that allows you to go back to using simple Microsoft .NET Framework auto-properties in your ViewModel.

Page 49: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 43

WP

F C

omm

and

s

{ C # C O R N E R }

interceptor that would only intercept calls to the getter of my ICommand properties:

public class CommandInterceptor : IInterceptor

{

public void Intercept(IInvocation invocation)

{

if (invocation.Method.ReturnType == typeof(ICommand)

&& invocation.Method.Name.StartsWith("get_"))

{

// Implementation comes next

}

invocation.Proceed();

}

}

The important thing to notice here is the call to invocation.Proceed at the bottom of the method. This tells the proxy to continue with the call to the base class that I proxied. This gives me the flexibility to conditionally execute the base class method or totally replace its functionality.

Now that I had my interception configured, I had to write the code that would create the DelegateCommand, initialize it and return it to WPF.

Creating DelegateCommand at RuntimeInitializing my DelegateCommand is trivial in straight C# code:

showDateCommand = new DelegateCommand(() => RunShowDate())

Doing this at runtime means I’d have to know the name of the method that performs the action of my command. Because the ICommand exposes an “Execute” method, I decided to form a convention that the method for any of my ICommands will be the name of the property prefixed with “Execute_”. I’m not a huge fan of underscores in my method names, but this allows me to easily see the methods that are automatically hooked up via my interceptor.

So, in the previous example, I need to create a lambda that points to the method “Execute_ShowDate” (as you recall earlier, my ICommand property is called “ShowDate”). Obviously, I’ll also have to rename the current implementation code, RunShowDate, to “Execute_ShowDate.” Because lambdas are really just syntactic sugar for delegates, I’ll be using the Delegate.CreateDelegate method. Here’s the code I’ll add to the “// implementation comes next” section:

// Strip off the "get_" prefix on the property getter

var methodName = invocation.Method.Name.Substring(4);

var commandDelegate = Delegate.CreateDelegate(typeof(Action),

invocation.InvocationTarget,

ExecutePrefix + methodName);

In this code, “ExecutePrefix” is a constant defined as “Execute_”. Now that I have this, I can create my DelegateCommand and pass this delegate (which represents the lambda) as a constructor argument:

var delegateCommand = Activator.CreateInstance(typeof(DelegateCommand),

new object[] { commandDelegate });

I need to set the return value of the intercepted method (the property getter) to the DelegateCommand I created. I don’t want

the default invocation to proceed. Because I’m now using auto-properties, the default invocation would simply return the value of the auto-generated backing field, which would be null in this case! Instead, Dynamic Proxy exposes a property on the invocation argument that allows me to set a specific return value:

invocation.ReturnValue = delegateCommand;

return;

I added the return statement so the code doesn’t fall through and hit the invocation.Proceed call.

Using the CommandInterceptorNow that my ViewModel doesn’t have to do any of the Delegate-Command creation nor maintain a backing field for my ShowDate command, I can simplify my code to:

public virtual ICommand ShowDate { get; private set; }

private void Execute_ShowDate()

{

//

}

Note that ShowDate is virtual. Dynamic Proxy can only intercept virtual methods/properties. The only other change needed is that my DataContext needs to be a proxy of my ViewModel, not the ViewModel itself. For the sample application that’s included with this article, available at VisualStudioMagazine.com/Steele0412, my original DataContext setup code was:

this.DataContext = new MainWindowVM();

Instead, I’ll need to create a proxy that uses my CommandInterceptor:var generator = new ProxyGenerator();

var vm = generator.CreateClassProxy<MainWindowVM>(new CommandInterceptor());

this.DataContext = vm;

This uses the Dynamic Proxy ProxyGenerator to create a proxied instance of my ViewModel, and sets up my Command-Interceptor to intercept all method calls.

Supporting CanExecuteReaders familiar with WPF and the DelegateCommand will note that I didn’t address the CanExecute capability. An overload of the DelegateCommand constructor accepts a Func<bool>, which can be used to indicate whether the ICommand can be executed or not. Augmenting my CommandInterceptor with this functionality is fairly easy.

However, there’s one big difference between setting up the delegate for Execute and setting up the delegate for CanExecute: the CanExecute is optional. If you recall, my original code for setting up the DelegateCommand was:

showDateCommand = new DelegateCommand(() => RunShowDate())

In this case, the ShowDate command is always available. Often in WPF, I need to enable/disable a command’s functionality based on program conditions. In those cases, I pass a delegate that will be used to determine if ShowDate is available:

showDateCommand = new DelegateCommand(() => RunShowDate(), () =>

CanExecuteShowDate())

I’m not a huge fan of underscores in my method names, but this allows me to easily see the methods that are automatically hooked up via my interceptor.

Page 50: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

44 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

</Language Lab>

{ C # C O R N E R }

I’ll go back to the code where I set up my commandDelegate and add a second call to create a canExecuteDelegate. As I did before, I’ve defined a convention that my CanExecute methods will be prefixed with “CanExecute_” (note code in bold is new code):

var commandDelegate = Delegate.CreateDelegate(typeof(Action),

invocation.InvocationTarget,

ExecutePrefix + methodName);

var canExecuteDelegate = Delegate.CreateDelegate(typeof(Func<bool>),

invocation.InvocationTarget,

CanExecutePrefix + methodName, false, false);

Note the two extra parameters at the end of the CreateDelegate call. The last one tells CreateDelegate to not throw an exception if it can’t create a delegate when the method doesn’t exist. It will just return null instead. I can use this as an indicator as to whether the ViewModel has defined an appropriate “CanExecute_” method.

Now I just need to determine which overloaded constructor of DelegateCommand to call. This one replaces the previous call to Activator.CreateInstance:

var delegateCommand = Activator.CreateInstance(typeof(Action),

canExecuteDelegate == null

? new object[] { commandDelegate }

: new object[] { commandDelegate, canExecuteDelegate });

Handling DelegateCommand<T>One last piece I had to handle was the case where the generic version of DelegateCommand was used. The DelegateCommand<T> is used in cases where the XAML defines a CommandParameter that is to be passed to the ICommand Execute and CanExecute methods.

I’ve defined a convention that the Execute methods for my ICommands will be prefixed with “Execute_”, but how do I know if I should create a DelegateCommand or DelegateCommand<T>? Easy—I can use a little reflection to see if the Execute method accepts a parameter. Once I have this information, I can create the proper, generic versions of Execute, CanExecute and the DelegateCommand.

The first thing I’ll do in my interceptor (once I’ve determined I’m intercepting a property-get on an ICommand) is use reflection to find information about the “Execute_” method defined in the ViewModel:

var mi = invocation.TargetType.GetMethod(ExecutePrefix + methodName,

BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

var parameters = mi.GetParameters();

Now, with a list of method parameters, I can tailor the creation of the DelegateCommand. Note how I use the MakeGenericType method on the generic delegate types to create a specific type of delegate (in this case, the type defined by the method’s parameter). I’ve refactored the delegate-creation code so it can support both DelegateCommand and DelegateCommand<T>. The result is seen in Listing 1.

Check out the sample code available for download for a complete sample application. You’ll see how one of the ICommands is configured to accept an instance of the ViewModel itself:

public virtual ICommand ToggleEnabled { get; private set; }

private void Execute_ToggleEnabled(MainWindowVM viewModel)

{

viewModel.ButtonEnabled = !viewModel.ButtonEnabled;

}

When the CommandInterceptor looks for “Execute_Toggle-Enabled,” it will see it has one parameter. Therefore, it will create a delegate of type Action<MainWindowVM> and a DelegateCommand<MainWindowVM>. In the sample code, you’ll also see how I have a dictionary to cache the Delegate-Commands I create in the interceptor so they only need to be created once per “get” of the ICommand.

Why Not a Base Class?Instead of using Dynamic Proxy and an interceptor, I could’ve simply created a base class for all of my ViewModels that contained similar functionality. In fact, if I used the Microsoft .NET Framework 4, I could’ve had my base ViewModel class inherit from DynamicObject and intercept method calls that way.

First, it seemed a little heavy to create a base class for all of my ViewModels just to do some auto-wiring of the ICommand objects. And because I moved off a ViewModel base class when I started using Notify Property Weaver, I really didn’t want to go back to needing a base class.

I’ve used this in a couple of WPF projects and really like the ease with which I can hook up my ICommand objects. A simple auto-property along with a couple of methods, and everything gets wired up automatically, thanks to my CommandInterceptor. VSM

Patrick Steele is a senior software consultant with SRT Solutions in Ann Arbor, Mich. A recognized expert on the Microsoft .NET Framework, he’s a Microsoft MVP award winner and a presenter at conferences and user group meetings.

GO ONLINEGo to VisualStudioMagazine.com/Steele0412 to read this article online and to download the sample code.

Listing 1. Creating the DelegateCommand.

var mi = invocation.TargetType.GetMethod(ExecutePrefix + methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);var parameters = mi.GetParameters();

Type commandType;Type canExecuteType;Type delegateCommandType;if (parameters.Length != 1){ commandType = typeof(Action); canExecuteType = typeof(Func<bool>); delegateCommandType = typeof(DelegateCommand);}else{ var parameterType = parameters[0].ParameterType; commandType = typeof(Action<>).MakeGenericType(parameterType); canExecuteType = typeof(Predicate<>).MakeGenericType(parameterType); delegateCommandType = typeof(DelegateCommand<>).MakeGenericType(parameterType);}

var commandDelegate = Delegate.CreateDelegate(commandType, invocation.InvocationTarget, ExecutePrefix + methodName);var canExecuteDelegate = Delegate.CreateDelegate(canExecuteType, invocation.InvocationTarget, CanExecutePrefix + methodName, false, false);var delegateCommand = Activator.CreateInstance(delegateCommandType, canExecuteDelegate == null ? new object[] { commandDelegate } : new object[] { commandDelegate, canExecuteDelegate });commands.Add(key, delegateCommand);invocation.ReturnValue = delegateCommand;return;

WP

F C

omm

and

s

Page 51: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

VisualStudioMagazine.com · April 2012 · VISUAL STUDIO MAGAZINE 45

</Language Lab>

Working with ListBoxes in a Windows Phone ApplicationBy overriding templates, you can modify the look and feel of the ListBox without changing the underlying behavior.BY NICK RANDOLPH

Most Windows Phone applications need to present a list of items to the user at some point. If you look through the six hubs that form part of the core Windows Phone experience, you’ll notice a number of lists, each one presented a bit differently. For example, in the People hub, there’s the “what’s new” pane, which is a

vertical list of recent activities, and the “recent” pane, which is a horizontal array of tiles representing an individual contact.

If you want to present lists within your Windows Phone application, then you’ll need to master using the ListBox control. In this article I’ll walk you through getting started with the ListBox, and then move on to some of the more advanced techniques.

Adjusting the LayoutFigure 1 (p. 46) illustrates four different ListBox applications. Figure 1 (A) illustrates a ListBox in which the list of items is hardcoded into the XAML, as shown in the following code:

<ListBox x:Name="ContactListBox" >

<sys:String>Item 1</sys:String>

<sys:String>Item 2</sys:String>

<sys:String>Item 3</sys:String>

<sys:String>Item 4</sys:String>

<sys:String>Item 30</sys:String>

</ListBox>

Each item is added to the ListBox using a default ListBoxItem, which creates a TextBlock containing the string representation of the item. In this case, each item is a string, so it isn’t far from what I want.

I’ll come back to how you handle different types of ListBox items in a minute. First, I’ll look at how to adjust the layout of the items in the ListBox. To do this, you need to modify the ItemTemplate for the ListBox. You can think of the ItemTemplate as a cookie cutter that’s used to determine the layout, or presentation, of each item in the List. Microsoft Expression Blend provides a nice design-time experience for modifying the ItemTemplate, which makes working with the ListBox control much easier.

In this case, I want to override the default layout. To do this, you go to the Objects and Timeline window in Expression Blend, right-click the ListBox and select Edit Additional Templates, then Edit Generated Items (ItemTemplate), and Create Empty. Give the new template a name, ListBoxItemTemplate, and specify where in the application the template will be defined. This will create a new DataTemplate that contains a Grid. Select the Grid, and then in the Assets window, locate the TextBlock control. Double-click on it to add a TextBlock to the Grid.

At this point, you’ll notice that the text “TextBlock” is repeated down the list. To correct the text that’s displayed within each TextBlock, you’ll need to change the Text property so that it’s data-bound to the current data context. In the case of controls within a ListBox item template, the data context is, of course, the item within the list. Your ListBox XAML should look similar to the code in Listing 1. You’ll also notice that a Style and Margin have been added to the TextBlock, as shown in Figure 1 (B).

Next, I’m going to change the contents of the ListBox so that the data is loaded dynamically at runtime, rather than hardcoded in the XAML. In this case, I’m using design-time data generated by Expression Blend, but you can use any collection or list of data loaded within your application. Each item in the list is a Contact with a properties Name and ImageUrl.

The following code illustrates the structure of the Contact class as it assigns the list of contacts to the ItemsSource property on the ListBox:

n amespaceExpression.Blend.SampleData.ContactSampleData{

public class Contact{

public string Name {get; set; }

public string ImageUrl {get; set;}

}

}

voidMainPage_Loaded(object sender, RoutedEventArgs e) {

var data = new ContactSampleData();

ContactListBox.ItemsSource = data.Contacts;

}

At this point, if you run the application, you’ll notice that all you see is a ListBox full of the type name of the Contact class, as shown in Figure 1 (C). By default the ListBox attempts to present the string representation of the item.

You can control how a Contact appears in the ListBox in different ways. If you simply want to display information about the Contact in a single TextBlock (for instance, use the ItemTemplate you currently have defined), you can either override the ToString method on the Contact class, or set the DisplayMemberPath attribute on the ListBox to the property that you want displayed.

{ MOBILE CORNER }

Listing 1. XAML for creating a ListBoxItemTemplate.

<ListBox x:Name="ContactListBox" > <ListBox.Resources> <DataTemplate x:Key="ListBoxItemTemplate"> <TextBlock Text="{Binding}" Style="{StaticResource PhoneTextLargeStyle}" Margin="12,0,12,12"/> </DataTemplate> </ListBox.Resources> <ListBox.ItemTemplate> <StaticResource ResourceKey="ListBoxItemTemplate"/> </ListBox.ItemTemplate> <sys:String>Item 1</sys:String> ....... <sys:String>Item 30</sys:String></ListBox>

Lis

tBox

Con

trol

Page 52: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

46 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

Lis

tBox

Con

trol

</Language Lab>

{ MOBILE CORNER }

For example, setting the attribute to “Name” will display the Name of each Contact.

In most cases, you’ll want more control over how each Contact is presented. For example, you might want to display both the image of the Contact (using the ImageUrl property) and the name of the Contact. The following XAML replaces the ListBoxItemTemplate used earlier with an ItemTemplate that’s made up of a Grid containing an Image, in the first column, and a TextBlock, in the second column:

<DataTemplate x:Key="ListBoxItemTemplate">

<Grid Margin="12,0,0,12">

<Grid.ColumnDefinitions>

<ColumnDefinition Width="Auto" />

<ColumnDefinition />

</Grid.ColumnDefinitions>

<Image Width="100" Height="100" Source="{Binding ImageUrl}"/>

<TextBlock Grid.Column="1" Text="{Binding Name}"

Style="{StaticResource PhoneTextLargeStyle}" />

</Grid>

</DataTemplate>

Note that the Text attribute of the TextBlock has changed from {Binding} to {Binding Name}, which tells the data-binding engine to use the Name property of the current data context (for instance, the Name property of the Contact being displayed). The Source property of the Image control is similarly data bound to the ImageUrl property. This will result in the layout shown in Figure 1 (D).

Deeper Dive into ListBoxNow that you’ve had a quick overview, it’s time to take a look at some of the more advanced aspects of the ListBox. I’ll start by looking at what happens when you set a background color on the list items. In the ListBoxItem-Template, add the following attribute value to the Grid: Background=“{StaticResource-PhoneInactiveBrush}”. In this case, as shown in Figure 2 (A), none of the list items stretches the width of the ListBox.

You might think that this could easily be solved by setting the HorizontalContent-Alignment property on the ListBox to Stretch. That’s not the case. You have to override the default ItemContainerStyle. Unlike the ItemTemplate, which was used

earlier to define the layout of each list item using a DataTemplate, the ItemContainer-Style is, as the name suggests, a Style. This means it’s comprised of a number of setters for properties such as the Background, Padding, Border and Template.

Right-click on the ListBox and select Edit Additional Templates, then select Edit Generated Item Container (ItemContainer-Style) and click on Edit a Copy. The Style that’s added to your project includes a Setter for Template, and its Value is a ContentTemplate. You can modify the ContentTemplate if, for example, you want to add a Border to each item in the list, or remove the default behavior that changes

the foreground color of the selected item. You can also change the default HorizontalContentAlignment from Left to Stretch, as shown in the following code:

<Style x:Key="FullWidthListBoxItemStyle" TargetType="ListBoxItem">

<Setter Property="HorizontalContentAlignment" Value="Stretch"/>

<!-- other property setters -->

</Style>

This will extend the background of the list items to the full width of the ListBox, as shown in Figure 2 (B).

In some cases, you may not want to present the list of items in a vertical list. Take, for example, the “recent” pane of the People hub. This is a 4x2 horizontal array of tiles that represent your recent contacts. You can present a similar interface within your application by overriding the default ItemsPanelTemplate. The ItemsPanel-Template determines how each list item is arranged relative to the other items in the list. By default, the layout of a ListBox uses a virtual- ized StackPanel, which makes it very efficient for long lists of items. This can be overridden by right-clicking on the ListBox and selecting Edit Additional Templates, then Edit Layout of Items (ItemsPanel), and Create Empty. Again, this doesn’t actually create an empty ItemsPanelTemplate; instead it includes a StackPanel by default.

UI Controls in the Silverlight ToolkitIn this case, I’m going to replace the StackPanel with a WrapPanel, found in the Silverlight Toolkit for Windows Phone (silverlight.codeplex.com). I want the list to extend sideways, so I change the default Orientation of the WrapPanel from Horizontal to Vertical. This will mean that items are initially listed vertically

Figure 1. The items in the ListBox can be hardcoded in XAML (A), dynamically loaded with Style and Margin (B), represented as a string by default (C) or arranged in Grid with an Image column and a TextBlock column (D).

(A) (B) (C) (D)

Figure 2. You can modify various templates; for example, change Left (A) to Stretch (B), or use Silverlight Toolkit controls such as WrapPanel (C) and HubTile (D) to modify the look of the ListBox.

(A) (B) (C) (D)

Page 53: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

{ MOBILE CORNER }

until the bottom of the control is reached, then a new column is started, progressing from left to right.

Finally, the default behavior of the ListBox itself is for the horizontal scrollbar to be disabled and for the vertical scrollbar to be automatic. This needs to be reversed by setting the Horizontal-ScrollbarVisibility to Auto and the VerticalScrollbarVisibility to Disabled. After doing this, you should see a layout similar to the one shown in Figure 2 (C).

At this point, I’ll make a small change to the ItemsTemplate to change the layout of the list items to use the HubTile control found in the Silverlight Toolkit:

<DataTemplate x:Key="ListBoxItemTemplate">

<toolkit:HubTile Notification="{Binding Name}" Source="{Binding ImageUrl}"

Margin="{StaticResource PhoneMargin}" />

</DataTemplate>

HubTile is a great control that makes building arrays of tiles within your application easy. It also includes animation similar to what a user sees on the Start screen of their device. Figure 2 (D)illustrates the use of HubTile within the ListBox.

Before I leave the ListBox, there are a couple of additional points worth noting. First, if you’re familiar with the behavior of the core Windows Phone experience, you’ll notice that when you tap an item in a list there’s a slight visual augmentation, or tilt, followed by an action, typically navigation to a new page. When the user returns to the list, typically via the back button, there’s no item selected in the list. The user can tap on the same item to interact with it again.

Unfortunately, the default behavior of the list does almost the reverse. There’s no tilt when the user taps an item. The ListBox changes the foreground color of the selected item and retains the selection when the user returns to the page. This prevents the user from reselecting that item. The steps to fix this problem are relatively straightforward:

Add the following attribute to the ListBox (alternatively you can add it to the ItemsTemplate): toolkit:TiltEffect.IsTiltEnabled=“True”.

Add an event handler to the SelectionChanged event on the ListBox and determine the selected item. Once the selected item has been retrieved, set the SelectedIndex to -1. This will reset the selected item on the list.

To prevent an iterative loop from occurring, make sure that you do a null check on the selected item:

private void ListSelectionChanged(object sender, SelectionChangedEventArgs e){

var selectedItem = (sender as ListBox).SelectedItem;

if (selectedItem == null) return;

(sender as ListBox).SelectedIndex = -1;

// Do action with selectedItem ...

}

In this article, I’ve covered a number of steps on how to use the ListBox control to present lists of items within your Windows Phone application. The ListBox is one of the most versatile and powerful controls. By overriding the various templates, you can completely change the look and feel of the control without changing the underlying behavior of the ListBox. VSM

Nick Randolph runs Built to Roam, a consulting company that specializes in training, mentoring and assisting other companies build mobile applications. With a heritage in rich client applications for both the desktop and a variety of mobile platforms, Randolph currently presents, writes and educates on the Windows Phone platform. 

Ask about fully-functional evaluations!

“lightning fast” Redmond Magazine

“covers all data sources” eWeek

“results in less than a second” InfoWorld

hundreds more reviews and developer case studies at www.dtsearch.com

The Smart Choice for Text Retrieval® since 1991

www.dtSearch.com 1-800-IT-FINDS

Instantly Search Terabytes of Text

®

Desktop with Spider Web with Spider

Network with Spider Engine for Win & .NET

Publish (portable media) Engine for Linux

• 25+ fielded and full-text federated search options

• dtSearch’s own file parsers highlight hits in popular file and email types

• Spider supports static and dynamic data

• APIs for .NET, Java, C++, SQL, etc.

• Win / Linux (64-bit and 32-bit)

Page 54: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

48 VISUAL STUDIO MAGAZINE · April 2012 · VisualStudioMagazine.com

The MVP Summit, from which I’ve just returned, is a very important event. The Summit is held toward the beginning of the calendar year, so it’s a kickoff of sorts; a good opportunity for MVPs to sync up and compare notes on where we think Microsoft is going. This year, it was especially important, as both the Windows 8 Consumer Preview and the Visual Studio 11 beta were released right in the middle of the Summit event, and the launch of SQL Server was scheduled for about a week later.

At the Summit, I attended a combination of developer- and SQL Server-oriented sessions; I sat in on an important Windows Azure briefi ng delivered by Corporate Vice President Scott Guthrie; I had some time to meet with the Visual Studio LightSwitch team; and I even learned a bit more about Offi ce 15. And though I didn’t attend any Windows 8-specifi c sessions, enough MVPs were able to download and install the Consumer Preview (despite the Wi-Fi overload this caused) that there was plenty of MVP conversation focused on that product as well.

Hard at WorkA lot of what I saw and heard at the Summit really encouraged me. Despite a signifi cant amount of personnel turnover at Microsoft of late, I found morale surprisingly high, product group members impressively focused, their presentations to be articulate and intelligent, and MVP reaction to be quite positive. I’m coauthor of a book on SQL Server and the author of a blog on Big Data, so I suppose I might be biased (at least in my level of interest), but I thought Microsoft’s efforts in both of these areas are especially well thought-out. In addition, the teams’ progress with Hadoop and SQL Server Parallel Data Warehouse exceeded my expectations.

The Developer Division guys had very good things to report, too. While most of what I heard can’t be shared just yet, I’d say that people have a lot to look forward to from OData, LightSwitch and Windows Azure. I genuinely found that team members were listening. Many of us joke that when Microsoft responds to input from the community by saying, “that’s good feedback,” you know your comment has fallen on deaf ears. At this year’s Summit, more than perhaps any event in memory, I really felt like the Microsoft people were listening and, literally, taking notes.

But the one area that has me concerned is Windows 8. That team’s communication strategy makes it tougher to gain insight and know that things are solid. Though it certainly won’t be

reversed, I have a feeling the team’s approach will be revised for the next product cycle.

One thing I found to be the case with virtually every team was a recognition of market realities. Microsoft really seems to be working with—rather than against—the grain of various technologies, many of them open source. Examples include HTML5, JavaScript, Representational State Transfer (REST) Web services, Hadoop, Git, a variety of non-Microsoft Web development tools and even, yes, the iPad. Redmond seems to have moved past rhetorical opposition to these technologies—and any self-congratulatory attitude around adoption of open source—toward a matter-of-fact acceptance of these technologies’ roles in the commonly heterogeneous technology environments in place for Microsoft customers.

Assess and ExecuteI’ve always found that when Microsoft assesses a problem correctly, it does well at solving it. That doesn’t mean Microsoft will, in the near term, transcend Apple’s multiyear head start in the consumer tablet space, beat Amazon Web Services in the cloud, or reverse the growth of new programming languages and environments. But what I think it does mean is that Microsoft will make progress in most or all of these areas.

If Microsoft can make big changes in several areas and iterative improvement in others, it may well reinvent itself in a way that’s sensitive to its particular strengths. That’s very hard to do, especially if it means Redmond acknowledging that its core strength, the PC, has become less central to many peoples’ lives, and that open source software has become a commodity fi xture at many customer sites.

But above the commodity level, there’s big opportunity, and lots of money to be made. Microsoft needs to believe in and align with that opportunity, and it seems it’s trying to succeed. If it does, it will be good for the company, its customers, its partners and even its competition. VSM

Andrew J. Brust is founder and CEO of Blue Badge Insights, an analysis, strategy and advisory firm serving Microsoft customers and partners. Brust is also a Microsoft regional director and MVP; an advisor to the New York Technology Council; coauthor of “Programming Microsoft SQL Server 2008” (Microsoft Press, 2008); co-chair of Visual Studio Live!; and a member of several Microsoft

“insiders” groups. Follow Brust on Twitter at twitter.com/andrewbrust.

Microsoft, the MVP Summit and the New Normal

BY ANDREW J. BRUST

</Redmond Review>

Page 55: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-4 1 1/9/12 3:32 PM

Page 56: Apr 2012: PDFpdf.1105media.com/VSMMag/2012/Apr.pdfApr 2012: PDF

Untitled-11 1 2/6/12 3:29 PM