Sei sulla pagina 1di 1550
Windows Forms 2.0 Programming By Chris Sells, Michael Weinhardt Publisher: Addison Wesley Professional Pub Date:

Windows Forms 2.0 Programming By Chris Sells, Michael Weinhardt

Publisher: Addison Wesley Professional Pub Date: May 16, 2006 Print ISBN-10: 0-3212-6796-6 Print ISBN-13: 978-0-321-26796-2 Pages: 1296

Table of Contents | Index

978-0-321-26796-2 Pages: 1296 Table of Contents | Index "Some books are different-the content can't be
978-0-321-26796-2 Pages: 1296 Table of Contents | Index "Some books are different-the content can't be

"Some books are different-the content can't be Googled from the Internet, the authors have real-life experiences to share, the code can be used in real-world projects. This is one of those books."

Neal Myrddin, Independent Developer

"Chris and Michael nail the soul of Windows Forms 2.0. This book provides an insightful view into the design of Windows Forms and the integration of new 2.0 features. It is just as appli c abl e for the fi rs t- ti me Wi ndows Forms programmer as the s eas oned li ne of bus i nes s developer. The 'What's New in 2.0' appendix is worth the price of admission alone."

MikeHarsh, Windows Forms ProgramManager, Microsoft, Inc.

"This book takes an amazingly broad and deep technology, and breaks it into manageable pieces that are easily consumed. You cannot survive building a complex WinForms application without this book."

Ryan Dorrell, Chief Technology Officer, AgileThought

" Wi ndows Forms 2.0 Programmi ng offers s omethi ng for every .NE T devel oper. Experi enc ed developers will appreciate the in-depth coverage of new 2.0 features, including the most comprehensive coverage of ClickO nce deployment, multithreading, and the new designer i ntegrati on found anywhere. Devel opers new to Wi nforms programmi ng wil l apprec i ate the coverage of the fundamentals all Winforms developers need to know. Whether you're an experienced WinForms developer or just beginning, you need this book."

Fritz Onion, cofounder of Pluralsight, author of Essential A SP.NET, and A SP.NET MV P

"I don't want just a description of the WinForms widgets. I can get that online or from other books . What I want i s a roadmap for pi tfall s to avoi d, and i nnovati ve s ol uti ons for c ommon problems. That is where this book shines. A ll of us who found the first edition of this book to be an indispensible part of our reference library will appreciate this updated edition that describes WinForms 2.0."

Johan Ericsson, Software Engineer, Agilent Technologies

"The books Chris Sells writes are always insightful and this newest addition is no different. This book in particular is for those who want to understand not just the flashy surface of Windows Forms 2.0, but also how it fits into the .NET environment. Readers will have this book at their desks, not stuck on their shelves, for quite a long time."

Yoshimatsu Fumiaki, Software Engineer based in Tokyo Japan

"Chris and Mike have done an excellent job presenting the information you need to be successful with Windows Forms."

Jessica Fosler, Dev Tech Lead, Microsoft

"This book is the 'must have' teaching and reference book for WinForms 2.0."

Jim Rittenhouse, Senior Software Engineer, Siemens

Wi ndows Forms 2.0 Programmi ng i s the s ucc ess or to the hi ghl y prai s ed Wi ndows Forms Programmi ng i n C#. T hi s edi ti on has been s i gni fi c antl y updated to amal gamate the s heer mas s of new and improved support that is encompassed by Windows Forms 2.0, the .NET Framework 2.0, and V isual Studio 2005. This is the one book developers need in order to learn how to build and deploy leading-edge Windows Forms 2.0 applications.

Readers will gain a deep understanding from Sells and Weinhardt's practical, well-balanced approach to the subject and clear code samples.

Windows Forms 2.0 fundamentals, including forms, dialogs, data validation, help, controls, components, and rendering

Static and dynamic layout, snap lines, HTML-style flow and table layout, automatic resizing, and automatic cross-DP I scaling

O ffice 2003-style tool strip control coverage, including dynamic layout and custom rendering

Design-time integration with the V isual Studio 2005 Properties Window and Smart Tags

• Resource management, strongly typed resources, and internationalization considerations

Strongly typed application and user settings

Windows Forms 2.0 Programming

By Chris Sells, Michael Weinhardt

SDI, MDI, Single Instancing, Multiple-Instance SDI, Single-Instance MDI, database-centric,

Publisher: Addison Wesley Professional

Pub Date: May 16, 2006

and document-centric applications

Print ISBN-10: 0-3212-6796-6

Print ISBN-13: 978-0-321-26796-2 Pages: 1296

Databinding data-source management, drag-and-drop databinding, the BindingSource, the BindingNavigator, and applied databinding

Events, delegates, multithreaded UIs, long-running operations, simplified multithreading with the BackgroundWorker, and asynchronous web service calls

ClickO nce application development publishing, shell integration, and partial trust security

Best practices for developers transitioning from Windows Forms 1.0 and MFC

and partial trust security • Best practices for developers transitioning from Windows Forms 1.0 and MFC
Table of Contents | Index Copyrigh t Microsoft.NET DevelopmentSeries Aboutthe Authors Forewor d Preface

Table of Contents | Index

Copyright

Microsoft.NET

DevelopmentSeries

Aboutthe Authors

Forewor

d

Preface

Chapter1.

Hello,WindowsForm

s Windows Forms

fromScratch

Windows Forms in Visual Studio .NET

Arranging Controls

Controls

Applicatio

n Settings

Resources

Dialog

s

Drawi

ng

Printin

g Data

Bindin

g

Multithreaded User

Interfaces

Deployment

Where

AreWe?

Chapter 2.

Forms

Showing

Forms

FormLifetime

FormNotificati

on FormSize

and Location

FormAdornme

Windows Forms 2.0 Programming By Chris Sells, Michael Weinhardt

Publisher: Addison Wesley Professional Pub Date: May 16, 2006 Print ISBN-10: 0-3212-6796-6 Print ISBN-13: 978-0-321-26796-2 Pages: 1296

nts

FormTranspar

ency Formand

Context Menus

Tool Strips

Status Strips

MultipleDocumentInte

rface Applications

Visual Inheritance

Where

AreWe?

Chapter 3.

Dialogs

Standard

Dialogs

FormStyl

es

Data

Exchange

Data

Validation

Implemen

tingHelp

Where

AreWe?

Chapter 4.

Layout

Fixed

Layout

DynamicLa

yout

Layout

Controls

Layout

Optimizatio

n

CustomLay

out Where

AreWe?

Chapter5.

DrawingBasi

cs Drawingto

the Screen

Colors

Brush

es

Pens

Shape

s

Paths

Image

s

Where

AreWe?

Chapter6.

DrawingText

Fonts

Strings

The Windows Forms 2.0 Programming

TextRenderer By Chris Sells, Michael Weinhardt

ATaleofTwo Publisher: Addison Wesley Professional

Technologies

Pub Date: May 16, 2006

Print ISBN-10: 0-3212-6796-6

Print ISBN-13: 978-0-321-26796-2

Where AreWe?

Pages: 1296

Chapter7.

AdvancedDra

wing Page

Units

Transform

s Regions

Optimized

Drawing

Where

AreWe?

Chapter 8.

Printing

Print

Document

s

PrintCont

rollers

BasicPrin

tEvents

Margins

Page

Settings

Printer

Settings

UsefulPrinting

Techniques

Where AreWe?

Chapter9.

Components

Components

Defined

UsingComponen

ts

CustomCompone

nts Where

AreWe?

Creating

Chapter10.

Controls

Controls

Defined

UsingControl

s

Controls

Themed

Owner-

Drawn

Controls

Extending

Existing

Controls

CustomContro

ls

User

Controls Hosting COMControls Where AreWe? Chapter11. Design- TimeIntegration:ThePropertie sWindow Design- TimeComponents Hosts, Containers, and Sites Debugging Design-Time Functionality The DesignMode Property Attributes Code Serializati on Batch Initializati on Extender Property Providers Type Converters UI Type Editors Where AreWe? Chapter12. Design- TimeIntegration:DesignersandS martTags Designers Smart Tags Where AreWe?

Chapter13.

Resources Resource Basics Strongly Typed Resources Application Internationalizati on Where

AreWe?

Chapter14.

Windows Forms 2.0 Programming

Applications

Applications

By Chris Sells, Michael Weinhardt

Publisher: Addison Wesley Professional

Pub Date: May 16, 2006

Single-Instance

Applications

Pages: 1296

Print ISBN-10: 0-3212-6796-6

Print ISBN-13: 978-0-321-26796-2

Where AreWe? Chapter 15. Settings The ApplicationEnvironment Application, User, and Roaming-User Settings Strongly Typed Settings Using Strongly Typed Settings Designer Settings

Alternative Storage for

Settings

AreWe?

Where

Chapter16.

DataBindingBasics

The Land before Data

Binding

Data Binding and ItemData Sources Simple Binding and List Data Sources

Simple

Complex Binding and List Data Sources IBindingList BindingList<T> The BindingSource Component Design- Time Data Sources BindingUIElementsi ntheDesigner Where AreWe?

Chapter17.

AppliedDataBindi ng Drag-and- Drop Data Binding Fundamentals of Data-Bound UIs Data Views Real-World Data-Bound UIs Where AreWe?

Chapter18.

MultithreadedUserIn terfaces Long- RunningOperations Asynchronous Web

Services

AreWe?

Where

Chapter19.

ClickOnceDeployment ADayintheLifeof ClickOnce Deployment ClickOnce Configuration ClickOnce Security Managing Permissions ConsiderationsforPartiall

yTrusted Assemblies Pr oc ess i ng Command Li ne

Arguments

Where

AreWe?

AppendixA.

What'sNewinWindowsF

orms2.0

WordsAboutWindowsFor

ms

AFew

Windows Forms

2.0 Enhancements Windows Forms 2.0: The Improvements AppendixB. MovingfromMFC AFew

WordsAboutMFC MFCVersus Windows Forms MFCand Windows Forms Interop Windows Forms as a Better MFC AppendixC. DelegatesandEvents Delegates Events Anonymous Delegates Happiness in theUniverse AppendixD. ComponentandContro lSurvey Components Controls AppendixE. DragandDrop Enabling Drag and Drop Adding Support for Multiple Drag-and-Drop Effects Customizing Drag and Drop Drag and Drop of Multiple Data Items File Drag and Drop AppendixF. DocumentManage ment TheFileDocumentC omponent Shell Integration The MruMenuManager Component Opening Files Dragged and Dropped fromthe Shell Bibliography

ColorIns

ert

Index

The MruMenuManager Componen t Opening Files Dragged and Dropped fromthe Shel l Bibliography ColorIns er t
The MruMenuManager Componen t Opening Files Dragged and Dropped fromthe Shel l Bibliography ColorIns er t
Copyright Many of the designations used by manufacturers and sellers to distinguish their products are

Copyright

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and the publisher was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals.

The .NET logo is either a registered trademark or trademark of Microsoft Corporation in the United States and/or other countries and is used under license from Microsoft. The following articles were originally printed in MSDN Magazine, and are reprinted in this book with permission. ".NET Zero Deployment: Security and V ersioning Models in the Windows Forms Engine Help You Create and Deploy Smart Clients" by Chris Sells, MSDN Magazine, July 2002. "V isual Studio .NET: Building Windows Forms Controls and Components with Rich Design-Time Features" by Michael Weinhardt and Chris Sells, MSDN Magazine, A pril 2003. "V isual Studio .NET: Building Windows Forms Controls and Components with Rich Design-Time Features, Part 2" by Michael Weinhardt and Chris Sells, MSDN Magazine, May 2003. ".NET Framework 2.0: Craft a Rich UI for Your .NET A pp with Enhanced Windows Forms Support" by Michael Weinhardt and Chris Sells, MSDN Magazine, May 2004. "Smart Tags: Simplify UI Development with Custom Designer A ctions in V isual Studio" by Michael Weinhardt, MSDN Magazine, July 2005. "Draft a Rich UI: Ground Rules for Building Enhanced Windows Forms Support into Your .NET A pp" by Michael Weinhardt and Chris Sells, MSDN Magazine, May 2005.

The authors and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions. No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein.

The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales, which may include electronic versions and/or custom covers and content particular to your business, training goals, marketing focus, and branding interests. For more information, please contact:

U.S. Corporate and Government Sales (800)

382-3419

For sales outside the United States please contact:

International Sales international@pearsoned .com

Library of Congress Cataloging-in-Publication Data:

Sells, Chris. Windows Forms 2.0 programmi ng/C hri s Sell s &

Michael Weinhardt. p. cm. ISBN 0-321-26796-6 (pbk. : alk. paper) 1. Microsoft .NET Framework. 2. Computer softwareDevelopment. I. Weinhardt, Michael. II. Title. QA

76.76.M52S44

2006

005.2'768dc22

2006000194

Copyright © 2006 Chris Sells and Michael Weinhardt A ll rights reserved. Printed in the United States of A merica. This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding permissions, write to:

Pearson Education, Inc. Rights and Contracts Department 75 A rlington Street, Suite 300 Boston, MA 02116 Fax: (617) 848-7047

Text printed in the United States on recycled paper at Edwards Brothers in A nn A rbor, Michigan First printing, May 2006

"Some books are different; the content can't be Googled from the Internet, the authors have real-life experiences to share, the code can be used in real-world projects. This is one of those books. A nd it's not a simple upgrade of the 1 st edition; this book has been completely refitted to present WinForms 2.0 as it should be presented."

Neal Myrddin, Independent Developer

"Chris and Michael nail the soul of Windows Forms 2.0. This book provides an insightful view into the design of Windows Forms and the integration of new 2.0 features . I t i s jus t as appli c abl e for t he fi rs t - ti me Wi ndows Forms programmer as t he seasoned line of business developer. The What's New in 2.0 appendix is worth the price of admission alone."

MikeHarsh, Windows Forms ProgramManager, Microsoft, Inc.

"This book takes an amazingly broad and deep technology, and breaks it into manageable pieces that are easily consumed. You cannot survive building a complex WinForms application without this book."

Ryan Dorrell, Chief Technology Officer, AgileThought

" Wi ndows Forms 2.0 Programmi ng offers s omethi ng for every .NE T devel oper. Experienced developers will appreciate the in-depth coverage of new 2.0 features, including the most comprehensive coverage of ClickO nce deployment, multithreading, and the new designer integration found anywhere. Developers new to Wi nforms programmi ng wil l apprec i ate the c overage of the fundamental s al l Wi nforms developers need to know. Whether you're an experienced WinForms developer or just beginning, you need this book."

Fritz Onion, cofounder of Pluralsight, author of Essential A SP.NET, and ASP.NET MVP

"I don't want just a description of the WinForms widgets. I can get that online or from other books. What I want is a roadmap for pitfalls to avoid, and innovative solutions for c ommon probl ems . T hat i s where thi s book s hi nes . A l l of us who found the fi rs t edition of this book to be an indispensible part of our reference library will appreciate this updated edition that describes WinForms 2.0."

Johan Ericsson, Software Engineer, Agilent Technologies

"The books Chris Sells writes are always insightful and this newest addition is no different. This book in particular is for those who want to understand not just the flashy surface of Windows Forms 2.0, but also how it fits into the .NET environment. Readers will have this book at their desks, not stuck on their shelves, for quite a long time."

Yoshimatsu Fumiaki, Software Engineer based in Tokyo Japan

"Chris and Mike have done an excellent job presenting the information you need to be successful with Windows Forms."

Jessica Fosler, Dev Tech Lead, Microsoft

"This book is the 'must have' teaching and reference book for WinForms 2.0."

Jim Rittenhouse, Senior Software Engineer, Siemens

Dedication

To my wife, Melissa, and my sons John and Tom. They define the heaven that exceeds my grasp. And to my parents, who made me a reader from the beginning and who passed on the secret writer gene, much to my surprise.

Chris Sells

To Josef and Lili, for all that I am and all that I've done. To Alex, for al l t hat I woul d li ke t o be and wi s h I coul d do. Mi chael Wei nhardt

all that I've done. To Alex, for al l t hat I woul d li ke
Microsoft .NET Development Series John Montgomery, Series Advisor Don Box, Series Advisor Martin Heller, Series

Microsoft .NET Development Series

John Montgomery, Series Advisor Don Box, Series Advisor Martin Heller, Series Editor

The Microsoft .NET Development Series is supported and developed by the leaders and experts of Microsoft development technologies including Microsoft architects and DevelopMentor instructors. The books in this series provide a core resource of information and understanding every developer needs in order to write effective applications and managed code. Learn from the l eaders how to maxi mi ze your us e of the .NE T Framework and i ts programmi ng languages.

Titles in the Series

Brad A brams, .NET Framework Standard Library Annotated Reference Volume 1: Base Class Library and Extended Numerics Library, 0-321-15489-4

Brad A brams and Tamara A brams, .NET Framework Standard Library Annotated Reference, Volume 2: Networking Library, Reflection Library, and XML Library, 0-321- 19445-4

Kei t h Balli nger, .NET Web Servi ces : Archi t ect ure and I mpl ement at i on, 0 - 321 - 11359 - 4

Bob Beauchemin, Niels Berglund, Dan Sullivan, A First Look at SQL Server 2005 for Developers, 0-321-18059-3 Don Box with Chris Sell s , Ess enti al .NET, Vol ume 1: The Common Language Runti me,

0-201-73411-7

Keith Brown, The .NET Developer's Gui de to Windows Security, 0-321-22835-9

Eric Carter and Eric Lippert, Visual Studio Tools for Office: Using C# with Excel, Word, Outlook, and InfoPath, 0-321-33488-4

Eric Carter and Eric Lippert, Visual Studio Tools for Office: Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath, 0-321-41175-7 Mahesh Chand, Graphics Programmi ng wi th GDI +, 0- 321- 16077- 0 Krzysztof Cwalina and Brad A brams, Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 0-321-24675-6 A nders Hejlsberg, Sc ott Wil tamuth, P eter Gol de, The C# Programmi ng Language, 0- 321- 15491- 6 A lex Homer, Dave Sussman, Mark Fussell, ADO.NET and System.Xml v. 2.0The Beta Versi on, 0-321-24712-4 A l ex Homer, Dave Sussman, Rob Howard, ASP.NET v. 2.0The Beta Version, 0-321-25727-8 James S. Mill er and Sus ann Rags dal e, The Common Language I nf ras tructure Annotated Standard,

0-321-15493-2

Christian Nagel, Enterprise Services with the .NET Framework: Developing Distributed Business Solutions with .NET Enterprise Services , 0-321-24673-X Brian Noyes, Data Bi ndi ng wi th Wi ndows Forms 2.0: Programmi ng Smart Cli ent Data Appli cati ons wi th .NET,

0-321-26892-X

Fri tz O ni on, Ess enti al ASP.NET wi th Exampl es i n C#, 0-201-76040-1

Fritz O nion, Essential ASP.NET with Examples in Visual Basic .NET, 0-201-76039-8

Ted P atti s on and Dr. Joe Hummel , Buil di ng Appli cati ons and Components with Visual Basic .NET, 0-201-73495-8 Dr. Neil Roodyn, eXtreme .NET: I nt roduci ng eXt reme Programmi ng Techniques to .NET Developers, 0-321-30363-6 Chris Sells, Wi ndows Forms Programmi ng i n C#, 0- 321- 11620- 8 Chris Sells and Justin Gehtland, Windows Forms Programmi ng i n Vi s ual Bas i c .NET, 0- 321- 12519- 3 P aul V i c k, The Vi s ual Bas i c .NET Programmi ng Language, 0- 321-

16951-4

Dami en Watki ns , Mark Hammond, Brad A brams , Programmi ng in the .NET Environment, 0-201-77018-0 Shawn Wildermuth, Pragmatic ADO.NET: Data Access for the Internet World, 0-201-

74568-2

P aul Y ao and Davi d Durant, .NET Compact Framework Programmi ng wi th C#, 0 - 321- 17403 - 8

P aul Y ao and Davi d Durant, .NET Compact Framework Programmi ng wi th Vi s ual Bas i c .NET, 0 - 321 -

17404-6

For more inf ormation go to www.awprof essional.com/msdotnetseries/

th Vi s ual Bas i c .NET, 0 - 321 - 17404-6 For more inf
About the Authors Chris Sells is a program manager for the Connected Systems Division. He's

About the Authors

Chris Sells is a program manager for the Connected Systems Division. He's written several books , i nc l udi ng Programmi ng Wi ndows Pres entati on Foundati on (O ' Reill y), Wi ndows Forms Programmi ng i n C# (A ddi s on- Wes l ey), and ATL I nternal s (A ddi s on- Wes l ey). I n hi s free ti me, Chris hosts various conferences and makes a pest of himself on Microsoft internal product team discussion lists. More information about Chris (and his various projects) is available at http://www.sellsbrothers.com.

Michael Weinhardt i s a programmer/wri ter at Mi c ros oft, worki ng on the Wi ndows C li ent SDK. Michael has coauthored a variety of articles with Chris, contributed to the "Wonders of Windows Forms" column at MSDN O nline, reviewed several Windows technology books, and generall y l oves c ommuni c ati ng the whys and wherefores of tec hnol ogy to hi s peers . Mi c hael i s sure that his parents attribute his fascination in technology to their purchase of an A miga 1000 in the mid-80s. They would be right.

attribute his fascination in technology to their purchase of an A miga 1000 in the mid-80s.
attribute his fascination in technology to their purchase of an A miga 1000 in the mid-80s.
Foreword A l ong, l ong ti me ago when I began programmi ng P

Foreword

A l ong, l ong ti me ago when I began programmi ng P C GUI s , there were none of thes e fanc y

framework thingies. O ne wrote a whole lot of C code in a case statement long enough to cut a giant's undershirt out of. I'd spent a couple weeks understanding and implementing DDE (yes, DDE) in the application we were building (and frankly, it was not the most pleasant experience) when I ran across an article in a magazine showing how this fancy thing called "Smalltalk" could do DDE in a couple of lines of code. Wow! I thought. That's the way I want to program! I've been

working with and on UI frameworks pretty much ever since, which is how I ended up working on Windows Forms at Microsoft.

For V 1 of Windows Forms, our goal was to produce a comprehensive UI framework that

combined the ease of use of V B with the extensibility and flexibility of MFC.

we picked up additional goals, including rich design-time extensibility, GDI+ support, and support for partial trust for No Touch Deployment (NTD). I think we did a reasonable job of

meeting these goals. Despite the focus on the "web stuff" when we first released, there are an enormous number of people using Windows Forms today to build all types of applications, from photo management software to applications supporting core business processes. I find seeing the interesting applications people build with Windows Forms one of the more rewarding parts

of my job. However, to be honest, there are areas where we could have done better, for

example, NTD had no V isual Studio support and could be complex to debug when things went

wrong, so overall, I have to give V 1 of Windows Forms a "shows promise" rating.

A long the way,

V 2 of Windows Forms is about delivering on that promise. This is a major upgrade to Windows

Forms. A lmost every area of Windows Forms design-time and run-time has been improved. A s Chris and Michael call out in A ppendix A : What's New in Windows Forms 2.0, we have incorporated completely new features and a large number of improvements to our existing features (apparently we have 329 new types, 139 updated types, and 14,323 new members). Rather than repeat A ppendix A , I'm going to call out three new features that I think illustrate how we achieved our goals for this version of Windows Forms: solve deployment, enable great- looking apps, and enhance productivity.

Deployment

I think the single most significant feature in V 2 of the .NET Framework (not just Windows Forms, but the whole .NET Framework) is ClickO nce. ClickO nce delivers on the promise of No Touch Deployment to bring easy, reliable, and manageable web-based deployment to client applications. Deploying your application via the web is now simply a matter of stepping through a wizard in V isual Studio 2005.

Great-Looking Apps

Ever since I joined Microsoft, customers have asked for the ability to build applications that look like Microsoft O ffice "out of the box," and you can do exactly that with V 2 of Windows Forms using the new menu strip, tool strip, and status strip controls (ToolStrip, MenuStrip, and StatusStrip). Not only do the strip controls support the standard Windows and O ffice look and

feel, but they can also be customized to look like pretty much anything you fancy.

Productivity

We've added a whole set of design-time and run-time improvements that we believe will help you to be more productive. O ne of my favorite new designer features is SnapLines, which allows you to quickly align controls with each other as you lay out your forms. O nce you've used a designer with SnapLines, you never want to go back, it's the designer equivalent of IntelliSense.

The Future

A fter shipping V 2, our thoughts are naturally turning to the future. Predicting the future is a

dangerous business, most of the predictions from when I was a kid mean we should be supporting actors in either The Jetsons or 1984 by now, and so I'm a little nervous about making any long-term predictions. However, I can say a few things based on where we are and what I would like to see us do. First, the .NET Framework and managed code is here to stay: It is the programmi ng model of the pres ent and t he future. Learni ng t o us e t he .NE T Framework and Windows Forms is a solid investment for the future. Second, to paraphrase Samuel Clemens terribly, "Reports of the death of client apps are greatly exaggerated." Client applications are here to stay, can now be deployed as easily as web applications, provide significant business value, and will provide more value as time progresses. Third, as part of our continued investment in Windows Forms, we will ensure that Windows Forms works well with new technologies coming down the pipe such as those in WinFX. This allows you to build applications today with the knowledge that you will be able to enhance those applications in the future using both Windows Forms and these new technologies as they become available. Finally, from a Windows Forms perspective, I believe we need to broaden what we provide into a framework and design experience that addresses the end-to-end process of building a client application. We have a great designer to help you build your UI, but you still have to write way too much code to

build your whole application. I would like to see us provide a great designer-based experience for your entire application, not just your forms.

So hopefully what I've said about Windows Forms has got you at least a little curious to find out more (which is where this book comes in). The first edition of this book was a great overview of and introduction to Windows Forms. The same is true of this second edition. Whether you are learning Windows Forms for the first time or if you just want to get a handle on the new stuff we've done in V 2, this book will help you. It covers all of the significant feature areas, from the basics of creating Forms, through ToolStrips and data binding to deployment with ClickO nce.

The book is a great balancing act: It neither ignores V isual Studio 2005 nor reduces itself to a simplistic "Click here then click here" walkthrough of V isual Studio 2005 features. The book not only explains the concepts and shows you how to use those concepts in code, but it also shows you how the designer helps you to be more productive by automatically generating the code for you. This leaves you with a solid understanding of both how things work and how to use V isual Studio 2005 to get things done as productively as possible. The chapters on data binding (16 and 17) are a great example of this approach. The source code examples are another great balancing act: They are neither too short to be useful nor so long as to be overwhelming. To quote A lan Cooper, they are "Goldilocks code" examples because they are "just right."

I would like to particularly highlight the chapters on data binding (Chapters 16 and 17), not just because data binding is very close to my heart, but because the book does an excellent

20 / 664

job of explaining how data binding works and how to use it effectively. I would also like to highlight the chapters on writing design-time behavior for your controls and components (Chapters 11 and 12) because this is a subject that is often neglected. These chapters alone make this a "must read" book.

So, i n s ummary, thi s book wil l l eave you not onl y i n a pos i ti on to effec ti vel y us e what we provi de as part of Windows Forms but also with the understanding you need to write your own run-time and design-time extensions to what we provide.

I'd like to close with some acknowledgments and thanks. First, thanks to the entire Windows Forms team, who have worked tirelessly to build and ship what I believe is a great product. I'm very proud of what we have achieved. Second, my thanks to Michael and Chris not only for producing a book that does a great job of explaining our product and will make it easier for our customers to use, but also for their c ontri buti ons to the wi der Wi ndows Forms c ommuni ty. T hanks to Mi c hael for hi s great arti c l es on MSDN and feedback on Windows Forms V 2particularly his feedback on the ToolStrip controls. Thanks to Chris for his seemingly boundless enthusiasm for Windows Forms, his excellent writing on Windows Forms, his deep understanding of Windows Forms, MFC, and Windows, and his polite and measured but enthusiastic and copious feedback on every aspect of the product. Both Mike and Chris have helped enormously both in promoting understanding of the product and in helping make Windows Forms as good as it is today. A nd finally, my thanks to our customers: Every single feature in Windows Forms V 2 is based on your feedback. So to all of you who took the time to give us feedback and suggestions: Thanks! Please keep it

coming!

I hope you have fun using Windows Forms.

MarkBoulter

P M Technical Lead,

Client Development Tools, Microsoft

22 / 664
Preface Wi ndows 1.0 programmers had a s trai ghtforward li fe. T hey had

Preface

Wi ndows 1.0 programmers had a s trai ghtforward li fe. T hey had al mos t no c hoi c es about how to

do thi ngs ; ei ther t here was an appli c ati on programmi ng i nterfac e

most of the time there wasn't. This meant that developers had to build almost everything by hand. A t the ti me, thi s was n' t a probl em. A l l Wi ndows programmers had t he s ame li mi tati ons , so everyone's apps more or less operated with the same limited set of functionality.

A modern Windows developer, on the other hand, is inundated with choices. The invention of

the web alone gives us static Hypertext Markup Language (HTML), server-based user interface (UI) interaction via A SP.NET, and client-side UI interaction via A ctiveX controls or A JA X (to

name a few). [1] O n the client side, we have native frameworks like Microsoft Foundation Classes (MFC), A ctive Template Library (A TL), and the next-generation managed framework known as the Windows Presentation Foundation (WP F is part of WinFX, the follow-on to the .NET Framework). How does a developer choose? Where does Windows Forms 2.0, the topic of this book, fit into this pantheon?

(A P I ), or t here was n' t, and

[1] AJAXstands f or Asynchronous JavaScript and XML, as def ined by Jesse James Garrett, "Ajax: A New Approach to Web Applications,"

Client technologies on Windows provide a range of reach and richness in inverse proportion to each other. Reach is the ability of a user interface (UI) to work across operating systems, whereas richness is the ability for a UI to take advantage of the operating system on which it runs. So even though static HTML works almost everywhere, to the extent that your HTML uses client-side JScript, reach is diminished for browsers that don't support the scripting constructs being used. Even further down the reach scale are A ctiveX controls, which work only on Windows but allow full access to its richness. [2]

[2] At one point, the Component Object Model (COM) and ActiveXwere made to work across platf orms, but they have long since been relegated to Windows only.

A t the other extreme we have WP F, a completely new managed framework built on top of

DirectX. WP F encompasses documents, layout, animation, 2-D, 3-D, text, and graphics primitives in a single, cohesive whole. This framework provides the richest client technology that Microsoft has ever built, and it takes maximum advantage of the platform on which it runs,

including any hardware 3-D graphics acceleration that may be available. However, at the time

of this writing, WP F has not yet shipped and works only under Windows XP, Windows Server

2003, and Windows

V ista. [3]

[3] WinFX (which inclues WPF) and Windows Vista are scheduled to ship in 2006.

Where does that leave Windows Forms 2.0? It doesn't quite offer the richness of WP F, but it's far richer than the HTML-based technologies. Windows Forms 2.0 also is much richer than Windows Forms 1.0, with greatly enhanced support for flexible layout, modern menu strip and

tool strip controls, data binding, multithreading, typed resources and settings, and, most importantly, ClickO nce deployment.

With ClickO nce, for the first time, users can deploy Windows applications as easily as web applications. Even better, ClickO nce allows Windows applications to be installed locally, integrated with the Start menu, and accessed even if no network connection is available. These options are not available for users of Web applications.

So Windows Forms 2.0 is high on the richness scale, but what about the reach scale? Unlike

web applications, Windows Forms requires that users' machines operate on Windows, specifically Windows 98 or later for P Cs. However, it also supports other devices, such as Pocket P Cs or Smartphones, via the .NET Compact Framework. This means that you can write

a Windows Forms 2.0 application and run it on your Windows smartphone.

Based on this level of richness and reach, what kinds of applications should you build with Windows Forms? A s it turns out, folks have used Windows Forms to build almost every kind of application, including productivity applications, utilities, enterprise tools, and more (even games). Windows Forms can be used to build smaller things, such as Microsoft's own internal human resources application (called HeadTrax), or larger things, such as most of the UI enhancements that have been built on top of V isual Studio since the 2002 edition. This range of applications can be built because of Windows Forms' range of features and tools, its reach, and, as of thi s vers i on, the maturi ty of the i mpl ementati on bas ed on c ommuni ty us age and feedback.

I n fac t, t he .NE T devel oper c ommuni ty has embrac ed Wi ndows Forms to a degree that defi es the early .NET focus on web-based applications. Based on talking to my friends in the training industry and on the sales of the first edition of this book, I conclude that a large and growing number of developers write Windows Forms applications. It's for those developers that we've written this book.

W ho Should Read This Book?

When writing this book, we wanted to provide real-world Windows Forms coverage for programmers who' ve programmed i n .NE T (and thos e who haven' t). To t hat end, we bri efl y introduce core .NET topics as they come up. However, we don't pretend to cover the .NET Framework completely. It's too large a topic. Instead, when we think more information would be useful, we reference another work that provides the full details. In particular, you'll find that we've referenced Essential .NET, by Don Box, with Chris Sells, a great deal, making it a good

c ompani on to thi s book. I n the s ame c ategory, we al s o rec ommend Advanced .NET Remoti ng, by

I ngo Rammer,

more details on these books, see the Bibliography.)

and Appli ed Mi cros of t .NET Framework Programmi ng, by J effrey Ri c hter. (For

O ne c ore .NE T topi c i s of s pec i al i mportanc e to Wi ndows Forms programmers , and we c over i t i n more detail in A ppendix C: Delegates and Events. This coverage is particularly important if

you' re new to .NE T, al though we don' t rec ommend di vi ng i nto that topi c unti l you' ve got a

Windows Forms-specific frame of reference (which through Chapter 1: Hello, Windows Forms).

is provided about one-third of the way

A l s o of parti c ul ar i mportanc e to former (or s oon- t o- be former) MFC programmers , we' ve provided A ppendix B: Moving from MFC, and A ppendix F: Document Management. A lthough

Windows Forms doesn't provide all the features of MFC, we've worked hard on the material and code samples in this book to plug most of the gaps.

O ne other note: Many years ago, one of the authors wrote his first five-day training course.

The topic, Windows 95, included a few hours of coverage on the new controls: what they looked like, what their properties, methods, and events were, and how to program against them. Those hours seemed like days for everyone involved. The details of a particular control are interesting only when you're putting it to use, and when that time comes, the control- specific documentation and V isual Studio's IntelliSense help support do a marvelous job of giving you the information you need.

To that end, this book covers none of the standard controls completely. Instead, when a control

is interesting in the context of the current topic (such as the DataGridV iew control in Chapter

17: A pplied Data Binding) we cover that control appropriately. A lso, to give you a list of all the

components and controls and to introduce you to each one's major functionality, A ppendix D:

Component and Control Survey provides a list of the standard controls and components. We wouldn't think of wasting your time by attempting to be more thorough than the reference documentation that comes with the .NET Framework software development kit (SDK) and V isual

Studio 2005. Instead, this book focuses on the real-world scenarios that aren't covered in detail

elsewhere. Finally, to help you understand the

and how to build both, we've provided Chapter 9: Components and Chapter 10: Controls.

differences between components and controls

Conventions

If you've decided to take the plunge with this book, we'd like to thank you for your faith and

express our hope that we live up to it. To aid you in reading the text, we want to let you in on

some conventions we use.

First, there is the mode of address that we use throughout the book (except for this preface). Because Chris and Michael worked so closely and so hard on every word in this book, the use

of "I" really means "both authors," whereas the use of "we" means "the authors and you." A

lthough we sometimes use "you" directly, Michael and Chris lean toward the inclusive.

The wonderful thing about Windows Forms is how visual it is, and that's why we use a lot of figures to illustrate its features. Some of those pictures really need to be in color to make the point, so be sure to check the color pages at the center of this book for those color plates.

A s useful as figures are, we both think primarily in code. Code is shown in monospace type:

System.Console.WriteLine(" Hello, Windows Forms.");

Console application activation is also shown in monospace type:

C:\> csc.exe

hello.cs

When a part of a c ode s ni ppet or a c ommand li ne ac ti vati on i s of parti c ul ar i nteres t, we mark i t i n bol d and often provi de a c omment:

// Notice the use of the .NET System namespace System.Console.WriteLine(" Hello, Windows Forms.");

When we want to direct your attention to a piece of code more fully, we replace superfluous code with ellipses:

class MyForm :

System.Windows.Form s.Form { // fields private void MyForm_Load( object sender, System.ComponentModel.Even tArgs e) {

MessageBox.Show("Hello from MyForm");

}

}

Furthermore, to make the printed code more readable, we often drop namespaces and protection keywords when they don't provide additional information:

/ / Shortened "System.Windows.Forms.F orm" base class class MyForm : Form { // fields

// Removed "private" specifier and "System.ComponentModel" namespace void MyForm_Load(object sender, EventArgs e) { MessageBox.Show("Hello from MyForm");

}

}

When showing .NET attributes, we use their abbreviated name:

[Serializable] // Instead of

[SerializableAttribute]

class MyCustomType {

}

C# lets you drop the "A ttribute" suffix for convenience, but remember to append this suffix when you look up the details of the attribute class in the online documentation.

For clarity, we sometimes omit error checking from the printed code, but we try to leave it in the sample code that you'll find at our web site.

In the text, we often put a word or phrase in italics to indicate a new term that we're about to define. A s an example of this kind of term and its definition, hegemony is a preponderant influence or authority, as well as a potent business practice.

Sometimes, we mention keyboard shortcuts because we find them convenient. The ones I menti on are the defaul t V i s ual Studi o 200 5 (V S05) key bi ndi ngs for C # programmers . I f you' re not using those key bindings, you'll need to map the keyboard shortcuts to your own settings.

Finally, because this is the second edition of this book, we've taken care to mark new and updated types i n the margi ns wi th graphi c s and i n the c ode wi th c omments . A l s o, for a s ummary of what' s new i n Wi ndows Forms , c hec k out A ppendi x A : What' s New i n Wi ndows Forms 2.0.

Contact

The up-to-date information for this book, including the source code and the errata, are maintained at http://www.sellsbrothers.com/writing/wfbook. This site also lets you send feedback about the book, both complimentary and less so.

Michael's

Acknowledgments

Writing a book is not just the application of pen to paper, nor is its creation confined to the authors. Whether they know it or not, many people have helped make this book what it is.

My parents, Josef and Lili: Without a doubt, I could not have seen this book through to the end

i f i t weren' t for the i mmeas urabl e and unques ti oni ng l ove and s upport of my parent s . T hey' ve been there for me in this way since the day I was born, which I find truly staggering. How can I

thank them enough? I simply cannot. Instead,

out of the life they've provided. For this reason, I put everything I had into this book.

I try and do the best I can by making the most

My brother, A lex: When he applied to attend a university, he definitely met the entry requirements. However, he was told by the university that he shouldn't bother because it would be very unlikely he would complete his studies successfully. O f course, they were very wrong.

When I endure some of the darker moments in writing and want to throw it all away, I think of all he has accomplished in his life. Then I very quickly realize that writing so completely pales in comparison, before pulling my head in and keeping on writing. He is a big inspiration in my life, and he helped me to stay the course on this book. I thought he should know.

My coauthor, Chris Sells: I have often written with Chris because I enjoy it so much. It's fun, it's a challenge, and it usually results in the production of something that I can really be proud of. When Chris asked me to coauthor this book, I couldn't say no. I'm still surprised by how much latitude he gave me to work with, more than a one-to-one update of the first edition, and I can't thank him enough for his faith, and for all that he has given over the years.

My friends Kym Phillpotts and Hodaka Shibata: They've been there for me for the long haul, and when I think of good mates, I instantly think of them.

"Mr. Windows Forms," Mark Boulter: Even though I've never met Mark in the physical world, he has played a huge role in fueling my passion for Windows Forms and the desire to tell its story. I'd always hoped that he would write the foreword for this book, and I am honored he did.

My safety net, Microsoft's Jessica Fosler: When I had technical and conceptual questions that often needed quick responses, Jessica always provided articulate, comprehensive, and prompt answers, for which I am very grateful. A nd, as if that weren't enough, Jessica made time to revi ew our enti re book, provi de t horough and pos i ti ve c ommentary, and, for good meas ure, threw in some great prose.

O ur main reviewer, Christophe Nasarre: Christophe performed two reviews in a very limited time. It is almost scary how good he is and how much the book improved as a result of his efforts. I can honestly say that I felt comfortable about this book only after his involvement, and if I ever write another book, I'll be disappointed if he isn't available. Merci!

O ur Microsoft reviewers, Sameer Bhangar, Barry Briggs, Felix Cheung, A ndrew Coates, Jamie

Cool, Shreeman Dash, Erick Ellis, Shawn Farkas, David Guyer, Mike Harsh, Zach Kramer, Steve Lasker, Elizabeth Maher, Chris Meyer, Mark Rideout, and Joe Stegman: A ll had a role in the development of Windows Forms 2.0, so it was a little nerve racking letting them review our exposition of their work. However, it was also vital because they provided extremely c omprehens i ve tec hni c al and c onc eptual c ommentary that dramati c all y i mproved the quali ty of the end result.

O ur user reviewers, William Bartholomew, Ron Green, Kym Phillpotts, and Fumiaki Yoshimatsu:

No technology book can be released without reviews from people who will actually use the

technology and will lean on our book to learn about it. From this perspective, these guys provided valuable insight that nicely juxtaposed the more technical focus provided by the Microsofties.

Bets y Hardi nger, Grammar Guru Extraordi nai re: Bets y, as C hri s li kes to c al l her, i s a grammar geek. She loves what she does. She's incredible at what she does. She's funny. She puts Strunk and White to shame.

A nd, last but not least, A ddison-Wesley: This is my first experience with a technical book

publisher, and it was a great one. The editors pretty much let us tell the story the way we wanted, always making sure we had what we needed and never pressuring us. Thanks!

Chris's

Acknowledgments

A lthough this book is dedicated to my family, I'd also like to acknowledge them here. I work

from my home, and in completing the book I often had to spend a great deal of extra time to get

the thing out the door. My wife, Melissa, is always enormously understanding when I have a deadline and gives me the space I need to meet it. A lso, I tend to leave my office door open because I like my family, and often my boys, John and Tom, will come in to talk to me about their day. Even though they're only eleven and ten, respectively, they're uncharacteristically understanding when it comes to letting me focus on my work for "just another five minutes" (although woe is me if I overpromise and underdeliver to those two, I'll tell you).

A lthough my family gave me the space to write, this book would not be what it is without the

efforts of my coauthor. Michael dedicated most of two years to this book. Michael's job was primarily to update the chapters based on the additions and changes in Windows Forms 2.0, but he did far more than that. His efforts in re- evaluating each and every part of the story and his willingness to try new ways to present information produced a far better book than the first edition. You should keep an eye out for Michael's future writings. He's definitely one of the good ones.

I also need to give special thanks to Mark Boulter for having a positive influence both on the Windows Forms technology and on my understanding of it, and also for writing our foreword. He doesn't consider himself a writer, so I literally had to call him and beg for his participation after he toldme "no," but I couldn't imagine anyone else I'd want to do it.

Special attention needs to be paid to any book's reviewers. Without the reviewers, authors might think that when they've written prose that covers a topic, they're actually finished. O h,

hated reviews, which correct this assumption, and sweet reviewers, who make sure our readers aren't tortured with inaccurate or unreadable prose and uncompiling code. O ur grand inquisitor was Christophe Nasarre, who flayed us so thoroughly in our first round of reviews that we asked him to be the sole reviewer in the second round. Christophe is such a wonderful reviewer that he's always busy with reviews, but he was able to squeeze us into an extremely short period while still finding things I'm embarrassed to have written in the first place. Thanks, Christophe! T hi s book i s i mmeas urabl y better bec aus e of your efforts .

We also had a dedicated team of reviewers from outside Microsoft, including Ryan Dorrell, Kym Phillpotts, Fumiaki Yoshimatsu, Ron Green, and William Bartholomew. External reviewers are particularly important because they're not steeped in the internal history of Windows Forms, and they represent our target audience. Thanks, guys!

O n the other hand, this book represents not only Mike's and my work with Windows Forms, but also a large number of Microsoft employees who took the time to review our chapters in their areas of expertise and make sure we weren't missing the important things. This group includes Joe Stegman, Steve Lasker, A ndrew Coates, Chris Meyer, Elizabeth Maher, David Guyer, Jessica Fosler, Sameer Bhangar, Felix Cheung, Mark Rideout, Shreeman Dash, Shawn Farkas, Erick Ellis, Mike Harsh, Jamie Cool, Zach Kramer, and Barry Briggs. O f special note are Steve Lasker, who gave us especially deep feedback on the data binding chapters on very short notice, and Jessica Fosler, who was our final authority on a huge range of topics. Michael and I tried very hard to make sure that we didn't slaughter the story of your technology; thanks for all the details we couldn't have found any other way.

I'd like to thank MSDN Magazine, MSDN Online, and Windows Developer magazine for allowing us to reuse material from articles that they originally published (as listed in the Bibliography). I'd also like to thank the readers of the first edition of this book, whose feedback on the initial pieces and the first edition helped shape the final version of this content, as well as inspired me to dig ever deeper.

Last but not least, I'd like to thank the fine folks at A ddison-Wesley. In increasingly tight times, they still manage to provide me an environment where I can write what I think best. Special thanks go to Betsy Hardinger: copy editor, frustrated fiction author, kindred spirit, and hyphen mentor. In addition to turning my prose into English, she also managed to catch technical inconsistencies that hard-core developers missed. Thanks, Betsy!

These folks, along with a bunch I'm sure I've missed, have helped shape everything good that comes through in this book. The errors that remain are our own.

Chris Sells

sellsbrother

s.com

Michael

Weinhardt

mikedub.net

in this book. The errors that remain are our own. Chris Sells sellsbrother s.com Michael Weinhardt
in this book. The errors that remain are our own. Chris Sells sellsbrother s.com Michael Weinhardt
1. Hello, Windows Forms A s easy to use as Windows Forms is, the sheer

1. Hello, Windows Forms

A s easy to use as Windows Forms is, the sheer amount of functionality it provides can make it intimidating; especially when combined with the huge number of features in V isual Studio 2005 (V S05) solely for the purpose of building Windows Forms code. This chapter takes a quick look at Windows Forms, including forms, controls, application settings, resources, dialogs, drawing, printing, data binding, threading, and even deployment over the web. We also look at how the V S05 integrated development environment (IDE) facilitates Windows Forms development. The remaining chapters will stuff you full, providing the sumptuous details of these topics, but in this chapter, you'll get your first taste.

you full, providing the sumptuous details of these topics, but in this chapter, you'll get your
you full, providing the sumptuous details of these topics, but in this chapter, you'll get your
Windows Forms from Scratch A typical Windows Forms application has at least one form. Without

Windows Forms from Scratch

A typical Windows Forms application has at least one form. Without the form, it's just an

"application," which is pretty boring. A form is simply a window, the unit of the Microsoft user interface we've seen since Windows 1.0.

O ne form in a Windows Forms application is typically the main form, meaning that it is either

the parent or the owner of all other forms that may be shown during the lifetime of the application. [1] It's where the main menu is shown, along with the tool strip, status strip, and so on. Typically, the main form also governs the lifetime of a Windows Forms application; generally when an application starts, the main form is opened, and when the main form is closed, the application exits.

[1] The distinction between a f orm's "parent" and its "owner" is covered in detail in Chapter2: Forms.

The main form of an application can be a simple message box, a dialog, a Single Document Interface (SDI) window, a Multiple Document Interface (MDI) window, or something more complicated (such as the forms you're used to seeing in applications like V S05). These latter forms may include multiple child windows, tool windows, and floating tool strips.

If your application is simple, you can implement it using the staple of any windowing system, the

lowly message box:

class MyFirstA pp { static void Main() { System.Windows.Forms.MessageBox.Show("Hello, Windows Forms!");

}

}

If

you're new to C#, Main is the entry point for any C# application. [2] The Main method must

be a member of a class, and hence the need for MyFirstA pp. However, the .NET runtime doesn't create an instance of the MyFirstA pp class when our code is loaded and executed, so our Main method must be marked static. In this way, you mark a method as available without requiring the instantiation of the type that exposes it.

[2] The entry point is the method that the Common Language Runtime (CLR) calls when an application is launched. For details, ref er to Essential .NET (Addison-Wesley, 2003), by Don Box, with Chris Sells.

The single line of real code in our first Windows Forms application calls the static Show method

of the MessageBox class contained within the System.Windows.Forms namespace. Namespaces are used extensively in the .NET Framework Class Libraries (.NET Framework) to separate types such as classes, structures, and enumerations into logical groupings. This separation is necessary when you have thousands of Microsoft employees working on the .NET Framework, hundreds of third parti es extendi ng i t, and mil li ons of programmers tryi ng to l earn i t. Wi thout names pac es , you would need all kinds of wacky conventions to keep things uniquely named (as demonstrated by the existing Win32 API).

However, as necessary as namespaces are, they require a little too much typing for me, so I rec ommend the C # us i ng s tatement:

using System.Windows.Forms; // For MessageBox

class

MyFirstAp

p {

static

void

Main() { MessageBox.Show("Hello, Windows Forms!");

}

}

When the compiler sees that the MessageBox class is being used, it first looks in the global namespace, which is where all types end up that aren't contained by a namespace (for example, the MyFirstA pp class is in the global namespace). If the compiler can't find the type in the global namespace, it looks at all the namespaces currently being used; in this case, System.Windows.Forms. If the compiler finds a type name being used that exists in two or more namespaces, it produces an error and we're forced to go back to the long notation. In practice, this is rare enough to make the short notation predominant when you type code by hand.

However, even though the MessageBox class is enormously handy for showing your users simple string information it's hard to build a real application with MessageBox. For most things, you need an instance of the Form class, located in System.Windows.Forms:

using System.Windows.For ms; // For Form

class

MyFirstAp

p {

static

void

Main() { Form form = new Form(); form.Show(); / / Not what you want to do

}

}

A lthough this code shows the form, you'll have to be quick to see it because the Show method displays the form modelessly. If you're not steeped in user interface lore, a modeless form is one that's displayed while allowing other activities (called modes) to take place. So, control is returned to the Mai n method i mmedi atel y after Show puts our new form on the sc reen, whi c h promptly returns and exits the process, taking our nascent form with it. To show a form modally (that is, to not return control to the Main function until the form has closed) you could call the ShowDialog method:

using

System.Windows.Form

s;

class

MyFirstAp

p {

static

void

Main() { Form form = new Form();

form.ShowDialog(); // Still not what you want to do

}

}

This code would show a blank form and wait for the user to close it before returning control to the Main method, but it's not the code you generally write. Instead, to make it accessible from other parts of your application, you designate one form as the main form. To do this, pass the main form as an argument to the A pplication object's static Run method, which also resides in the System.Windows.Forms namespace:

using System.Windows.Forms; // For Form, Application

class

MyFirstAp

p {

static

void

Main() { Form form = new Form(); Application.Run(form); // This is what you want to do

}

}

The Run method shows the main form. When the form is closed, Run returns, letting our Main

method exit and close the process. To see this in action, you can compile your first Windows Forms appli c ati on us i ng the foll owi ng c ommand: [3]

[3] To get a command prompt with the proper PATH environment variable set to access the .NET command line tools, click on Start | Programs | Microsof t Visual Studio 2005 | Visual Studio Tools, and then Visual Studio 2005 Command Prompt. If you don't have VS05 installed, you can set up the PATH using the corvars.bat batch file in your FrameworkSDK\Bin directory.

C:\> csc.exe /t:winexe /r:System.Windows.Forms.dll MyFirstApp.cs

T he csc .exe c ommand i nvokes the c ompil er on our s ourc e fil e, as ki ng i t to produc e a Wi ndows

application via the /t flag (where the "t" stands for "target"), pulling in the System.Windows.Forms.dll library using the /r flag (where the "r" stands for "reference"). [4]

[4] csc.exe is the command line compiler f or C#, and it is located in your c:\Windows\Microsof t.NET\Framework\v2.0.50727 f older.

The job of the compiler is to pull together the various source code files into a .NET assembly. A n assembly is a collection of .NET types, code, or resources (or all three). A n assembly can be either an application, in which case it has an .exe extension, or a library, in which case it has a .dll extension. The only real difference between assembly types is whether the assembly has an entry point that can be called by Windows when the assembly is launched (.exe files do, and .dll files do not).

Now that the compiler has produced MyFirstA pp.exe, you can execute it and see an application so boring, it's not even worth a screen shot. When you close the form, MyFirstA pp.exe exits, ending your first Windows Forms experience.

To spice things up a bit, we can set a property on our new form before showing it:

class MyFirstAp p { static void Main() { Form form = new Form(); form.Text = "Hello, Windows Forms!"; Application.Run(fo rm);

}

}

Like most classes in the .NET Framework, Form has several properties to access, methods to call, and events to handle. In this case, we've set the Text property, which sets a form's caption bar text. We could do the same thing to set other properties on the form, showing it when we were finished, but that's not the way we generally do things in Windows Forms. Instead, each custom form is a class that derives from Form and initializes its own properties:

class

MyFirstForm

: Form {

public

MyFirstForm

() { this.Text = "Hello, Windows Forms!";

}

}

class MyFirstAp p { static void Main() { Form form = new MyFirstForm(); Application.Run(f orm);

}

}

Notice that the MyFirstForm class derives from Form and then initializes its own properties in the constructor. This gives us a simpler usage model, as shown in the new Main method, which creates an instance of the MyFirstForm class. You also gain the potential for reuse should MyFirstForm be needed in other parts of your application.

Still, our form is pretty boring. It doesn't even include a way to interact with it except for the system-provided adornments. We can add some interactivity by adding a button:

class

MyFirstForm

: Form {

public

MyFirstForm

() { this.Text = "Hello, Windows

Forms!"; Button button = new Button(); button.Text = "Click Me!"; this.Controls.Add( button);

}

}

A dding a button to the form is a matter of creating a new Button object, setting the properties

that we like, and adding the Button object to the list of controls that

code produces a button on the form that does that nifty 3-D depress thing that buttons do when

you press them, but nothing else interesting happens. That's because we're still not handling the button's Click event, which is fired when the user presses the button:

using System; // For EventArgs

the form manages. This

class MyFirstForm : Form { public MyFirstForm () { this.Text = "Hello, Windows Forms!"; Button button = new Button(); button.Text = "Click Me!"; button.Click += new EventHandler(button_Click); this.Controls.Add(button);

}

void button_Click(object sender, EventArgs e) { MessageBox.Show("That's a strong, confident click you've got ");

}

}

Handling the button's Click event involves two things. The first is creating a handler function with the appropriate signature; we've used the standard naming convention for events (VariableName_EventName) to name this method button_Click. The type signature of the vast majority of .NET events is a method that returns nothing and takes two parameters: an object that represents the sender of the event (our button, in this case) and an instance of either the EventA rgs class or a class that derives from the EventA rgs class.

T he s ec ond t hi ng t hat ' s needed t o s ubsc ri be t o an event i n C # i s s hown by t he us e of t he " +=" operator in the MyFirstForm constructor. This notation means that we'd like to add a function to the list of all the other functions that care about a particular event on a particular object, and that requires an instance of an EventHandler delegate object. A delegate is a class that translates invocations on an event into calls on the methods that have subscribed to the event. [5]

[5] Delegates and events are covered in depth in AppendixC: Delegates and Events.

For this particular event, we have the following delegate and event defined for us in the .NET Framework:

namespace System { delegate void EventHandler(object sender, EventArgs e);

}

namespace System.Windows. Forms { class Button { public event EventHandler Click;

}

}

Notice that the Click event on the Button class stores a reference to an EventHandler delegate. Consequently, to add our own method to the list of subscribers to the button's Click event, we create an instance of the EventHandler delegate. To achieve the same effect with less typing, C# offers a syntactic shortcut that allows you to simply provide the name of the subscribing method:

public MyFirstForm() {

button.Click +=

button_Click;

}

Shortcut or not, it can quickly become tedious to add property settings and event handlers by hand for any nontrivial UI. Luckily, it's also unnecessary, thanks to the Windows Forms A pplication Wizard and the Windows Forms Designer provided by V S05.

unnecessary, thanks to the Windows Forms A pplication Wizard and the Windows Forms Designer provided by
39 / 664
Windows Forms in Visual Studio .NET Most Windows Forms projects start in the New Project

Windows Forms in Visual Studio .NET

Most Windows Forms projects start in the New Project dialog, available via File | New | Project (Ctrl+Shift+N) and shown in Figure 1.1.

Figure 1.1. Windows Forms Projects

[Viewfullsizeimage]

. Figure 1.1. Windows Forms Projects [ Viewfullsizeimage ] To develop an application, you want the

To develop an application, you want the Windows A pplication project template. To develop a library of custom controls or forms for reuse, you want the Windows Control Library project template. When you run the Windows A pplication Wizard, choosing whatever you like for the project name, location, and solution name, click O K and you'll get a blank form in the Windows Forms Designer, as shown in Figure 1.2.

Figure 1.2. A Windows Forms Application Wizard-Generated Blank Form in the Windows Forms Designer

Wizard-Generated Blank Form in the Windows Forms Designer Before we start the control drag-and-drop extravaganza that

Before we start the control drag-and-drop extravaganza that the Windows Forms Designer

enables, let's look at a slightly abbreviated version of the code generated by the Windows Forms A pplication Wizard (available by right-clicking on the design surface and choosing V iew Code or

by pressing F7): [6]

[6] The Windows Forms Designer off ers two f orm views: Code and Designer. F7 toggles between them (although this key board shortcut is merely the VS05 def ault and, like any keystroke, depends on your specif ic settings).

// Program.cs using System.Windows.Form s;

namespace

MySecondApp

{ static

class Program { /// <summary>

// / The main entry point for the application. /// </summar y> [STAThread

]

static void Main() { Application.Enab leVisualStyles(); Application.SetCompatibl

eTextRenderingDefault(fa lse); Application.Run(new

Form1());

}

}

}

// Form1.cs

using

System.Windows.Form

s;

namespace

MySecondApp

{ partial

class Form1 : Form { public Form1() { InitializeCo

mponent()

;

}

}

}

//

Form1.De

signer.cs

namespace

MySecondAp

p {

partial

class

Form1 {

#region Windows Form Designer generated code

}

/// <summary>

// / Required method for Designer support - do not modify

// / the contents of this

/// </summary> void InitializeComponent() { this.components = new System.ComponentModel.Con tainer(); this.AutoScaleMode = AutoScaleMode.Font;

method with the code editor.

this.Text = "Form1";

}

#endregion

}

Most of this code should be familiar, including the using statements at the top, the form class that derives from the Form base class, the static Main function that provides the entry point to the application, and the A pplication.Run method. However, four things differ from what we did ourselves.

First, the Windows Forms Designer has dynamic theme support because of the call to A pplication.EnableV isualStyles, which keeps a UI's appearance consistent with the current Windows theme.

Second, the Windows Forms Designer has also set the default form's A utoScaleMode property to a value of A utoScaleMode.Font, which ensures that the form will automatically retain the correct visual proportions (as discussed in Chapter 4: Layout).

Third, the static Main method is implemented from a static class, Program, which exists in a file, program.cs , that' s s eparate from any of the UI el ement s i n the appli c ati on. Mai n i s augmented wi th the ST A T hread attri bute, whi c h enabl es appropri ate c ommuni c ati on bet ween Wi ndows 20 / 664

Forms and Component O bject Model

Windows Forms functionality, including using the Clipboard, the file dialogs, and drag and drop (shown in A ppendix E: Drag and Drop). Because any serious Windows Forms application likely uses some form of C O M, the Windows Forms Designer tacks this on to protect you from nasty exceptions that wouldotherwise arise.

(C O M) technology. This is required for several types of

Finally, a call to InitializeComponent is added to the form's constructor to set the form's properties instead of doing it in the constructor itself. InitializeComponent gives the Windows Forms Designer a place to put the code to initialize the form and its controls and components as we visually design the form. For example, dragging a button from the Toolbox onto the form's design surface changes the InitializeComponent implementation to the following, in its entirety:

void InitializeComponen t() { this.button1 = new System.Windows.Forms. Button(); this.SuspendLayout();

// // button1 // this.button1.Location = new System.Drawing.Point(205, 75); this.button1.Name =

"button1";

this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex =

0;

this.button1.Text =

"button1";

this.button1.UseVisualStyleBackColor = true; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScal eMode.Font; this.ClientSize = new System.Drawing.Size(292,

266);

this.Controls.Add(this.button1)

;

this.Name

= "Form1";

this.Text =

"Form1";

this.Resume

Layout(false

);

}

Notice again that this code is similar to what we built ourselves, although this time created for us by the Windows Forms Designer. Unfortunately, for this process to work reliably, the Windows Forms Designer must have complete control over the InitializeComponent method. In fact, you can notice from the previous sample that the Wizard-generated InitializeComponent code is wrapped in a region that is collapsed to hide the code by default, and is marked with a telling c omment:

#region Windows Form Designer generated code /// <summary> // / Required method for

Designer support - do not modify

// / the contents

method with the code

editor. /// </summary>

of this

#endregion

To emphasize the need for control, the Windows Forms Designer splits the Form1 class across two filesForm1.cs and Form1.Designer.csusing partial class support in C#.

T he c ode i n I ni ti ali zeC omponent may l ook li ke your favori te programmi ng l anguage, but i t' s actually the serialized form of the object model that the Windows Forms Designer uses to manage the design surface. A lthough you can make minor changes to this code, such as changing the Text property on the new button, major changes are likely to be ignored; or, worse, thrown away. Feel free to experiment to find out how far you can go by modifying this s eri ali zati on format by hand, but don' t be s urpri s ed i f your work i s l os t. I rec ommend putti ng custom form initialization into the form's constructor, after the call to InitializeComponent, giving you confidence that your code will be safe from the Windows Forms Designer.

However, we put up with the transgression of the Windows Forms Designer because of the benefits it provides. For example, instead of writing lines of code to set properties on the form or the controls contained therein, all you have to do is to right-click on the object of interest and choose Properties (or press F4) to bring up the Properties window for the selected object, as shown in Figure 1.3. [7]

[7] Instead of F4, you can press Alt+Enter.

Figure 1.3. Browsing and Editing Properties in the Properties Window

Browsing and Editing Properties in the Properties Window Any properties with nondefault values, as indicated by

Any properties with nondefault values, as indicated by values in boldface in the browser, are written to the InitializeComponent method for you. Similarly, to choose an event to handle for the form, or a control or component hosted on the form, you can press the Events lightning bolt button at the top of the Properties window to open the corresponding list of events (shown in Figure 1.4).

Figure 1.4. Creating Events with the Properties Window

the corresponding list of events (shown in Figure 1.4 ). Figure 1.4. Creating Events with the

You have a few ways to handle an event from the Properties window. O ne way is to find the event you'd like to handle on the object selected (say, Click), type the name of the function you'd like to call when this event is fired (say, button_Click), and press Enter. V S05 takes you to the body of an event handler with that name and the correct signature, all ready for you to implement:

void button_Click(object sender, System.EventArgs e) {

}

A fter you've added a handler to a form, that handler will show up in a drop-down list for other events having the same signature. This technique is handy if you'd like the same event for

multiple objects to be handled by the same method, such as multiple buttons with the same handler. You can use the sender argument to determine which object fired the event:

void button_Click(object sender, System.EventArgs e) { Button button = sender as Button; MessageBox.Show(button. Text + "was clicked");

}

If you'd like each event that you handle for each object to be unique or if you just don't care what the name of the handler is, as is often the case, you can simply double-click on the name of the event in the Properties window; an event handler name is generated for you, based on the name of the control and the name of the event. For example, if you double-clicked on the Load event for the Form1 form, the event handler name would be Form1_Load.

Furthermore, if you want to handle the default event of an object, you can create a handler for it automatically by simply double-clicking on the object itself. This generates an event handler name just as if you'd double-clicked on that event name in the Properties window event list. A n

object's default event is intuitively

For example, I'm sure you won't be surprised to learn that the default event for a button is Click and that the default event for a form is Load. Unfortunately, neither the Windows Forms Designer nor the Properties window gives any indication what the default event is for a particular type, but experimentation should reveal few surprises.

meant to be the most handled event for a particular type.

type, but experimentation should reveal few surprises. meant to be the most handled event for a
type, but experimentation should reveal few surprises. meant to be the most handled event for a
Arranging Controls The beauty of the Windows Forms Designer is that it lets you lay

Arranging Controls

The beauty of the Windows Forms Designer is that it lets you lay out your controls lovingly within your form, making sure everything lines up nicely with the aid of snap lines, as shown in Figure 1.5.

Figure 1.5. Nicely Laid-Out Form at Ideal Size

Figure 1.5 . Figure 1.5. Nicely Laid-Out Form at Ideal Size Snap lines cause controls to

Snap lines cause controls to "snap" to certain positions as they are dragged around the design surface. These alignments are determined by the target control's proximity to other controls and the edges of the form. Controls can also be snapped to both the vertical (left edge) and horizontal (text baseline) edges of text in other controls. Snapping proximity is visually represented as lines on the design surface.

So building the form is a pleasant experience, although what happens by default when the user resizes it at run-time is less so, as shown in Figure 1.6.

Figure 1.6. Nicely Laid-Out Form Resized

in Figure 1.6 . Figure 1.6. Nicely Laid-Out Form Resized The user isn't resizing the form

The user isn't resizing the form to get more gray space but to make the controls bigger so that they will hold more visible data. For that to happen, the controls need to resize to take up the newly available space. You can do this manually by handling the form's Resize event and writing the code. O r you can do it with anchoring.

Anchoring is one of the ways Windows Forms gives you automatic layout control of your forms and their controls. By default, all controls are anchored to the upper left, so that as the form is resized and moved, all controls are kept at their position relative to the upper-left corner of the form. In this case, though, we'd clearly like to have the text box controls widen or narrow as the

form is resized. We implement this by setting each text box's A nchor property from the Properties window, which displays an editor like the one in Figure 1.7.

Figure 1.7. Setting the Anchor Property

one in Figure 1.7 . Figure 1.7. Setting the Anchor Property To change the text boxes

To change the text boxes so that they anchor to the right edge, as well as the default top and left edges, is a matter of clicking on the anchor rectangle at the right and changing the A nchor property to "Top, Left, Right." This causes the text boxes to resize as the form resizes, as shown in Figure 1.8.

Figure 1.8. Anchoring Text Boxes Top, Left, Right and Buttons Bottom, Right

The default anchoring is "Top, Left," but those edges need not be a part of

The default anchoring is "Top, Left," but those edges need not be a part of the anchoring settings at all. For example, notice that Figure 1.8 anchors the O K and Cancel buttons to the bottom right, as is customary in Windows dialogs.

If instead of building a dialog-style form, you'd like to build a window-style form, anchoring is not your best bet. For example, suppose you're building an Explorer- style application: a menu strip and tool strip at the top, a status strip at the bottom, and a tree view and a list view taking up the rest of the space, with a splitter between them. In that kind of application, anchoring won't do. Instead, you want docking.

Docking allows you to "stick" any control on the edge of its container, the way a status strip is stuck to the bottom of a form. By default, most controls have the Dock property set to None. (T he defaul t for the Status St ri p c ont rol i s Bottom.) Y ou c an c hange the Doc k property i n the Properties window by picking a single edge to dock to, or to take up whatever space is left, as shown in Figure 1.9.

Figure 1.9. Setting the Dock Property

shown in Figure 1.9 . Figure 1.9. Setting the Dock Property A s an example of

A s an example of several types of docking, the form in Figure 1.10 shows the Dock properties for a status strip, a tree view, and a list view, the latter two being separated and managed by a SplitContainer control. You can arrange all this without writing a line of code.

Figure 1.10. Docking and Splitting

Snap lines, anchoring, docking, and splitting are not the only ways to arrange controls on

Snap lines, anchoring, docking, and splitting are not the only ways to arrange controls on a form. Windows Forms also lets you group controls and handle custom layout for special situations, such as HTML-like tabular and flow layouts. Layout is covered in Chapter 4: Layout. A lso, Windows Forms supports arranging windows within a parent, which we call MDI, in addition to several other UI models. These techniques are all covered in detail in Chapter 14.

we call MDI, in addition to several other UI models. These techniques are all covered in
we call MDI, in addition to several other UI models. These techniques are all covered in
Controls A fter arranging a group of controls just right, you may find that you

Controls

A fter arranging a group of controls just right, you may find that you need that group elsewhere in your application or even in other applications. In that case, you might consider copying and pasting the controls between forms, making sure that all the settings are maintained.

For a more robust form of reuse, however, you can encapsulate the controls into a user control, which is a container for other controls. A lthough you can add one to a Windows A pplication project, you get one by default when you create a new Windows Control Library project. To add this project to a solution, right-click the solution in Solution Explorer and choose A dd | New Project | Windows Control Library. A lso make sure that you're creating the new project in the same location as your existing solution, because V S05 defaults to placing new projects one folder too far up the hierarchy in most cases. Figure 1.11 shows how to add a new project called MyFirstControlLibrary to an existing solution called MySecondA pp.

Figure 1.11. Adding a New Project to an Existing Solution

[Viewfullsizeimage]

a New Project to an Existing Solution [Viewfullsizeimage] A fter you've created a Control Library project,

A fter you've created a Control Library project, you're presented with a user control in a designer that looks very much like the Windows Forms Designer, as shown in Figure 1.12.

Figure 1.12. UserControl Designer

looks very much like the Windows Forms Designer, as shown in Figure 1.12 . Figure 1.12.

The only real difference is that this designer shows no border or caption, because those features are provided by the form that will host your new control. The code generated by the wizard looks very much like the code generated for a new form except that the base class is UserControl (located in the System.Windows.Forms namespace) instead of Form:

// UserControl1.cs using

System.Windows.Forms

;

namespace

MyFirstControlLibrar y { partial class UserControl1 :

UserControl{ public UserControl1() { InitializeCo mponent();

}

}

}

//

UserControl1.De

signer.cs using System.Window s.Forms;

namespace MyFirstControlLib rary { partial class UserControl1 {

void InitializeComponent() {

}

}

}

In the UserControl Designer, you can drop and arrange any desired controls on the user control, setting their properties and handling events just as on a form. Figure 1.13 shows a sample user control as seen in the UserControl Designer.

Figure 1.13. A User Control Shown in the UserControl Designer

When you're happy with your user control, build the project and select it from the

When you're happy with your user control, build the project and select it from the Toolbox,

where you'll find that V S05 has automatically added it to a new tab

created especially for

your project; in this case, "MyFirstControlLibrary Components." Drag and drop your control onto the forms of your choice, setting properties and handling events via the Properties window just as with any of the built-in components or controls. Figure 1.14 shows the user control from

Figure 1.13 hosted on

a form.

Figure 1.14. Hosting a User Control

1.13 hosted on a form. Figure 1.14. Hosting a User Control User controls aren't the only

User controls aren't the only kind of custom controls. If you're interested in drawing the contents of your controls yourself, scrolling your controls, or getting more details about user controls, see Chapter 10: Controls. If you need to package reusable code that doesn't have a UI of any kind, see Chapter 9: Components. Either way, you can integrate your custom implementations into the design-time environment of V S05 to take advantage of the Properties window, snap lines, and smart tags, as covered in Chapter 11: Design-Time Integration: The Properties Window, and Chapter 12: Design-Time Integration: Designers and Smart Tags.

Integration: The Properties Window, and Chapter 12 : Design-Time Integration: Designers and Smart Tags. 32 /
Integration: The Properties Window, and Chapter 12 : Design-Time Integration: Designers and Smart Tags. 32 /
Application Settings A fter you've assembled your application from the required forms, controls, and components,

Application Settings

A fter you've assembled your application from the required forms, controls, and components,

you build it and deploy it. To run, however, applications need certain information, and that often differs between installations, users, and application sessions. Consequently, you can't compile this information directly into the application assemblies. Instead, the information must reside in

a location independent from those assemblies, from which it is read and to which it is written as needed during execution. To solve this problem, .NET provides a complete infrastructure whose fundamental element is the setting.

.NET considers there to be two types of settings: those for users and those for applications. User settings, such as information you might find in a Tools | O ptions dialog for an application like V S05, change from one application session to the next. Application settings, such as database connection strings, change from one installation to the next. You can add one or more of each type of setting to your application by using the Settings Editor. To open this editor, right-click your project and select Properties | Settings, as shown in Figure 1.15.

Figure 1.15. Configuring Settings

[Viewfullsizeimage]

1.15 . Figure 1.15. Configuring Settings [Viewfullsizeimage] Each setting has a name, a type, a scope,

Each setting has a name, a type, a scope, and a value. The name is the way you refer to the setting; type specifies the type of value it stores; scope determines whether a setting is a user setting or an application setting; and value is the setting's initial value. A ll the settings you create are stored in your project's app.config file, in which they are grouped by scope:

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections>

</configSections>

<userSettings>

<MySecondApp.Pro

perties.Settings> <setting name="WindowLocation" serializeAs="String">

<value>100,

100</value>

</sett

ing>

</MySecondApp.Pr

operties.Settings>

</userS

ettings>

<applicationSettings> <MySecondApp.Pro perties.Settings> <setting name="Pi" serializeAs="String">

<value>3.141592

7</value>

</sett

ing>

</MySecondApp.Pr

operties.Settings>

</applicationSett

ings>

</configuration>

When you build your application, the content and settings stored in app.config are copied into your application's configuration file, which is named ApplicationName.exe.config.

When your app executes, it needs a way to retrieve these values and, if necessary, save new values. To provide a simple way to do this, V S05 generates a special class, Settings, in your project:

namespace MySecondApp.Properti es { internal sealed class Settings :

ApplicationSettingsBase { public static Settings Default { get }

}

{

public Point

Location {

get {

set {

}

}

}

public decimal Pi {

get {

}

}

}

}

This class, generated in the ApplicationName.Properties namespace, exposes each setting as a property that holds a value of the type specified when the setting was added. A lthough you could create an instance of this class manually, you can use the static Default method to take on that burden for you. The Settings class

derives from A pplicationSettingsBase, a .NET class located in the System.Configuration namespace that implements all the support to read and write settings. This support is encapsulated by the generated properties, so all you need to worry about is the Settings class itself. A dditionally, because the properties are strongly typed, you'll receive compile-time errors if you use them incorrectly.

You may have noticed that the user setting is read-write, whereas the application setting is read-only. User settings are read-write to allow users to change values between application sessions. In contrast, application settings are likely to store configuration information; so to prevent developers from writing code that could change them (potentially breaking the application) application settings are generated as read-only properties. The following code shows how you might use both user and application settings at run-time:

/ / Read an

application setting decimal pi = Properties.Settings.Defaul t.Pi;

// Write to an

application setting

/ / NOTE: This won't

compile

Properties.Settings.D

efault.Pi =

3.142;

// Write a user setting Properties.Settings.Default.Wi ndowLocation = this.Location;

When you use the Settings class like this, the settings values are initially retrieved from the application's configuration file and subsequently are operated on in memory. But because user settings need to be persisted across application sessions, all user-scoped property values held by the Settings object should be persisted back to the configuration file if changed. To do this, you call the Save method on the Settings class:

void saveSettingsButton_Click(object sender, EventArgs e) { // Save all user settings Properties.Setting s.Default.Save();

}

Changed user settings are not stored back to an application's configuration file, as you might expect; the only settings stored in an application's configuration file are application settings and default user settings. A ltered user settings are persisted to a file named user.config, which is placed in one of several Windows logo- compliant locations within the file system, depending

on where the application is installed and whether the user is roaming. The path to user.config for a locally installed application executed by a nonroaming user conforms to the following:

%SystemDrive%\Docum ents and Settings\UserName\ Local Settings\Application Data\ProductName\ ApplicationName.exe_Url_UrlHash\AssemblyVersionNumber

Sometimes, users change settings to values they are not happy with and then can't remember what the previous defaults were. Fortunately, the settings infrastructure offers two simple backup options to rollback to the previous settings values. First, you can provide a mechanism for users to revert to the last saved settings by calling the Settings object's Reload method:

void reloadSettingsButton_Click(object sender, EventArgs e) { // Revert to last saved user settings Properties.Settings. Default.Reload();

}

Second, if user settings are damaged beyond recovery, you can allow users to revert to the application's default installed user settings; the default values stored in the application's configuration file. Retrieving them is a matter of calling the Settings object's Reset method:

void resetSettingsButton_Click(object sender, EventArgs e) { // Revert to default installed user settings Properties.Settings .Default.Reset();

}

User settings are managed so that if the user.config file is deleted, the default values for those settings are loaded into the next application session. This is the same as calling the Reset method.

The settings subsystem comes with more exotic capabilities, including versioning support, settings profiles, and even the ability to create custom settings providers, a feature that lets you save user settings to, for example, a web service. A dditionally, you can bind form and control properties directly to settings from the Properties window, a practice that can save a lot of coding effort. To explore these in detail, look at Chapter 15: Settings.

a practice that can save a lot of coding effort. To explore these in detail, look
a practice that can save a lot of coding effort. To explore these in detail, look
Resources A pplication and user settings data is used to control an application's look and

Resources

A pplication and user settings data is used to control an application's look and feel, as well as its behavior, while remaining separate from the code itself. A lternatively, this kind of application and control data can be stored as part of an assembly's resources. A resource is a named piece of data bound into the executable (EXE) or dynamic link library (DLL) at build time. For example, you could set the background image of a form in your application by loading a bitmap from a file:

// ResourcesForm.cs partial class ResourcesForm : Form { public ResourcesForm()

{

InitializeComponent(); this.BackgroundImage = new Bitmap(@"C:\WINDOWS\Web\Wallpaper\Azul.jpg");

}

}

Unfortunately, the problem with this code is that not all installations of Windows have A zul.jpg, and even those that have it may not have it in the same place. Even if you shipped this picture with your application, a space-conscious user might decide to remove it, causing your application to fault. The only safe way to make sure that the picture, or any file, stays with code is to embed it as a resource.

Resources can be conveniently embedded in two ways. First, you can use the Resource Editor, which can be opened by right-clicking on your project in Solution Explorer and choosing Properties | Resources. The Resource Editor provides a simplified UI, shown in Figure 1.16, that allows you to manage resources and, just as important, see what your resources will look like at designtime.

Figure 1.16. The Resource Editor

and, just as important, see what your resources will look like at designtime. Figure 1.16. The

With the Resource Editor, you can add new and existing resources in a variety of ways, including using the drop-down list shown in Figure 1.17, pasting them from the Clipboard, or dragging and dropping onto the Resource Editor itself.

Figure 1.17. Adding a Resource with the Resource Editor

[Viewfullsizeimage]

a Resource with the Resource Editor [ Viewfullsizeimage ] A ll resources added to and managed

A ll resources added to and managed by the Resource Editor are categorized by resource type. You can use the drop-down list shown in Figure 1.18 to navigate between categories.

Figure 1.18. Viewing Resource Categories

[Viewfullsizeimage]

In addition to the categories you would expect to find (strings, images, icons, text files,

In addition to the categories you would expect to find (strings, images, icons, text files, and sound files) there is another category, O ther, for extra resource data such as component- defined serialization of design-time data. Depending on the category, you can even view your resources in one of several ways. For example, you can display image resources using the List, Details, or Thumbnails view.

By default, string resources added with the Resource Editor are embedded in Resources.resx, a resource file located in the Properties folder of a Windows Forms project. O ther resources are copied into a local project folder named "Resources" and linked (rather than embedded) with a file path reference stored in Resources.resx. A s with settings, V S05 exposes your resources as strongly typed properties of the Resources class. Here's the abridged version:

internal class Resources {

internal static Bitmap Azul { get; }

}

A part from the advantage of compile-time type checking, the code you write to use resources is simple:

/ / Load strongly typed image resource this.BackgroundImage

=

Properties.Resources.Az

ul;

If you are currently working on a form, control, or component, you can avoid having to write this code: Set the value of many properties by using the Properties window directly. For

example, to set the background image for a form, you merely press the ellipses ("

in the Properties window next to the BackgroundImage property, opening the Select Resource dialog shown in Figure 1.19.

") button

Figure 1.19. Selecting a Resource for a Form Property

Figure 1.19. Selecting a Resource for a Form Property This dialog allows you to import or

This dialog allows you to import or select a resource from the form itself (if you choose Local Resource) or from your project's Resources.resx file (or any additional .resx files you may have added). This action causes the image to be shown in the Designer and generates the code that loads the resource at run time:

// Form1.cs partial class Form1 : Form { public Form1() { InitializeComponent();

}

}

//Form1.

Designer.

cs partial

class

Form1 {

void InitializeComponen t() {

this.BackgroundImage = Properties.Resources.Azul;

}

}

A s you can see, the generated code is pretty much the same code you'd write yourself.

For more details about resources and their relationship to localization and internationalization, see Chapter 13: Resources.

about resources and their relationship to localization and internationalization, see Chapter 13 : Resources. 32 /
about resources and their relationship to localization and internationalization, see Chapter 13 : Resources. 32 /
Dialogs You've seen how to create and show forms, but you can instead show them

Dialogs

You've seen how to create and show forms, but you can instead show them as dialogs. A

lthough it's not always the case, dialogs are typically modal and exist to take information from a user before a task can be completed; in other words, a dialog is a form that has a "dialog" with the user. For example, we created the O ptions dialog in Figure 1.20 by right-clicking on a project in Solution Explorer and choosing A dd Windows Form. Implementing the form was a

matter of exposing the

form's design surface, and setting the ControlBox property to false so that it looks like a dialog.

favorite color setting as a property, dropping the controls onto the

Figure 1.20. A Dialog

dropping the controls onto the Figure 1.20. A Dialog You can use this form as a

You can use this form as a modal dialog by calling the ShowDialog method:

// OptionsDialog.cs partial class OptionsDialog : Form { public OptionsDialog()

{

InitializeComponent();

}

void optionsToolStripMenuItem_Clic k(object sender, EventArgs e) { OptionsDialog dlg = new

OptionsDialog(); dlg.FavoriteColor = this.BackColor; if( dlg.ShowDialog() == DialogResult.OK ) { this.BackColor

=

dlg.FavoriteColor;

}

}

}

Notice that the custom O ptionsDialog class is instantiated, but before it's shown, the initial color value is passed in via the FavoriteColor property. When the modal ShowDialog method completes, it returns the value of the DialogResult enumeration; in this case, either O K or Cancel. A lthough it's possible to implement the Click events for the O K and Cancel buttons inside the O ptionsDialog class, there's a much easier way to make O K and Cancel act as they should: You set each button's DialogResult property appropriately, and set the O ptionsDialog form's A cceptButton and CancelButton properties to the O K button and the Cancel button, respectively. In addition to closing the dialog and returning the result to the caller of ShowDialog, setting these properties enables the Enter and Esc keys and highlights the O K button as the default button on the form.

You may still feel the need to handle the O K Click event to validate data captured by the dialog. A lthough you can do that, Windows Forms provides built-in support for validation. In conjunction with an ErrorProvider component, you can handle the control's V alidating event and thereby validate the contents of each control when the user moves focus from the control. For example, if we want the user to specify a color with some green in it, we can drop an ErrorProvider component onto the O ptionsDialog form and handle the V alidating event for the Change button whenever it loses focus:

// OptionsDialog.cs partial class OptionsDialog :

Form {

void changeColorButton_Validating(obj ect sender, CancelEventArgs e) { byte greenness = this.changeColorButton.BackColor .G; string err = ""; if( greenness < Color.LightGreen.G ) {

err = "I'm sorry, we were going for leafy,

leafy

e.Cancel = true;

";

}

this.errorProvider.SetError(changeColorButton, err);

}

}

In the V alidating event handler, notice that we set the CancelEventA rgs.Cancel property to true; this cancels the loss of focus from the control that caused the validating event. A lso notice the ErrorProvider.SetError invocation; SetError accepts as arguments the control that is being validated and a string, which is the message displayed by the ErrorProvider. When this string is null, the error provider's error indicator for that control is hidden. When this string

contains something, the error provider shows an icon to the right of the control and provides a tooltip with the error string, as shown in Figure 1.21.

Figure 1.21. ErrorProvider Providing an Error (See Plate 1)

Figure 1.21. ErrorProvider Providing an Error (See Plate 1) The V alidating event handler is called

The V alidating event handler is called whenever focus is moved from a control whose CausesV alidation property is set to true (the default) to another control whose CausesV alidation property is also set to true.

O ne side effect of setting CancelEventA rgs.Cancel to true is that focus is retained on an invalid control until valid data is entered, thereby preventing users from

navigating away from the control. The Form class's A utoV alidate property dictates this

behavior to remain consistent with previous versions of Windows Forms.

default value is EnablePreventFocusChange. If you prefer to let your users navigate away from invalid controls (generally considered better from a user's point of view) you can change A utoV alidate to EnableA llowFocusChange in the Properties window, as shown in Figure 1.22.

A utoV alidate's

Figure 1.22. Setting the AutoValidate Property to Allow Focus to Change from an Invalid Control

Property to Allow Focus to Change from an Invalid Control The host form's A utoV alidate

The host form's A utoV alidate value applies to all controls hosted by the form that perform validation. A utoV alidate and validation are explored further in Chapter 3: Dialogs.

If you do allow free navigation across invalid controls, it means that users can conceivably tab to, or click, a form's A cceptButton without having any valid data on the form. Consequently, you need to write additional code to validate the entire form from the A cceptButton. Fortunately, the Form class exposes the V alidate method for this purpose:

// OptionsDialog.cs partial class OptionsDialog :

Form {

void okButton_Click(object sender, EventArgs e) { // Validate form bool isValid = this.Validate(); / / Don't close form if data is invalid if( !isValid ) this.DialogResult = DialogResult.None;

}

}

The V alidate method fires the V alidating event for each of the controls hosted on a form, harvesting the results along the way. If any of the V alidating event handlers set CancelEventA rgs.Cancel to true, V alidate returns false.

ErrorProvider and the V alidating event give you most of what you need for basic validation, but

more complicated validation scenarios require some custom coding. Chapter 3 explores these. It also discusses the standard Windows Forms dialogs and explains how to support c ommuni c ati on between your modal and model es s di al ogs and other parts of your appli c ati on.

to support c ommuni c ati on between your modal and model es s di al
Drawing A s nifty as all the built-in controls are, and as nicely as you

Drawing

A s nifty as all the built-in controls are, and as nicely as you can arrange them, sometimes you need to take things into your own hands and render the state of your form or control yourself. For example, if you want to compose a fancy A bout dialog, as shown in Figure 1.23, you must handle the form's Paint event and do the drawing yourself.

Figure 1.23. Custom Drawing (See Plate 2)

drawing yourself. Figure 1.23. Custom Drawing (See Plate 2) The following is the Paint event-handling code

The following is the Paint event-handling code to fill the inside of the A bout dialog:

// AboutDial og.cs using System.Dr awing; using System.Drawing.Dra

wing2D;

partial class

AboutDialog : Form

{

void AboutDialog_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.SmoothingMode = Smoothing Mode.AntiAlias;

Rectangle rect =

this.ClientRectan

gle;

rect.Width; int cy = rect.Height;

int cx =

float scale = (float)cy / (float)cx;

LinearGradientBrush brush =

new

LinearGradientBrush(this.ClientRectangle,

Color.

Empt

y,

Color.

Empt

y,

45);

try { ColorBlend blend = new ColorBlend(); blend.Colors = new Color[] { Color.Red, Color.Green, Color.Blue }; blend.Positions = new float[] { 0, .5f, 1 }; brush.InterpolationColo rs = blend; Pen pen = new Pen(brush); try { for( int x = 0; x < cx; x += 7 ) { g.DrawLine(pen, 0, x * scale, cx - x, 0); g.DrawLine(pen, 0, (cx - x) * scale, cx - x, cx * scale); g.DrawLine(pen, cx - x, 0 * scale, cx, (cx - x) * scale); g.DrawLine(pen, cx - x, cx * scale, cx, x * scale);

}

}

finally

{

pen.Di

spose(

);

}

StringFormat format = new StringFormat(); try { format.Alignment =

StringAlignment.Center;

format.LineAlignment

=

}

}

StringAlignment.Center;

string s

graphics cool?"; g.DrawString(s,this.Font, brush,rect,format);

=

"Ain't

}

finally

{

format.

Dispose(

);

}

}

finally

{

brush.D

ispose()

;

}

Notice the use of the Graphics object from the PaintEventA rgs passed to the event handler. This provides an abstraction around the specific device we're drawing

on, which we do with constructs like pens, brushes, shapes, and text. A ll this and more are explored in Chapter 5: Drawing Basics, Chapter 6: Drawing Text, and Chapter 7: A dvanced Drawing.

You may be wondering what the try-finally blocks are for. Because the pen and brush objects hold underlying resources managed by Windows, we're responsible for releasing the resources when we're finished, even in the face of an exception. Like many classes in .NET, the Pen and Brush classes implement the IDisposable interface, which serves as a signal for an object's client to call the IDisposable Dispose method when it's finished with an object. This lets the object know that it's time to clean up any unmanaged resources it's holding, such as a file, a database connection, or a graphics resource.

To simplify things in C#, you can replace the try-finally block with a using block (shown here for the Brush object):

// AboutDial og.cs using System.Dr awing; using System.Drawing.Drawing2D;

partial class AboutDialog : Form {

void AboutDialog_Paint(object sender, PaintEventArgs e) { using( LinearGradientBrush brush =

new

LinearGradientBrush(this.ClientRectangle, Color. Empt y, Color. Empt y, 45) )

{

// Wrap Pen and StringFormat usage in "using" blocks, too

}

}

}

// brush.Dispose called automatically

The C# using block instructs the compiler to wrap the code it contains in a try-finally block and call the IDisposable Dispose method at the end of the block for objects created as part of the us i ng c l aus e. T hi s i s a c onveni ent s hort c ut for C # programmers , a good prac ti c e to get i nto, and something you'll see used extensively in the rest of this book.

, a good prac ti c e to get i nto, and something you'll see used
42 / 664
Printing Printing is just a matter of getting at another Graphics object that models the

Printing

Printing is just a matter of getting at another Graphics object that models the printer. We can do that by using the PrintDocument component and handling the events that it fires when the user requests a document to be printed. For example, we can drag the PrintDocument component from the Toolbox onto our A boutDialog form and use it to implement a Print button:

void

printButton_Click(object sender, EventArgs e) { PrintDialog dlg = new PrintDialog(); dlg.Document = this.printDocument; if( dlg.ShowDialog() == DialogResult.OK )

{

this.printDocumen

t.Print();

}

}

Notice that before we ask the PrintDocument component to print, we use the standard PrintDialog component to ask the user which printer to use. If the user presses the O K button, we ask the document to print. O f course, it can't print on its own. Instead, it fires the PrintPage event, asking us to draw each page:

using

System.Drawing.Pri

nting;

void printDocument_PrintPage(object sender, PrintPageEventArgs e) { Graphics g = e.Graphics; using( Font font = new Font("Lucida Console", 72) ) { g.DrawString("Hello,\nPrinter", font, Brushes.Black, 0, 0);

}

}

If you'd like to print more than one page, set the HasMorePages property of the PrintPageEventA rgs class until all pages have been printed. To be notified at the beginning and

end of each print request as a whole, you handle the BeginPrint and EndPrint events. To change settings (such as margins, paper size, landscape versus portrait mode, and so on) you handle the QueryPageSettings event.

A fter you have the PrintDocument events handled, Windows Forms makes adding print preview as easy as using the PrintPreview dialog:

void printPreviewButton_Click(obj ect sender, EventArgs e) { this.printPreviewDialog.Docu ment = this.printDocument; this.printPreviewDialog.Show Dialog();

}

For more details on printing, read Chapter 8: Printing.

this.printPreviewDialog.Show Dialog(); } For more details on printing, read Chapter 8 : Printing. 44 / 664
Data Binding Dealing with data is one aspect of your application development that may not

Data Binding

Dealing with data is one aspect of your application development that may not require you to write custom code. Data-centric applications are fully supported in Windows Forms, and you can manage data sources completely in V S05's Data Sources window, shown in Figure 1.24.

Figure 1.24. VS05 Data Sources Window

in Figure 1.24 . Figure 1.24. VS05 Data Sources Window You open the Data Sources window

You open the Data Sources window by clicking Data | Show Data Sources (Shift+A lt+D).

From the Data Sources window, you can add a new data source to your project either by clicking the A dd New Data Source link label (if your project has no data sources) or from the tool strip (to add other data sources). Either action opens the Data Source Configuration Wizard, shown in Figure 1.25.

Figure 1.25. Data Source Configuration Wizard

Figure 1.25 . Figure 1.25. Data Source Configuration Wizard The Data Source Configuration Wizard allows us

The Data Source Configuration Wizard allows us to create and configure a data source for tables in a database, objects located in the current assembly, and objects located in another assembly or web service. Figure 1.26 shows the result of creating a data source for the Northwind database's Employees table.

Figure 1.26. Employees Data Source in VS05

A fter you have a data source, you can perform a variety of additional configurations,

A fter you have a data source, you can perform a variety of additional configurations, as covered in Chapter 16: Data Binding Basics. The most interesting feature is that you can create a fully operational data-bound form simply by dragging data-bound controls straight onto the form from the Data Sources window. Figure 1.27 shows the result of dragging the Employees data source onto a form.

Figure 1.27. Result of Dragging a Data Source onto a Form

The data source is represented by two data components: a data set , a DataSet-derived

The data source is represented by two data components: a data set, a DataSet-derived class generated by the Designer to hold Employees data for the Employees table; and a table adapter to shuttle data between the data set's Employees table and the Employees table in the Northwind database. The UI is composed of two controls: a DataGridView to display the data, and a BindingNavigator to provide V C R-style navigation of the data.

Between the data components and the UI controls lies the BindingSource component; BindingSource consumes item or collection types and exposes them as data, which can be associated with controls in a special relationship known as data binding. Data binding a control to a data s ourc e provi des for bi di rec ti onal c ommuni c ati on between the c ontrol and the data source so that when the data is modified in one place, it's propagated to the other. Built on top of this basic concept are many additional levels of data binding support that item or collection types can implement, although it is often difficult and time consuming. However, the BindingSource component's major role is to "upgrade" such types to a satisfactory minimum level of data binding support, which includes currency management, inserts, updates, deletes, and change notification.

Figure 1.28 shows the resulting application executing without a single change to the code generated by the Windows Forms Designer.

Figure 1.28. Full Data Binding Without Code

Forms Designer. Figure 1.28. Full Data Binding Without Code We've scratched only the surface of what

We've scratched only the surface of what can be done with data binding. For more, read Chapter

16: Data Binding Basics, and Chapter 17: A pplied Data Binding.

applications deal with lists of data located in places like databases, other applications deal with document-style data. Such applications have special requirements that are covered in A ppendix F: Document Management.

A lso, while some types of

have special requirements that are covered in A ppendix F : Document Management. A lso, while
48 / 664
Multithreaded User Interfaces Because the Windows Forms Designer provides so much functionality via drag and

Multithreaded User Interfaces

Because the Windows Forms Designer provides so much functionality via drag and drop and the P roperti es wi ndow, i t mi ght be a whil e before you get to the meat of your programmi ng c hores . When you do, though, you're bound to run into a task that takes long enough to annoy your users if you make them wait while it completes; for example, printing, searching, or calculating the last digit of pi.

It's especially annoying if your application freezes while an operation takes place on the UI thread, showing a blank square where the main form used to be and giving your users time to consider your competitors' applications. To build applications that remain responsive in the face of long-running operations, you need to create and manage worker threads from your main appli c ati on (UI ) thread, as wel l as ens ure s afe c ommuni c ati on bet ween the UI threads and worker threads. If the thought of doing this fills you with trepidation, then have no fear:

Windows Forms encapsulates these complexities within a single component, BackgroundWorker, which you can drop onto a form and configure from the Windows Forms Designer.

For example, consider the application in Figure 1.29, which provides the potentially long-running ability to calculate pi to any number of decimal places.

Figure 1.29. Digits of Pi Calculator

of decimal places. Figure 1.29. Digits of Pi Calculator To have the pi calculation execute on

To have the pi calculation execute on a worker thread, simply double-click the BackgroundWorker component. The Windows Forms Designer automatically creates an event handler for BackgroundWorker's default DoWork event:

// AsyncCalcPiForm.cs partial class AsyncCalcPiForm :

Form {

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { / / Pi calculation code

}

}

The job of initiating the long-running operation and having the DoWork code execute is left up to you, although it is simply a case of invoking BackgroundWorker.DoWorkA sync:

// AsyncCalcPiForm.cs partial class AsyncCalcPiForm :

Form {

void calcButton_Click(object sender, EventArgs e) {

// Initiate asynchronous worker thread this.backgroundWorker.Ru nWorkerAsync(digits);

}

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {

}

}

When RunWorkA sync is invoked, BackgroundWorker creates a worker thread from the thread pool, transitions to it, and fires the DoWork event. A ll this is done behind the scenes and, as long as you follow the golden rule, is thread safe. If you need to update controls on the UI thread from a worker thread (for example, to report the progress of a long-running operation) BackgroundWorker provides additional mechanisms for doing so safely, as well as for canceling a long-running operation mid-execution. These details and more are covered in Chapter 18:

Multithreaded User Interfaces.

operation mid-execution. These details and more are covered in Chapter 18 : Multithreaded User Interfaces. 50
operation mid-execution. These details and more are covered in Chapter 18 : Multithreaded User Interfaces. 50
Deployment When you have your application just the way you like it, all arranged and

Deployment

When you have your application just the way you like it, all arranged and responsive and fancy- pants, you'll want to share it. You have several options. You can create an archive of your files and send them as an e-mail to your friends and family, from which they can extract the files into the folder of their choice and run your application. O r if you don't like providing user support because your friends and family inevitably have no idea what they're doing, you can use the V S05 Setup Project template to create a project that produces a Windows Installer (.msi) file containing your application's files. Recipients can use this .msi file to install the application into the desiredfolder.

The problem with both of these techniques is that as soon as you share your application, that's when you find the crushing bug that, when the moon is full and the sun is in the house of O rion, causes bad, bad things to happen. When problems come up, you need to remember who received your application so that you can let them know to install the new version before the existing version formats C: or resets your boss's Minesweeper high scores. O f course, all this explains why your IT department mandates that all internal applications be web applications.

The web application deployment model is so simple, there is no deployment. Instead, whenever users surf to the web application in the morning, they get the version that the IT department uploaded to the server the night before. This deployment model is now provided for Windows Forms applications, using a technology known as ClickO nce.

A t this point, you should stop reading and try the following:

1. Use the New Project dialog to create a new Windows A pplication called ClickO nceFun.

2. In Solution Explorer, right-click the ClickO nceFun project and choose Publish.

3. In the Publish Wizard, click the Finish button.

4. O n the web page that's opened, click the Install ClickO nceFun button.

5. O n the A pplication InstallSecurity Warning dialog, click the Install button.

6. Bask in the glory of using ClickO nce deployment to publish and install a real Windows application over the web, without any setup required.

You've just used the ClickOnce deployment feature of .NET to deploy your Windows Forms application like a web application, except that it's a real Windows application complete with full user control over the frame, the tool strip, the menu strip, the status strip, shortcut keys, and so on. A ny libraries your application requires, such as custom or third-party controls, will be downloaded from the same virtual directory that the application came from. When a ClickO nce- deployed application is downloaded, the .NET Framework's code access security dictates that the permissions of your code are limited according to the zone from which the application is deployed, such as the Internet, an intranet, or a local machine.

When applications require more permission than their zone allows, users have the option either to prevent the application from installing or to authorize permission elevation to allow the application to execute with increased permissions. This is in contrast to classic Windows security, where code is awarded permissions based on who launched the application, an

approach that doesn't work very well when everyone seems to run as A dministrator.

If that isn't enough security for you, ClickO nce-deployed applications are downloaded using a model built on trust certificates to identify application publishers; this model allows users to decide whether they should install an application based on whether they trust the application's publisher. If they trust a dodgy publisher and get burned, they have recourse; because the identity of the publisher is stored in the trust certificates themselves, and because trust certificates are handed out only by authorities certified to do so, such as V eriSign, users can be pretty confident in tracking down the perpetrator of any evil crimes that take place. [8]

[8] You can reach VeriSign at http://www.verisign.com.

O verall, ClickO nce deployment offers a slew of support for a wide variety of deployment scenarios that can be configured from V S05. Further, if your deployment needs aren't supported by V S05, you can use code to leverage the System.Deployment namespace to enable them. For the details, turn to Chapter 19: ClickO nce Deployment.

the System.Deployment namespace to enable them. For the details, turn to Chapter 19 : ClickO nce
the System.Deployment namespace to enable them. For the details, turn to Chapter 19 : ClickO nce
WhereAre We? A s this chapter has shown, Windows Forms provides a great deal of

WhereAre We?

A s this chapter has shown, Windows Forms provides a great deal of functionality. Not only does it give you the basic elements needed to build applications, forms, controls, resources, and dialogs, but it also provides advanced features such as anchoring, docking, user controls, print preview, data binding, and web deployment. Guiding you along the way are a slew of wizards and the Windows Forms Designer, the main vehicle for visually developing the look and feel of your application. Where Windows Forms stops, the rest of the .NET Framework steps in to provide drawing, object serialization, threading, security, and tons of other bits of functionality in thousands of classes and components. O ne book can't cover all of those, but I'll show you what you need to know to write real Windows Forms applications and controls in the rest of this one.

show you what you need to know to write real Windows Forms applications and controls in
show you what you need to know to write real Windows Forms applications and controls in
2. Forms In a technology named Windows Forms, you can expect the form to play

2. Forms

In a technology named Windows Forms, you can expect the form to play a critical role. This chapter explores the basics, including displaying forms, form lifetime, form size and location, nonclient form adornments, menu strips, tool strips, and status strips, as well as advanced topics such as form transparency, nonrectangular forms, and visual inheritance. A nd if that's not enough, Chapter 3: Dialogs is all about using forms as dialogs.

Some of the material in this chapter discusses child controls, but only where those controls are c ommonl y found on forms , parti c ul arl y mai n forms . For a di sc uss i on devoted to Wi ndows Forms controls, see Chapter 10: Controls. Chapter 4: Layout covers arranging controls using the myriad of design-time and run-time features offered by .NET.

4 : Layout covers arranging controls using the myriad of design-time and run-time features offered by
4 : Layout covers arranging controls using the myriad of design-time and run-time features offered by
Showing Forms A ny form (that is, any class that derives from the Form base

Showing Forms

A ny form (that is, any class that derives from the Form base class) can be shown in one of two ways. Here, a form is shown modelessly:

void button_Click(object sender, EventArgs e)

{ AnotherForm form

= new AnotherForm();

form.Show();//Show

formmodelessly

}

Here, a form is shown modally:

void button_Click(object sender, EventArgs e)

{ AnotherForm form

= new AnotherForm();

form.ShowDialog();//

Showformmodally

}

Form.Show s hows the new form model ess l y and returns i mmedi atel y wi thout c reati ng any

relationship between the currently active form and the new form. This

form can be closed, leaving the new form behind. [1] Form.ShowDialog, on the other hand, shows the form modally and does not return control until the created form has been closed, either by using the explicit Close method or by setting the DialogResult property (more on this in Chapter

3).

means that the existing

[1] If the closing f orm is the main f orm, by def ault the other f orms close and the application exits.

Owner and Owned Forms

A s ShowDialog shows the new form, an implicit relationship is established between the currently active form, known as the owner form, and the new form, known as the owned form. This relationship ensures that the owned form is the active form and is always shown on top of the owner form, as illustrated in Figure 2.1.

Figure 2.1. Implicit Owner-Owned Relationship Established by ShowDialog Method

O ne feature of this relationship is that the owned form affects the behavior of

O ne feature of this relationship is that the owned form affects the behavior of its owner form:

The owner form cannot be minimized, maximized, or even moved.that the owned form affects the behavior of its owner form: The ownedformblocks mouse and keyboardinput

The ownedformblocks mouse and keyboardinput to the owner form.owner form cannot be minimized, maximized, or even moved. The owner formis minimized when the ownedformis.

The owner formis minimized when the ownedformis.ownedformblocks mouse and keyboardinput to the owner form. Only the owned formcanbe closed. If both owner

Only the owned formcanbe closed.owner form. The owner formis minimized when the ownedformis. If both owner and owned forms are

If both owner and owned forms are minimized and if the user presses A lt+Tab to switch to the owned form, the owned form is activated.when the ownedformis. Only the owned formcanbe closed. Unlike the ShowDialog method, however, a call to

Unlike the ShowDialog method, however, a call to the Show method does not establish an implicit owner-owned relationship. This means that either form can be the currently active form, as shown in Figure 2.2.

Figure 2.2. No Owner-Owned Relationship Established by Show Method

2.2. No Owner-Owned Relationship Established by Show Method Without an implicit owner-owned relationship, owner and

Without an implicit owner-owned relationship, owner and owned forms alike can be minimized, maximized, or moved. If the user closes any form other than the main form, the most recently active form is reactivated.

A lthough ShowDialog establishes an implicit owner-owned relationship, there is no built-in way for the owned form to call back to or query the form that opened it. In the modeless case, you can set the new form's O wner property to establish the owner-owned relationship:

void button_Click(object sender, EventArgs e) {

OwnedForm form = new OwnedForm(); form.Owner = this; // Establish owner-owned relationship form.Show();

}

this; // Establish owner-owned relationship form.Show(); } A s a shortcut, you could pass the owner

A s a shortcut, you could pass the owner form as an argument to an overload of the Show method, which also takes an IWin32Window parameter: [2]

[2] IWin32Window is implemented by Windows Forms UI objects that expose a Win32 HWND property via the IWin32Window.Handle property.

void button_Click(object sender, EventArgs e)

{ OwnedForm form =

new OwnedForm();

form.Show(this); // Establish owner-owned relationship

}

The modal case is similar in that you can either set the O wner property explicitly or pass the owner form as an argument to the ShowDialog override:

void button_Click(object sender, EventArgs e)

{ OwnedForm form =

new OwnedForm(); // Establish owner- owned relationship

// form.Owner = this; form.ShowDialog(this);

}

A n owner form can also enumerate the list of forms it owns using the O wnedForms collection:

void button_Click(object

sender, EventArgs e)using the O wnedForms collection: void button_Click(object { OwnedForm form = new OwnedForm(); form.Own er =

{ OwnedForm form =

new OwnedForm(); form.Own er = this; form.Sho w();

foreach( Form ownedForm in this.OwnedForms ) {

form = new OwnedForm(); form.Own er = this; form.Sho w(); foreach( Form ownedForm in this.OwnedForms )

MessageBox.Show(ownedForm.Text);

}

}

The behavior of forms in an explicit modal owner-owned form relationship is the same as its implicit modal counterpart, but the modeless owner-owned relationship provides additional behavior in the non-owner-owned modeless case. First, the modeless owned form always appears on top of the owner form, even though either can be active. This is useful when you need to keep a form, such as a floating tool window, on top of other forms within an application. [3] Second, if the user presses A lt+Tab to switch from the owner, the owned forms follow suit. To ensure that the user knows which form is the main form, minimizing the owner hides the task bar buttons for all owned forms, leaving only the owner's task bar button visible.

[3] Keeping a f orm on top of all open f orms f or all applications depends on z-order, discussed later in this chapter.

You may have noticed that in addition to an optional owner, a form can have an optional parent, as exposed via the Parent property (which is almost always set to null). This property is reserved for Multiple Document Interface (MDI) forms, discussed later in this chapter, and controls. For controls, the parent-child relationship dictates clipping (that is, a child's edge is clipped to the edge of the parent, as shown in Figure 2.3).

Figure 2.3. A Child ListBox Control Clipped to the Client Area of Its Parent Form

as shown in Figure 2.3 ). Figure 2.3. A Child ListBox Control Clipped to the Client
FormLifetime A lthough the user can't see a form until either Show or ShowDialog is

FormLifetime

A lthough the user can't see a form until either Show or ShowDialog is called, a form comes into existence as soon as a form object is instantiated. From there, its lifetime is measured by a series of events that you can handle to control, manage, or just be notified as appropriate. Figure 2.4 illustrates the sequence of these events, from form construction to form closure.

Figure 2.4. Form Lifetime Event Sequence

to form closure. Figure 2.4. Form Lifetime Event Sequence We now explore a form's lifetime in

We now explore a form's lifetime in detail.

Form Opening

A new form object begins waking up when its constructor is executed, which in turn calls

InitializeComponent to create and initialize all the child controls. InitializeComponent is Designer-generated, and consequently it's a bad idea to put custom code into it because the Designer is likely to throw it away. However, if you'd like to add other controls or change anything set by the InitializeComponent method, you can do so from the constructor after the call to InitializeComponent:

public

Form1() {

InitializeCo

mponent()

;

/ / Adding a control Button

anotherButton = new Button(); this.Controls.Add(a notherButton);

// Changing a property to something not known at design-time this.Text = DateTime.Now.ToSt ring();

}

When either Form.Show or Form.ShowDialog is called, that's the new form's cue to show itself and all its child controls. To be notified just before this happens, you handle the Load event:

// Form1.cs partial class Form1 : Form {

void Form1_Load(object sender, EventArgs e) { MessageBox.Show('Load ing Form1!');

}

}

//Form1.

Designer.

cs partial

class

Form1 {

void InitializeComponen t() {

this.Load += this.Form1_Load;

}

}

The Load event is useful for doing any final initialization right before a form is shown. A lso, the

Load event is a good place to restore any main form settings that need to be remembered from one application session to the next, such as size and location. [4]

[4] How to save and restore main f orm settings is discussed in Chapter 15: Settings.

When a form is loaded for the first time, it becomes the active form, which is the foreground form that receives keyboardinput. It's at this point that a formfires the

Activated event:

// Form1.cs

partial class Form1

: Form {

void Form1_Activated(object sender, EventArgs e) {

MessageBox.Show("Form1

activated!");

}

}

//Form1.

Designer.

cs partial

class

Form1 {

void InitializeComponen t() {

this.Activated += this.Form1_Activated;

}

}

t() { this.Activated += this.Form1_Activated; } } A fter activation, a form broadcasts that opening has

A fter activation, a form broadcasts that opening has completed by firing the Shown event:

// Form1.cs

partial class Form1

: Form {

void Form1_Shown(object sender, EventArgs e) {

MessageBox.Show("Form1

shown!");

}

}

//Form1.

Designer.