Programming in .net

Document Sample
Programming in .net Powered By Docstoc
					Programming .NET 3.0




                                                                                                                                                   Table of Contents

Preface............................................................................................................................ 1
   Who This Book is For................................................................................................................................................................. 1
   How This Book is Organized...................................................................................................................................................... 1
   What You Need to Use this Book.............................................................................................................................................. 5
   Conventions Used in This Book................................................................................................................................................. 5
   Using Code Examples............................................................................................................................................................... 6
   Comments and Questions......................................................................................................................................................... 6
   Acknowledgements.................................................................................................................................................................... 6



Chapter 1. XAML: A Markup Language For Windows — And More.......................... 7
   1.1. ............................................................................................................................................................................................ 7
   1.2. Simple XAML done simply................................................................................................................................................ 10
   1.3. It's Alive! ( Or how I learned to stop worrying and love animation)................................................................................... 31



Chapter 2. WPF............................................................................................................ 41
   2.1. Starting Simple: Panels..................................................................................................................................................... 41
   2.2. Resources......................................................................................................................................................................... 60
   2.3. Transformations................................................................................................................................................................ 61
   2.4. Animation.......................................................................................................................................................................... 62
   2.5. Data Binding..................................................................................................................................................................... 69



Chapter 3. WPF............................................................................................................ 81
   3.1. Starting Simple: Panels..................................................................................................................................................... 81
   3.2. Resources....................................................................................................................................................................... 100
   3.3. Transformations.............................................................................................................................................................. 101
   3.4. Animation........................................................................................................................................................................ 102
   3.5. Data Binding................................................................................................................................................................... 109




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                         Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                                  User number: 851621 Copyright 2007, Safari Books Online, LLC.
This PDF is exclusively for your use in accordance with the Safari Terms of Service. No part of it may be reproduced or transmitted in any form by any means without the prior
written permission for reprints and excerpts from the publisher. Redistribution or other use that violates the fair use priviledge under U.S. copyright laws (see 17 USC107) or that
otherwise violates the Safari Terms of Service is strictly prohibited.
Programming .NET 3.0                 Page 1                                                                                         Return to Table of Contents




Preface


In 1992 I saw C++ and object oriented programming and turned away from C and procedural
programming and never looked back; it was the right decision. In 2000, I saw C# and .Net,
and turned away from C++ and the MFC and never looked back. It was the right decision.
The advent of .NET 3.0 marks another turning point in how we approach programming for
the Windows Platform. In some ways, it is as big a sea-change; in other ways it represents a
natural evolution from .NET 2.
From one perspective .NET 3.0 is nothing more than a collection of new technologies:
Windows Presentation Foundation (WPF0 for writing Windows applications; Windows
 Copyright Safari Books Online #851621
Communication Foundation (WCF), for creating contract-based web services () and Windows
Work Flow Foundation (WF) for defining work flow in an application (, not mention associated
technologies such as CardSpaces and (arguably) ASP.NET AJAX. Thus, you can expect to see
many books on the market treating each of these technologies individually; what we call
"silo" books.
Our goal is to tell the story of the entirety of .NET 3.0 and to draw all of these technologies
together with common themes, not least of which is that together these technologies foster
and enhance n-tier applications in a way that .NET 2.0 paid lip service to but did not integrate
into its core.
We will focus on demonstrating how to build applications that implement well established
architectural patterns (especially n-tier and Service Oriented Architecture) using .NET 3.0,
and – more, how .NET 3.0 not only facilitates this approach but fosters it. Our emphasis will
be on programming, but our underlying message will be that .NET 3.0 encourages these best
practices as an almost inevitable outcome of the very architecture of the framework itself.


Who This Book is For
This book is for experienced .Net 2.0 programmers who have written Windows and web
applications for the Windows platform and who are at least comfortable comfortable with
C# (or Visual Basic 2005). While Java programmers will have no trouble following this book,
we do assume that you've had at least some experience writing .NET 2.0 programs. If not, we
recommend starting with either Programming C# or Programming Visual Basic 2005, both
available from O'Reilly Media.


How This Book is Organized
Section 1 – Dot Net 3.0 – Enterprise Patterns Made Real


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 2                                                                                         Return to Table of Contents




Preface
You are reading it right now; quick spin around, you'll see yourself. Ahh, not fast enough.
Somehow that never works.

1 Introducting.NET 3.0
This book will take a goal and objective-oriented approach to learning the .Net 3.0 and
technologies and will focus implicitly on a MVC / n-tier and SOA approach to building
applications. Best practices and pattern-based programming will be made explicit from the
very beginning, without letting these architectural design patterns get in the way of straight
forward explanations of the new classes and how to put them to work.
We will urge the developer to stop thinking about "Windows vs. Web" applications, and to
think instead about the problem to be solved, the model or engine that represents the
solution and from there, downward to persistence and upward to presentation.
For presentation there is a spectrum of choices that includes: Windows forms, WPF, WPF/E,
ASP.NET with Ajax, ASP.NET. We will demonstrate all but the first and last (as these are
presumed to be already understood).
The application will interact with users; if that interaction is with many users (e.g., over the
internet) authentication, authorization and personalization become issues. ASP.NET 2.0
offers many new techniques; .NET 3.0 provides CardSpaces, which will be explored.
The engine itself can contain business objects, but can also contain work flow, which we will
demonstrate. Applications interact with other applications on two levels: they may provide
information at the business level through WCF or another machine or application may
provide persistence or data either through ADO.NET or WCF. We will explore the WCF aspects
but not the ADO.NET, as ADO.NET has not (yet) changed.
The overall emphasis of the entire book will be on productivity and telling the evolving story
of .NET 3.0 rather than recreating the API documentation.
We will include a number of sidebars that explain why we have not covered certain aspects
of the design patterns (e.g., persistence is not covered because the technology used
(ADO.NET) is not changed in the current .NET 3.0 release) and other sidebars will relate how,
for example, the "C" (Controller) in "MVC" is expressed through the framework and through
events.

2 Design Patterns and .NET 3.0 (20)
A discussion of the ways in which .NET 3.0 fosters the implementation of architectural
patterns in day-to-day programming. Our thesis is that while we have been paying lip service
to n-tier programming for the past decade, .NET 1.0 and 2.0 did not foster this approach, and
many.NET programs were, inevitably and as a direct result of the framework itself, really 2-
tier at best.

Section 2 – Presentation Options


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 3                                                                                         Return to Table of Contents




3 XAML: A Dessert Topping and a Floor Wax
The single biggest change in the presentation layer is the ability to create desktop based
presentation using a declarative syntax. This chapter will discuss the core XAML syntax.
elements, attributes, attached and binding properties, events and event handlers, layout
positioning, stacks, grids, and other essential elements, switching between XAML, design
and code view, debugging xaml and so forth. Key emphasis on isomorphism between xmal
elements and framework classes.

4 A Richer UI Experience: WPF
Explores the various controls as implemented in XAML as well as the use of styles, triggers,
resources, and 2-D and 3-D fundamentals. We'll review animation and timelines, storyboards
and creating animation procedurally. Also, exploration of WPF enhancements to text
rendering.

5 Building a WPF Biz App (Example Program)
Demonstrate how much richer a desktop application can be built with .NET 3.0 than could
be built in the past.

6 Moving the UI to the Web With Ajax
General introduction and includes rant on the idea that Atlas should be easy and no need to
use JavaScript until and unless you need custom controls. How Atlas is modernizing web
applications for better user experience. Explanation of the script manager. Discusses update
panels and ability to retrieve just those parts of the page that we need. Less flicker, more
responsive, tastes great, less filling.

7 Ajax Example
ListMania – a detailed example of a real-world web-based AJAX-enhanced application.

8 Project: Multiple Presenations
Look at the same model as a WPF project, a WinFroms project, an Ajax project, an ASP.NET
project. An exercise in understanding, viscerally, separation of model from view.

9 Richer Personalization with CardSpaces

Section 3 - Workflow – A Business Layer Enhancement

10 Using Work Flow to Create Applications
Discussion of the use of work flow in human interaction, business processes, software
processes and development etc. Also discussion of various types of work flow with an
emphasis on state machine vs. sequential


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 4                                                                                         Return to Table of Contents




11 Developing A Simple Work Flow Engine
The basic unit of sequence is called an activity and activities themselves are the unit of
encapsulation. There is no language for workflow, and all workflows must be hosted within
an application. Therefore we will create a workflow engine and host it both within a simple
Windows and a simple web application.

12 Project: Tracking the progress of this book
Using workflow, data and smoke and mirrors to track the progress of the writing, editing and
publication of the book you are reading (see recursion).

Section 4 –WCF and Service Oriented Architecture.

13 Service Oriented Architecture – WCF
Defining SOA. What problems does it solve. How does it relate to .NET Applications. Looking
at the service model as a software resource, binding a service for accessing the resource,
using the service, hosting the service in IIS, securing the service and debugging the service.
Describes the ABCs of creating a web service: Access, Binds and Contract. Shows an example

14 Consuming web services
Describe the creation of the .cs and .config files and integrating them into the consuming
application and accessing the methods through the proxy. Shows an example

15 Creating a remote application (binary)
The WCF is designed to replace the .NET 2.0 remoting protocols, as well as ASP.NET web
services, and we will create an application that communicates with a second application
using binary protocols.

16 WCF Security
Microsoft has made a commitment to the emerging W* protocols, arguably the most
important of which sre those for security, so we will demonstrate claims based and roles
based authorization as well as ACLs using WCF.

17 SOA Example

Appendix I – Where to Learn More
To come.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 5                                                                                         Return to Table of Contents




What You Need to Use this Book
To work through the examples in this book you will need a machine running Windows XP
(SP2), Windows Vista or Windows Server 2003 SP1.
Please make sure you also have:

     •   .NET Framework 3.0
     •   Visual Studio 2005 (not the express edition)
     •   Visual Studio 2005 extensions for .NET Framework 3.0 (WCF & WPF), November 2006
         CTP ( or the most current release )


Conventions Used in This Book
The following typographical conventions are used in this book:

Plain text
      Indicates menu titles, menu options, menu buttons, and keyboard accelerators (such as
      Alt and Ctrl).
Italic
      Indicates new terms, URLs, email addresses, filenames, file extensions, pathnames,
      directories, and Unix utilities.
Constant width
      Indicates commands, options, switches, variables, attributes, keys, functions, types,
      classes, namespaces, methods, modules, properties, parameters, values, objects, events,
      event handlers, XML tags, HTML tags, macros, the contents of files, or the output from
      commands.

      Constant width bold

   Shows commands or other text that should be typed literally by the user.
Constant width italic
   Shows text that should be replaced with user-supplied values.



                 NOTE
                 This icon signifies a tip, suggestion, or general note.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 6                                                                                         Return to Table of Contents




                 NOTE
                 This icon indicates a warning or caution.




Using Code Examples
This book is here to help you get your job done. In general, you may use the code in this book
in your programs and documentation. You do not need to contact us for permission unless
you're reproducing a significant portion of the code. For example, writing a program that
uses several chunks of code from this book does not require permission. Selling or
distributing a CD-ROM of examples from O'Reilly books does require permission. Answering
a question by citing this book and quoting example code does not require permission.
Incorporating a significant amount of example code from this book into your product's
documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title,
author, publisher, and ISBN. For example: "Programming .NET 3.0 by Jesse Liberty and Alex
Horovitz. Copyright 2007 O'Reilly Media, Inc., 9780596527563."
If you feel your use of code examples falls outside fair use or the permission given above, feel
free to contact us at permissions@oreilly.com.


Comments and Questions
Please address comments and questions concerning this book to the publisher:

        O'Reilly & Associates, Inc.
        1005 Gravenstein Highway North
        Sebastopol, CA 95472
        (800) 998-9938 (in the United States or Canada)
        (707) 829-0515 (international or local)
        (707) 829-0104 (fax)

For more information about our books, conferences, Resource Centers, and the O'Reilly
Network, see our web site at:

        http://www.oreilly.com (http://www.oreilly.com/)



Acknowledgements
To come



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 7                                                                                         Return to Table of Contents




Chapter 1. XAML: A Markup Language For Windows
                                   — And More.


Until .NET 3, web applications were written with "mark up" languages such as HTML and
Windows applications were not. We may have dragged controls onto forms, but the creation
of the controls and their properties were managed by the development environment or you
instantiated them programmatically at run-time.
.NET 3 changes all that with the introduction of XAML (pronounced ZAMEL to rhyme with
CAMEL). XAML is (almost) an acronym for eXtensible Application Markup Language. There
are two key things to know about XAML:

  1. It is a mark up language for creating Windows Applications like HTML is a markup
     language for creating Web applications and
  2. Every XAML object corresponds exactly to a CLR object; anything you can create
     declaratively in XAML you can create programmatically in C# and vice versa.

The goal of this chapter is to provide an overview of XAML and how it is used in creating the
user experience. By the end of this chapter you should have an appreciation of XAML as a
declarative language, an understanding of the basic elements and attributes that you are
likely to encounter when writing a .NET 3 application, and a fundamental appreciation for
hand-crafting meaningful XAML applications. We will not cover every element in the XAML
vocabulary, but we will cover the entire landscape of XAML, demonstrating all of its
significant capabilities.


       NOTE
       We highly recommend XAML in a Nutshell by Lori A. MacVittie for a complete reference
       on the XAML mark up language.



1.1.



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 8                                                                                         Return to Table of Contents




1.1.1. XAML 101
Historically, developers often had a difficult time translating the ideas of user interface (UI)
designers into something that worked within the confines of a development platform.
Designers, for their part, were often forced to compromise their design to meet the
limitations of software tools. In short, these two worlds design and development did not
share a common border, creating significant frustration. XAML is specifically designed to
provide that common border.


    A declarative programming language describes the goals of your program, as
    opposed to the implementation of achieving that goal. For example HTML is
    declarative because you use it to specify how the page will look, but not how to
    implement achieving that presentation.
    In a declarative language you say "a text box with a 1 pixel border will be drawn
    here" while in an imperative language you specify the algorithm for drawing the
    text box.
    XAML is a declarative language, each element of which corresponds exactly to a
    class in an imperative language (e.g., C#), making it a tremendously powerful and
    flexible mark up language for declaring how Windows pages will appear and
    (ultimately) behave.


1.1.2. Interface vs. Implementation
Declarative languages are typically used to describe the Interface or presentation layer of a
program; that is the part of the program presented to the user and with which the user
interacts.
Programming code (e.g., C#) is typically used to provide the implementation, that is the
behavior of the program.

                                                          Figure 1-1. Interface vs. Implementation




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 9                                                                                         Return to Table of Contents



Consider a watch as shown in Figure 3-1 . The user or designer is most interested in the
interface (Is it easy to tell the time? Are the number clear? Can I distinguish the hour hand
from the minute hand? Are the numbers in the conventional place? What font is used?)
The developer, on the other hand, may be more interested in the implementation: how do I
create a mechanism so that the watch tells the correct time, all the time, while meeting the
other design requirements (cost, size, reliability, etc.)
XAML greatly improves collaboration between designers and developers because it is, as
Microsoft describes it, "toolable" (that is, it can be manipulated by software tools). This helps
foster the separation of the application design from the implementation because it is
inexpensive and easy to build tools targeted at designers and other tools targeted at
programmers, all of which can interact with the same underlying XAML.
For example, in some companies, designers will work with UI tools (such as Microsoft's
Expression Interactive Designer) to create the UI, and then they will generate XAML that
developers will import into code-oriented tools such as Visual Studio.


       NOTE
       So, you might ask, why didn't Microsoft leverage existing markup languages like
       HTML for creating the user interface? The short answer is that HTML simply wasn't
       rich enough to express everything that is required for a Windows application. HTML
       was invented to be a "cut down" and simplified markup language. XAML builds on
       the industry standard XML and is inherently extensible.

With XAML each Window is represented by a panel, each property by an XML element and/
or attribute. All of the information about the window is contained in the XMAL file itself, and
a single XAML file can contain all that the parser needs to know to render the window.
All controls or windows in XAML have a predefined tag and each of these tags has property
values (key value pairs) related to that control or window. For example, the following code
for a Button tag sets a few properties of a button control:

     <Button Width="20" Height="10">OK Button</Button>

Each window will contain XAML elements, nodes, and other components organized
hierarchically. XAML based screens also describe an object model. At runtime the object
model creates the windows and each of the elements and nodes described in the XAML
document are instantiated and the object model is created in memory. This allows for the
programmatic manipulation of the object model, allowing the programmer to add and
remove elements and nodes, changing the page and re-rendering it as it changes.
XAML element names are one to one mappings of CLR object names. The attributes of each
element are similarly isomorphic mappings of the members exposed by the object
referenced in the element name. The net effect is there is a single unified API; XAML objects
are CLR objects, and vice versa.


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 10                                                                                        Return to Table of Contents




1.1.3. Up and running
To follow along with the examples in this chapter you will need a machine running Windows
XP (SP2), Windows Vista or Windows Server 2003 SP1.
Please make sure you also have:

     • .NET Framework 3.0
     • Visual Studio 2005 (not the express edition)
     • Visual Studio 2005 extensions for .NET Framework 3.0 (WCF & WPF), November 2006
       CTP ( or more current release )
     • Microsoft Windows Software Development Kit (SDK)




         NOTE
         It is very important that your .NET framework, SDK and Visual Studio extensions are
         all from the same release. Please check the Microsoft documentation for more
         information to make sure you have the right versions properly loaded.

We'll be using both XAMLPad and Visual Studio in this chapter. XAMLPad is included with
the SDK.


1.2. Simple XAML done simply
Markup languages combine information the UI elements (text, images, etc.) with mark up
information. In HTML you might write the following:

     <b><i>XAML is a markup language</i></b>

This would lead to a web browser displaying that text as follows:
XAML is a markup language
The text is augmented by mark up that indicates that the text should be rendered in bold
italics.
The same combination of UI elements and mark up applies to XAML, making it a a very
convenient way to approach the presentation layer of your Windows application. Consider
this simple XAML example:

     <Label Name="HelloLabel" Content="Hello World" FontFamily="Verdana" FontSize="32" />

The <Label /> tag represents a standard System.Windows.Controls label. As such, you can
expect that through the attributes of the tag, you will have access to all the members exposed
by the Label type, which you can set declaratively (as shown here with the Content,
FontFamily and FontSize attributes) or which you can set programmatically at run time.
Hello World
In general, you will find that XAML is relatively obedient to XML syntax rules.

Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 11                                                                                        Return to Table of Contents




       NOTE
       Be sure to name each element that you create using the ID or Name attribute. This
       will allow you to refer to the element in code. We recommend self-documenting
       naming conventions rather than cryptic names that require comments.

Because XAML is XML your document must be "well formed." While the total set of rules can
be complex[*], the principal things to keep in mind are:
        [*] See http://www.w3.org/TR/REC-xml/ for more information




  1. Element and attribute names need to be cased correctly.
  2. Attribute values but be in quotes
  3. Elements may not overlap (though they may be nested)

XAML elements fall into a limited number of categories: root elements, control elements,
panel elements, shape and geometric elements, and document elements. Taken together
these five categories provide user interface designers with some spectacular opportunities
to create rich user experiences.

1.2.1. Panel Elements
A panel element is a container.. Panels come in several different shapes and sizes and
depending on their features they are useful for containing different types of elements. Panel
elements are there to support the layout and placement of elements on a page.
A Panel element's underlying Panel class enforces a strong content model for child content.
Having a strong content model means that time was taken to identify the appropriate level
of granularity of content chunks and the desired functionality of the chunks that will be
contained. The class structure enforces these decisions.
The Children collection of a Panel element can only consist of UIElement objects. Adding a
child to a Panel implicitly adds that child to the UIElementCollection of the Panel.
Open up XAML pad and type the following (broken) code into the code window (replacing
whatever code was already there)

     <Window
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="My Window" Height="300" Width="300"
         >
         <Grid Name="AGrid" Background="AntiqueWhite">
     </Window>

As you can see in Figure 3-2, the auto parse mode allows you to see syntax errors immediately
as you enter XAML.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 12                                                                                        Return to Table of Contents



                                                     Figure 1-2. XAMLPad shows errors automagically




If an error is encountered, the entire XAML content is displayed in red, and the status
information at the bottom of XamlPad displays the specific syntax error. A hyperlink to the
right of the displayed error allows you to jump to the area of XAML content that contains the
error.
In our broken code example, the Grid start tag on line 6 does not match the end tag of
'Window'. To fix this you can add a close grid tag </Grid> after the grid tag and before the
close window tag </Window>. Having corrected this error, XAML Pad should now look like
Figure 3-3.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 13                                                                                        Return to Table of Contents



                                        Figure 1-3. XAML with no errors displays without the error messages




Now, if you click the refresh button, XAMLPad should instantiate a window labeled "My
Window" with an off white background as in Figure 3-4.

                                                                      Figure 1-4. My Window




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 14                                                                                        Return to Table of Contents




1.2.2. Root Elements
Root elements are special derivations of Panel elements and serves as the fundamental
container for the page. Every page will require exactly one root element. You will notice in
Visual Studio the default root element is the <Grid />, though it is not uncommon for other
panel elements (StackPanel, DockPanel or Canvas as well as Page and Window) to serve as
root elements as well. The root element will need to contain a reference to the namespace
needed by the other elements in the container.
You should be able to type the following code into XAMLPad and get a result similar to the
Hello World text you noted previously.

     <Page
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="Hello" Height="300" Width="300"
         >
        <Grid
        Name="HelloWorldGrid">

               <Label
              Content="Hello World"
              FontFamily="Verdana"
              FontSize="32"
              />

         </Grid>
     </Page>




This time we did not use a Window container but rather a page container. Your XAMLPad
display should automatically have rendered Hello World in 32 point Verdana as shown in
Figure 3-5.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 15                                                                                        Return to Table of Contents



                                                                      Figure 1-5. Hello World




All XML documents expect that the elements contained inside are appropriately referenced.
In our case we do this by declaring the namespace(s) for our controls by way of the page
attribute:

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

In the case where the standard root elements are not working for you, you can always create
custom root elements by creating new classes that inherit from Page or Window and
exposing them as XAML elements. Indeed, for very sophisticated user interactions where the
standard features my not suffice, this is probably the desired course of action.

1.2.3. Control Elements
Control elements are user manipulated objects that help with data or user interactions.
Controls are differentiated by their support of the Content, Header, and Item attributes Using
this distinction we can look at each of the five types of Control elements in some detail.

  1.    Simple controls
  2.    Content controls
  3.    Item controls
  4.    Header items controls
  5.    Header content controls

Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 16                                                                                        Return to Table of Contents




1.2.4. Simple Controls
A simple control does not have content, headers, or items. Controls like images, frames, and
scroll bars all fall into this category. An example of an Image control in a window is shown in
the next snippet

     <Window
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="Image" Height="100" Width="200"
         >
        <Grid Name="StuffToBuy">

             <Image
         Source="http://www.oreilly.com/images/oreilly/add_to_cart.gif"
         Height="33"
         Width="142"
         />

         </Grid>
     </Window>

Running in XAMLPad, you should get something that look like Figure 3-6.

                                                         Figure 1-6. An image embeded in a window




While this is just the display of an image, it is easy to see how you could make this functional
in your application by embedding the image inside a button control like this:

     <Button Height="33" Width="142" Background="Transparent">
        <Image
           Source="http://www.oreilly.com/images/oreilly/add_to_cart.gif"
        />
     </Button>



                                                Figure 1-7. Image control embedded in a button control




Change your code in XAMLPad and hit refresh. You should get a clickable button similar to
Figure 3-7 . Note that it registers clicking action from the mouse by changing the background
color.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 17                                                                                        Return to Table of Contents




1.2.5. Content Controls
Content controls display some sort of content. Content controls fall into two categories:
simple and complex.
Simple content controls have single elements as their content property and include text
boxes, buttons, and labels. Complex content controls can have multiple elements as their
content property. An example of a Complex Content Control is the Panel.
All Content controls have a Content attribute as well as Header or Item attributes.
There are two ways to set the content of the Button control. The first is to place the in the
element,

     <Button Height="30" Width="100">
        Click on Me
     </Button>

Or, you could just as easily use the Content attribute,

     <Button Height="30" Width="100" Content="Click on Me" />

You can also embed controls inside the open and close element tag

     <Button Height="30" Width="150" Background="Transparent">
        <TextBox>Click to type in here</TextBox>
     </Button>




       NOTE
       Although, I must confess, I do not know why from a design point of view you would
       ever want a text box inside a button.

Complex content controls can have multiple elements as their content property. If we start
with a DockPanel and add an image and our crazy Button with TextBox we'll wind up with
code like this:

     <Window
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="Image" Height="100" Width="400"
         >
        <Grid Name="StuffToBuy">
        <DockPanel>
        <Image Source="http://www.oreilly.com/images/oreilly/add_to_cart.gif"
     Height="33" Width="142" />
     <Button Height="30" Width="150" Background="Transparent">
        <TextBox>Click to type in here</TextBox>
     </Button>
         </DockPanel>
         </Grid>
     </Window>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 18                                                                                        Return to Table of Contents




       NOTE
       The job of the DockPanel is to render the elements in the order in which they are
       declared, from left to right. (You may use attributes of the DockPanel to alter the
       relative position of the child elements.)

The result is shown in Figure 3-8.

                                                 Figure 1-8. Complex content control using a DockPanel




Now change the DockPanel to a StackPanel and the height and width of the Window to 120h
x 170w and note the difference in how the User Interface is rendered. While the DockPanel
by default orients its child objects horizontally, the StackPanel by default orients its children
vertically, as shown in Figure 3-9

                                                 Figure 1-9. Complex content control using a StackPanel




1.2.6. Item Controls
Item controls have children, including controls with collections. Header item controls have
no Content attribute but they do have Header and Item attributes. As an example, a Menu
is an Item control and a collection of MenuItem(s). MenuItem(s) are Header item conrols, as
shown in the following example,

     <Window
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          Title="Hello and Goodbye" Height="300" Width="300"
          >
        <StackPanel
        Name="HelloWorldGrid"
        Background="AntiqueWhite"
        >
          <Menu
            Height="21" Margin="0,0,0,0">
        <MenuItem Header="Say Hello">
            <MenuItem Header="Hello Jesse" />
            <MenuItem Header="Hello Alex" />
            </MenuItem>



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 19                                                                                        Return to Table of Contents



        <MenuItem Header="Say Goodbye">
           <MenuItem Header="Goodbye Jesse" />
           <MenuItem Header="Goodbye Alex" />
           </MenuItem>
        </Menu>
            <Label
                  Content="Hello Goodbye"
                  FontFamily="Verdana"
                  FontSize="32"
               />
         </StackPanel>
     </Window>

As you can see when you launch this code from XAMLPad you get a window that looks like
Figure 3-10. You can see how the Menu control is exposing it's list of MenuItem(s) and we
have used the implicit Item declaration of MenuItem to expose the children menu items.

     Psudo code to follow:
     <HeaderItemControl Header="Parent">
        <HeaderItemControl Header="Child">
           <HeaderItemControl Header="Grandchild">
              <HeaderItemControl Header="Great Grandchild" />
           </HeaderItemControl>
        </HeaderItemControl>
     </HeaderItemControl>




                                   Figure 1-10. Item Controls and Header Item Controls in the form on a Menu




                        To keep the example focused, the menus drop down but do not change
                        the text




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 20                                                                                        Return to Table of Contents




1.2.7. Header Content Controls
Header content controls have a Header attribute and a Content attribute but no Item
attribute. Similar to the content control, the header content control can only have one child
in its Content attribute. You can set the content implicitly or explicitly:

     <Expander Height="50"
        Name="MyExpander"
        VerticalAlignment="Bottom" >
           When you click on an expander it shows its content.
     </Expander>

Or

     <Expander Height="50"
        Name="MyExpander"
        VerticalAlignment="Bottom"
        Content="When you click on an expander it shows it's content."
     />




1.2.8. Document Elements
Another interesting aspect of XAML is the nature of Document elements. Most of us are
familiar with the first case of the document element FixedDocument which is the traditional
what you see is what you get view of a document that we have all grown to know and love.
The document example coming up is a FlowDocument which provides a richer user
experience.
The flow document provides a much greater level of flexibility in how the document is
rendered. Coupled with a rich set of controls, a flow document can make for a very pleasant
reading experience. Things are going to get a bit recursive here, as we look at how the first
part of this Chapter might look as a flow document.
Here is the complete code for XAML pad, (discussion follows)

     <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Programming .NET 3 | Chapter 3">
     <FlowDocument >
         <Paragraph FontSize="28" Foreground="Red">XAML: A Common Experience for
     Designers and Developers</Paragraph>

        <Paragraph>
         The goal of this chapter is to give you an overview of XAML and how it is used
         in creating the software user experience. By the end of this chapter you should
         have an appreciation of XAML as a declarative language, an understanding of
         the basic elements and attributes that you are likely to encounter when
         writing a .NET 3 application, and a fundamental appreciation for hand crafting
         meaningful XAML applications. The tour will be far from complete but more than
         comprehensive. If you are looking for a really good XAML reference, we would
         highly recommend XAML in a Nutshell by Lori A. MacVittie.
        </Paragraph>
         <Paragraph FontSize="24" Foreground="Red">XAML 101</Paragraph>
         <Paragraph>
            If you've been writing software for a while, then you know often times you
     have a    hard time translating the ideas of User Interface (UI) designers into
     something     that works within the confines of your development environment and



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 21                                                                                        Return to Table of Contents



     platform. If
        you are a designer, then you know that over the years you have had to make
     compromise after compromise with software engineers because the tool that you were
     using to design those rich user experiences was only limited by your imagination
     and ability. In short, these two worlds design and development did not share a
     common border.    Although the divide between these two worlds wasn't very large,
     it was traditionally big enough to create significant frustration.
         </Paragraph>
         <Paragraph>Enter Microsoft's <Bold> Extensible Application Markup
     Language</Bold> (XAML; pronounced "Zammel").</Paragraph>
         <Paragraph>As with so many of the key aspects of .NET 3, XAML is an important
         evolutionary    step in the software development process. For the second time,
         designers and developers are being given a common border to their creative
         worlds. The first time was with another declarative programming language called
         HTML. Now, through XAML, Microsoft is enabling the   type of collaboration that
         has existed with web based applications for some time now.
         </Paragraph>
         <Paragraph>
            In software, especially object oriented software, you're going to hear a lot
         about interface and implementation. Programming languages provide mechanisms
         allow developers to express abstractions. These mechanisms are simply
        a means of grouping implementation details and giving them a common interface.
         </Paragraph>
        <BlockUIContainer>
           <Image Height="184" Width="202" Source="http://developer.apple.com/documentation
     /Cocoa/Conceptual/ObjectiveC/art/watchcalls_35.gif" />
        </BlockUIContainer>
        <Paragraph FontSize="15" Foreground="Blue">Figure 3-1. Interface vs.
     Implementation</Paragraph>
        <Paragraph>Consider a watch [ Figure 3-1 ] from the point of view of a
        developer . You would likely want to concern yourself with what it's made of
        and how it keeps time. Looking at the watch from the point of view of a user
        (or designer) you'd likely only care that it was accurate a keeping time and
        had an easy to understand means of letting you know what time it was. So it
        also goes with good software development, the people who care about the
        interface of a software program (users/designers) and the developers who
        implement that interface aren't always going to care about the same
        things.</Paragraph>

     </FlowDocument>
     </Window>

Click on the refresh button and watch XAMLPad launch a window that can, through the use
of the embedded user flow controls, be made to look like Figure 3-11.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 22                                                                                        Return to Table of Contents



                                                    Figure 1-11. FlowDocument version of this chapter




1.2.9. Over here, no wait I meant over there
One of the major tasks underlying software user experience design is the task of deciding
what goes where and why. Then, after you know what you want to show to a user and why
you want to show it, you need a mechanism of addressing screen size and resolution.
Fortunately for us, XAML addresses both these issues automagically.
XAML is rich with options for grouping page resources conveniently and ensuring that layout
elements are positioned in a manner that facilitates a great user experience. In addition,
XAML elements by default dynamically size to fit their environment. What all this means is
that you'll be able to accommodate the most demanding UI designer's requirements.
In laying out an applications user interface, you will find it convenient to call on two subclasses
of Panel to do your heavy lifting: DockPanel and StackPanel. Their primary function is
relative positioning of elements and they have the added feature of automatically placing
elements in the order of their declaration in the XAML.


       NOTE
       Review: DockPanel is typically used to lay out elements left to right, though attributes
       can be used to dock the elements to any border (left, right, top or bottom) while
       StackPanel is typically used to stack elements one on top of the other.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 23                                                                                        Return to Table of Contents



We're going to use a fictional employee directory to explore how these controls interoperate
with other elements and how they assist in the layout of the user experience.
This is the complete code for our example which we will review in detail as we re-build this
example:

     <Window
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         Title="Employee Directory" Height="480" Width="640"
         >
     <Grid>
        <DockPanel>
        <Border
            DockPanel.Dock="Top"
            BorderBrush="Black"
            BorderThickness="1"
            Height="70">
            <Label
               FontFamily="Verdana"
               FontSize="32"
               HorizontalAlignment="Center"
            >ACME Software Employee Directory</Label>
        </Border>
        <Border
            DockPanel.Dock="Left"
            BorderBrush="Black"
            BorderThickness="1"
            Width="400">
            <StackPanel>
            <Label
               FontFamily="Verdana"
               FontWeight="Bold" FontSize="18"
               HorizontalAlignment="Left"
            >Name: Alex Horovitz</Label>
            <Separator
               Height="5"
               Margin="2,0,40,0"
               Name="s1"
               VerticalAlignment="Bottom"
            />
            <Label
               FontFamily="Verdana"
               FontSize="14"
               HorizontalAlignment="Left"
            >Department: Software Engineering</Label>
            <Label
               FontFamily="Verdana"
               FontSize="14"
               HorizontalAlignment="Left"
            >Location: Acton, MA</Label>
            <Label
               FontFamily="Verdana"
               FontSize="14"
               HorizontalAlignment="Left"
            >Email: alex@alexhorovitz.com</Label>
            <Separator
               Height="5"
               Margin="2,0,40,0"
               Name="s2"
               VerticalAlignment="Bottom"
            />
            <DockPanel>
               <Border
                   DockPanel.Dock="Left"
                   BorderThickness="0"
               >
               <Image
                  Width="80"
                     Source="http://alexhorovitz.com/DotNet3/Nortel_Phone.gif"
               />



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 24                                                                                        Return to Table of Contents



              </Border>
              <Border DockPanel.Dock="Right" BorderThickness="0">
                  <Label
                     FontFamily="Verdana"
                     FontSize="14"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Center"
                  >978 555 1111</Label>
              </Border>
           </DockPanel>
           <DockPanel>
              <Border
                  DockPanel.Dock="Left"
                  BorderThickness="0"
              >
                  <Image Width="80" Source="http://alexhorovitz.com/DotNet3/X-
     Phone_r2_c3.gif"/>
              </Border>
              <Border DockPanel.Dock="Right" BorderThickness="0">
                  <Label FontFamily="Verdana" FontSize="14" HorizontalAlignment="Left"
     VerticalAlignment="Center">978 555 1212</Label>
              </Border>
           </DockPanel>
           <DockPanel>
              <Border DockPanel.Dock="Left" BorderThickness="0">
                  <Image Width="80" Source="http://alexhorovitz.com/DotNet3/fax.gif"/>
              </Border>
              <Border DockPanel.Dock="Right" BorderThickness="0">
                  <Label FontFamily="Verdana" FontSize="14" HorizontalAlignment="Left"
     VerticalAlignment="Center">978 555 1313</Label>
              </Border>
           </DockPanel>
     </StackPanel>
        </Border>
        <Border
           DockPanel.Dock="Right"
           BorderBrush="Black"
           BorderThickness="1"
           Width="240">
           <StackPanel>
           <Image Name="EmployeePicture" Margin="0,10,0,0" Height="200"
     HorizontalAlignment="Center" VerticalAlignment="Top" Width="200" Source="
     http://alexhorovitz.com/DotNet3/Alex_w200.jpg" />
           </StackPanel>
        </Border>
        </DockPanel>

     </Grid>
     </Window>




1.2.10. StackPanel and DockPanel
The first step is to divide the window into 3 content areas using StackPanel and
DockPanel.
Begin by creating Window element in XAMLPad and give it a title of "Employee Directory"

     <Window
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         Title="Employee Directory" Height="480" Width="640"
         >

Insert a <Grid> element along with the <DockPanel> that will contain our three content
areas.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 25                                                                                        Return to Table of Contents




     <Grid>
        <DockPanel>




       NOTE
       The Grid is a souped up form of the StackPanel that allows you to orient your layout
       both horizontally and vertically. Be careful not to confuse this with a datagrid.

Add a series of <Border> elements, one at the top and two below. One on the left and one
on the right.


       NOTE
       The Border element inherits from Decorator and is used to draw a border around an
       element and can also be used to provide a background color for an element.
       Because every child in a DockPanel has a DockPanel.Dock element to represent the
       position of that element in the DockPanel, and because a Border can contain
       elements, we can use the Border element to position label controls within the
       DockPanel. Thus, in the example, we create four Border controls, setting the
       DockPanel.Dock attribute to Top, Left, and Right in turn, and the Labels we contain
       within these Border elements are thus docked within the DockPanel to the Top, Left
       and Right edges of the DockPanel respectively.

<Border>, like all elements within a DockPanel, has a DockPanel.Dock location as an
attribute. Set these to Top, Left, and Right and then add a <Label> element inside each
<Border> to reflect the docking location.

         <Border
            DockPanel.Dock="Top"
            BorderBrush="Black"
            BorderThickness="1"
            Height="70">
            <Label
               FontFamily="Verdana"
               FontSize="32"
               HorizontalAlignment="Center"
            >Top</Label>
         </Border>
         <Border
            DockPanel.Dock="Left"
            BorderBrush="Black"
            BorderThickness="1"
            Width="400">
            <StackPanel>
            <Label
               FontFamily="Verdana"
               FontWeight="Bold" FontSize="18"
               HorizontalAlignment="Center"
            >Left</Label>
            </StackPanel>
         </Border>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 26                                                                                        Return to Table of Contents



         <Border
            DockPanel.Dock="Right"
            BorderBrush="Black"
            BorderThickness="1"
            Width="240">
            <StackPanel>
            <Label
               FontFamily="Verdana"
               FontWeight="Bold" FontSize="18"
               HorizontalAlignment="Center"
            >Right</Label>
            </StackPanel>
         </Border>

Close the opened tags from the start and test the program

         </DockPanel>

     </Grid>
     </Window>

Assuming everything is typed in correctly, you should end up with a window that looks like
the one in Figure 3-12.

                                 Figure 1-12. Figure Three Content Sections using<Border>and<DockPanel>




As you can see, layout in XAML is not very different from layout in HTML. In your mind's eye
it is helpful to think about columns and rows if you are going to code XAML without the aid
of a layout tool.
XAML also combines the x,y layout positioning you get with CSS, so you have the ability to
be very precise in the placement of your elements.



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 27                                                                                        Return to Table of Contents




1.2.10.1. Moving beyond columns and Rows
The first enhancement we'll make is to add in an image that we'll pull from a web site. In part,
this is to demonstrate that .NET 3.0 applications can mix and match resources. You can have
images locally, and/or you can reference images that are remote using a number of protocols.
In this case, we're going to retrieve an image via an http request.
In the 'Right' <DockPanel> and inside the <border> add a <StackPanel> and an image.

         <Border
            DockPanel.Dock="Right"
            BorderBrush="Black"
            BorderThickness="1"
            Width="240">
            <!-- New Content -->
                         <StackPanel>
                         <Image Name="EmployeePicture"
                         Margin="0,10,0,0"
                         Height="200"
                         HorizontalAlignment="Center"
                         VerticalAlignment="Top"
                         Width="200"
                         Source="http://alexhorovitz.com/DotNet3/Alex_w200.jpg"
                         />
                         </StackPanel>
                         <!-- End New Content -->
         </Border>

Note that we set the Margin attribute to make sure we were at least 10 pixels from the top
of the <Border> container and we used the HorizontalAlignment and the
VerticalAlignment attributes to make sure the image was positioned correctly relative
to the container. It is important to understand that all positioning happens relative to the
parent container.
When you run this, you will get a window that looks like Figure 3-13.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 28                                                                                        Return to Table of Contents



                                         Figure 1-13. Employee Directory with picture from a HTTP request.




At this point, we're going to fill out the rest of the <Border> containers using a smattering of
XAML elements and attribute formatting to create a nice user experience.
We'll start with the <Border> that has been attached to the 'Top' of our dock panel. Here
were going to change the existing <Label> and set attributes of the font which will give us
the desired effect on the text of the label.

         <Border
            DockPanel.Dock="Top"
            BorderBrush="Black"
            BorderThickness="1"
            Height="70">
            <Label
                         FontFamily="Verdana"
                         FontSize="32"
                         HorizontalAlignment="Center"
                         >
            ACME Software Employee Directory
            </Label>
         </Border>




When you run this again in XAMLPad you will see a nice banner across the top dock panel
that says in a nice 32 point Verdana font:
ACME Software Employee Directory
Things are a little more complicated in the 'Left' <Border> element as we're going to have
rows and columns of information. We'll use a series of StackPanel, DockPanel, and
Seperator elements to get the desired look and feel.



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 29                                                                                        Return to Table of Contents




At the very top of our <Border> we'll introduce a StackPanel to keep the elements in
this border flowing vertically as opposed to horizontally. We'll also introduce the
<Seperator> element to further visually divide this column.

                          <StackPanel>
              <Label
                 FontFamily="Verdana"
                 FontWeight="Bold" FontSize="18"
                 HorizontalAlignment="Left"
              >Name: Alex Horovitz</Label>
              <Separator
                          Height="5"
                          Margin="2,0,40,0"
                          Name="s1"
                          VerticalAlignment="Bottom"
                          />
              <Label
                 FontFamily="Verdana"
                 FontSize="14"
                 HorizontalAlignment="Left"
              >Department: Software Engineering</Label>
              <Label
                 FontFamily="Verdana"
                 FontSize="14"
                 HorizontalAlignment="Left"
              >Location: Acton, MA</Label>
              <Label
                 FontFamily="Verdana"
                 FontSize="14"
                 HorizontalAlignment="Left"
              >Email: alex@alexhorovitz.com</Label>
              <Separator
                          Height="5"
                          Margin="2,0,40,0"
                          Name="s2"
                          VerticalAlignment="Bottom"
                          />


That section is pretty straight forward. It is easy to extrapolate how you might apply these
elements in any application you might be writing.
We want to place some icons near our information contents and we're going to want to
control the layout at a finer granulatity. In this case we'll introduce a series of
<DockPanel> elements (with Border elements within) inside the current StackPanel,
creating a hierarchy that will provide us with very fine grain control over the layout.

              <DockPanel>
                 <Border
                     DockPanel.Dock="Left"
                     BorderThickness="0"
                 >
                 <Image
                    Width="80"
                       Source="http://alexhorovitz.com/DotNet3/Nortel_Phone.gif"
                 />
                 </Border>
                 <Border DockPanel.Dock="Right" BorderThickness="0">
                     <Label
                        FontFamily="Verdana"
                        FontSize="14"
                        HorizontalAlignment="Left"
                        VerticalAlignment="Center"
                     >978 555 1111</Label>
                 </Border>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 30                                                                                        Return to Table of Contents



              </DockPanel>
              <DockPanel>
                 <Border
                    DockPanel.Dock="Left"
                    BorderThickness="0"
                 >

                 <Image Width="80" Source="http://alexhorovitz.com/DotNet3/X-
     Phone_r2_c3.gif"/>
              </Border>
              <Border DockPanel.Dock="Right" BorderThickness="0">
                 <Label FontFamily="Verdana" FontSize="14" HorizontalAlignment="Left"
     VerticalAlignment="Center">978 555 1212</Label>
              </Border>
           </DockPanel>
           <DockPanel>
              <Border DockPanel.Dock="Left" BorderThickness="0">
                 <Image Width="80" Source="http://alexhorovitz.com/DotNet3/fax.gif"/>
              </Border>
              <Border DockPanel.Dock="Right" BorderThickness="0">
                 <Label FontFamily="Verdana" FontSize="14" HorizontalAlignment="Left"
     VerticalAlignment="Center">978 555 1313</Label>
              </Border>
           </DockPanel>
     </StackPanel>


This code renders in XMLPAD as shown in Figure 3-14.

                                                   Figure 1-14. Full blown employee directory in XAML




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 31                                                                                        Return to Table of Contents




1.3. It's Alive! ( Or how I learned to stop worrying and love animation)
XAML is a very powerful declarative language. As we have seen, it allows you to create layout
and absorb resources both locally and remotely. But one of the truly amazing things about
XAML is the ability to animate your User Experience.
In this next example we're going animate a fairly simple window with an eye on the nuts and
bolts of animation. At first, the XAML code base might seem a little daunting, but hang in
there. You will come to see that most of it has to do with positioning and timing of effects.
When you run this example, you should notice that our user interface elements fade in rather
than appearing abruptly and that the artwork in the product name banner is gently animated.
In the real world, the human eye can process visual information at an astonishing rate but
there are, in fact, limits. Most applications we have traditionally built present all UI elements
simultaneously.
An overloaded eye doesn't know where to look first and the user is temporarily overwhelmed.
By having the UI elements appear in a logical sequence, you guide the user to see the story
of your presentation.

1.3.1. Animation Overview
In the next chapter we'll go into animation in more detail, but to get us started, you'll need
a quick review of animation. There are two techniques used for animation: From/ToBy
animation in which you transition from a starting to an ending value (target values). You can
specify either an end point (from here to there) or a By property (from here, offset by this
much).
The second technique is called keyframe animation which lets you specify more than two
values (more than just a start and stop position) and also lets you specify the interpolation
method (that is, Linear interpolation (animation at a constant rate) Discrete Interpolation
( animation jumping from one value to the next without interpolation) or Splined
Interpolation (the most realistic in which there is both acceleration and deceleration effects).

1.3.2. An Example of KeyFrame Animation
This is the complete code for the animation example which we will review in detail below.

     <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        x:Name="RootWindow"
        Title="Welcome to O'Reilly"
        SizeToContent="WidthAndHeight" ResizeMode="NoResize" >
        <Window.Resources>

              <System:Double x:Key="LargeText">14</System:Double>

              <Storyboard x:Key="OnLoaded">
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear1"
     Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3]
     .(RotateTransform.Angle)" BeginTime="00:00:00" RepeatBehavior="Forever">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 32                                                                                        Return to Table of Contents



     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="360"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear2"
     Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3]
     .(RotateTransform.Angle)" BeginTime="00:00:00" RepeatBehavior="Forever">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="-360"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>

                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear4"
     Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3]
     .(RotateTransform.Angle)" BeginTime="00:00:00" RepeatBehavior="Forever">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="360"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear5"
     Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3]
     .(RotateTransform.Angle)" BeginTime="00:00:00" RepeatBehavior="Forever">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="-360"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear1"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:01"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear2"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00.5000000"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:01.5420000"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear4"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.4580000"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.5000000"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Gear5"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:02"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:03"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:01:18"/>
                 </DoubleAnimationUsingKeyFrames>
                 <!--Text Logo Fade In-->




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 33                                                                                        Return to Table of Contents



                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextLogo_png1"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.5"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.5"/>
                 </DoubleAnimationUsingKeyFrames>

                 <!--Content area (UI) fade in-->
                 <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ContentGrid"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02"/>
                 </DoubleAnimationUsingKeyFrames>

              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="RedGradient"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:01"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="WhiteKnockout"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:00.5830000"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextBlock2"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.3330000"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.3330000"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextBlock3"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.9990000"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.3330000"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="PDFImage"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.6660000"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.3330000"/>
              </DoubleAnimationUsingKeyFrames>
              </Storyboard>
              <Style x:Key="HeaderedContentControlStyle1" TargetType="{x:Type
     HeaderedContentControl}">
                 <Setter Property="Template" Value="{DynamicResource
     HeaderedContentControlControlTemplate1}"/>
              </Style>
              <ControlTemplate x:Key="HeaderedContentControlControlTemplate1"
     TargetType="{x:Type HeaderedContentControl}">
                 <BulletDecorator x:Name="BulletDecorator1"
     RenderTransformOrigin="0.5,0.5">




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 34                                                                                        Return to Table of Contents



                    <BulletDecorator.Bullet>
                       <ContentControl Content="{TemplateBinding Header}" Width="Auto"
     Height="Auto" VerticalAlignment="Center" Margin="0,0,0,0"/>
                    </BulletDecorator.Bullet>
                    <ContentControl Content="{TemplateBinding Content}"
     VerticalAlignment="Stretch" Margin="4,4,4,4" HorizontalAlignment="Left"/>
                 </BulletDecorator>
              </ControlTemplate>

        </Window.Resources>
        <Window.Triggers>
           <EventTrigger RoutedEvent="FrameworkElement.Loaded">
              <EventTrigger.Actions>
                  <BeginStoryboard x:Name="_OnLoaded" Storyboard="{DynamicResource
     OnLoaded}"/>
              </EventTrigger.Actions>
           </EventTrigger>
        </Window.Triggers>
        <Grid x:Name="DocumentRoot" Width="640" Height="480">
           <Grid.ColumnDefinitions>
              <ColumnDefinition/>
           </Grid.ColumnDefinitions>
           <Grid.RowDefinitions>
              <RowDefinition Height="*"/>
           </Grid.RowDefinitions>

           <Rectangle Fill="#FFFFFFFF" StrokeMiterLimit="2"
     x:Name="GearBackgroundRectangle" RenderTransformOrigin="0.5,0.5"
     HorizontalAlignment="Stretch" VerticalAlignment="Top" Width="Auto" Height="175"
     Margin="0,0,0,0" Opacity="1"/>
           <Image IsEnabled="True" HorizontalAlignment="Left" VerticalAlignment="Top"
     RenderTransformOrigin="0.5,0.5" x:Name="Gear1" Margin="0,-100,0,0" Width="192"
     Height="187" Opacity="1">
              <Image.Source>
                 <BitmapImage
     UriSource="http://alexhorovitz.com/DotNet3/rotate_tarsier.png"/>
              </Image.Source>
              <Image.RenderTransform>
                 <TransformGroup>
                    <TranslateTransform X="0" Y="0"/>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>
                    <SkewTransform AngleX="0" AngleY="0"/>
                    <RotateTransform Angle="0"/>
                    <TranslateTransform X="0" Y="0"/>
                    <TranslateTransform X="0" Y="0"/>
                 </TransformGroup>
              </Image.RenderTransform>
           </Image>
           <Image IsEnabled="True" HorizontalAlignment="Left" VerticalAlignment="Top"
     RenderTransformOrigin="0.5,0.5" x:Name="Gear2" Margin="169,-4,0,0" Width="192"
     Height="187" Opacity="1">
              <Image.Source>
                 <BitmapImage
     UriSource="http://alexhorovitz.com/DotNet3/rotate_tarsier.png"/>
              </Image.Source>
              <Image.RenderTransform>
                 <TransformGroup>
                    <TranslateTransform X="0" Y="0"/>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>
                    <SkewTransform AngleX="0" AngleY="0"/>
                    <RotateTransform Angle="0"/>
                    <TranslateTransform X="0" Y="0"/>
                    <TranslateTransform X="0" Y="0"/>
                 </TransformGroup>
              </Image.RenderTransform>
           </Image>
           <Image IsEnabled="True" HorizontalAlignment="Left" VerticalAlignment="Top"
     RenderTransformOrigin="0.5,0.5" x:Name="Gear4" Margin="339,-101,0,0" Width="192"
     Height="187" Opacity="1">
              <Image.Source>
                 <BitmapImage
     UriSource="http://alexhorovitz.com/DotNet3/rotate_tarsier.png"/>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 35                                                                                        Return to Table of Contents



              </Image.Source>
              <Image.RenderTransform>
                 <TransformGroup>
                    <TranslateTransform X="0" Y="0"/>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>
                    <SkewTransform AngleX="0" AngleY="0"/>
                    <RotateTransform Angle="0"/>
                    <TranslateTransform X="0" Y="0"/>
                    <TranslateTransform X="0" Y="0"/>
                 </TransformGroup>
              </Image.RenderTransform>
           </Image>
           <Image IsEnabled="True" HorizontalAlignment="Right" VerticalAlignment="Top"
     RenderTransformOrigin="0.5,0.5" x:Name="Gear5" Margin="0,-4,-60,0" Width="192"
     Height="187" Opacity="1">
              <Image.Source>
                 <BitmapImage
     UriSource="http://alexhorovitz.com/DotNet3/rotate_tarsier.png"/>
              </Image.Source>
              <Image.RenderTransform>
                 <TransformGroup>
                    <TranslateTransform X="0" Y="0"/>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>
                    <SkewTransform AngleX="0" AngleY="0"/>
                    <RotateTransform Angle="0"/>
                    <TranslateTransform X="0" Y="0"/>
                    <TranslateTransform X="0" Y="0"/>
                 </TransformGroup>
              </Image.RenderTransform>
           </Image>
           <Rectangle StrokeMiterLimit="2" x:Name="WhiteKnockout"
     RenderTransformOrigin="0.5,0.5" Margin="0,176,0,0" HorizontalAlignment="Stretch"
     VerticalAlignment="Stretch" Width="Auto" Height="Auto" Opacity="1"
     Fill="#FFFFFFFF"/>
           <Rectangle Stroke="{x:Null}" StrokeMiterLimit="2" x:Name="RedGradient"
     Margin="0,90,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Top"
     Width="Auto" Height="90" Opacity="1">
              <Rectangle.Fill>
              <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                 <LinearGradientBrush.GradientStops>
                    <GradientStopCollection>
                        <GradientStop Color="#FF0000" Offset="0"/>
                        <GradientStop Color="sc#1, 1, 1, 0.768538356"
     Offset="0.10256410256410256"/>
                        <GradientStop Color="#FF0000" Offset="0.60897435897435892"/>
                        <GradientStop Color="#FF0000" Offset="0.79487179487179482"/>
                        <GradientStop Color="#FF0000" Offset="1"/>
                        <GradientStop Color="#FF0000" Offset="0.25"/>
                        <GradientStop Color="#FF0000" Offset="0.44230769230769229"/>
                    </GradientStopCollection>
                 </LinearGradientBrush.GradientStops>
              </LinearGradientBrush>
              </Rectangle.Fill>
              <Rectangle.OpacityMask>
                 <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                    <LinearGradientBrush.GradientStops>
                        <GradientStopCollection>
                           <GradientStop Color="sc#1, 1, 0.987141, 0"
     Offset="0.39743589743589741"/>
                           <GradientStop Color="sc#0.7, 1, 0.658374846, 0" Offset="1"/>
                        </GradientStopCollection>
                    </LinearGradientBrush.GradientStops>
                 </LinearGradientBrush>
              </Rectangle.OpacityMask>
           </Rectangle>

           <Grid x:Name="ContentGrid" Width="640" Height="480"
     RenderTransformOrigin="0.5,0.5" Opacity="1">
              <Grid.RenderTransform>
                 <TransformGroup>
                    <TranslateTransform X="0" Y="0"/>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 36                                                                                        Return to Table of Contents



                         <SkewTransform AngleX="0" AngleY="0"/>
                         <RotateTransform Angle="0"/>
                         <TranslateTransform X="0" Y="0"/>
                         <TranslateTransform X="0" Y="0"/>
                      </TransformGroup>
                   </Grid.RenderTransform>

           </Grid>
           <Image IsEnabled="True" HorizontalAlignment="Left" VerticalAlignment="Top"
     RenderTransformOrigin="0.5,0.5" x:Name="TextLogo_png1" Width="369" Height="69"
     Margin="50,300,0,0" Opacity="1">
               <Image.Source>
                  <BitmapImage
     UriSource="http://www.oreilly.com/images/oreilly/oreilly_large.gif"/>
               </Image.Source>
           </Image>
           <TextBlock x:Name="TextBlock2" Margin="0,185,10,0"
     HorizontalAlignment="Right" VerticalAlignment="Top" Width="290" Height="21"
     Text="Short Cuts" TextAlignment="Right" FontSize="11" Opacity="1"/>
           <TextBlock x:Name="TextBlock3" Margin="0,250,10,0"
     HorizontalAlignment="Right" VerticalAlignment="Top" Width="400" Height="40"
     Text="Getting Started with .NET 3.0" TextAlignment="Left" FontSize="24"
     Opacity="1"/>
           <Image x:Name="PDFImage" IsEnabled="True" HorizontalAlignment="Left"
     VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5"
     Source="http://www.oreilly.com/catalog/covers/059652921X_cat.gif"
     Margin="400,300,10,20" Opacity="1"/>
        </Grid>
     </Window>




1.3.3. The Animation Storyboard
The first part of creating an animated user experience is to decide what will be animated,
how it will be animated, and in what order will the animation occur. The more common name
for this collection of information is a Storyboard.
Just for fun, we're going to mock up a splash page for an O'Reilly book. We'll have some text,
some branding in the form of a red gradient opaque banner, and, what example would be
complete without a hexatarsier [ See Figure 3-15].




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 37                                                                                        Return to Table of Contents



                                                          Figure 1-15. World renowned hexatarsier




In our storyboard we're going to first add the bit of XAML that will help us rotate our friend
the hexatarsier. We'll add a DoubleAnimationUsingKeyFrames object, that is
comprised of two SplineDoubleKeyFrame objects:


     <DoubleAnimationUsingKeyFrames
            Storyboard.TargetName="Gear1"
         Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children
         )[3].(RotateTransform.Angle)" BeginTime="00:00:00" RepeatBehavior="Forever">

         <SplineDoubleKeyFrame
            KeySpline="0.5,0.5,0.5,0.5"
            Value="0"
            KeyTime="00:00:00"
         />

        <SplineDoubleKeyFrame
           KeySpline="0.5,0.5,0.5,0.5"
              Value="360"
              KeyTime="00:01:18"
        />
     </DoubleAnimationUsingKeyFrames>

You will note that the Storyboard.TargetName value ("Gear1") of the
DoubleAnimationUsingKeyFrames object refers to the target of the behavior which
we will see later on as:

     <Image IsEnabled="True" HorizontalAlignment="Left" VerticalAlignment="Top"
     RenderTransformOrigin="0.5,0.5" x:Name="Gear1" Margin="0,-100,0,0" Width="192"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 38                                                                                        Return to Table of Contents



     Height="187" Opacity="1">
        <Image.Source>
          <BitmapImage UriSource="http://alexhorovitz.com/DotNet3/rotate_tarsier.png"/>
        </Image.Source>
        <Image.RenderTransform>
          <TransformGroup>
           <TranslateTransform X="0" Y="0"/>
           <ScaleTransform ScaleX="1" ScaleY="1"/>
           <SkewTransform AngleX="0" AngleY="0"/>
           <RotateTransform Angle="0"/>
           <TranslateTransform X="0" Y="0"/>
           <TranslateTransform X="0" Y="0"/>
           </TransformGroup>
        </Image.RenderTransform>
     </Image>




The KeySpline values of the SplineDoubleKeyFrame objects define quadratic Bezier
curves. The resulting curves specify how an animation is interpolated during a time segment;
that is, the curve represents the rate of change in the animation's target attribute over the
time segment. In our case, we are simply rotating 360 degrees over the course of one minute
eighteen seconds.
We're going to make five animated gears in our story board and label them Gear1 through
Gear5.
We're also going to animate the other aspects of the UI.

              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextLogo_png1"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.5"/>
                    <SplineDoubleKeyFrame
     KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.5"/>
                 </DoubleAnimationUsingKeyFrames>

Content grid fades in using opacity

                           <DoubleAnimationUsingKeyFrames
     Storyboard.TargetName="ContentGrid" Storyboard.TargetProperty="(UIElement.Opacity)"
     BeginTime="00:00:00">
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01"/>
                    <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02"/>
                 </DoubleAnimationUsingKeyFrames>

Same with RedGradient and the WhiteKnockOut from the red gradient box.

              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="RedGradient"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:01"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="WhiteKnockout"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 39                                                                                        Return to Table of Contents



     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:00.5830000"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextBlock2"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.3330000"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.3330000"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TextBlock3"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.9990000"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.3330000"/>
              </DoubleAnimationUsingKeyFrames>
              <DoubleAnimationUsingKeyFrames Storyboard.TargetName="PDFImage"
     Storyboard.TargetProperty="(UIElement.Opacity)" BeginTime="00:00:00">
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:00"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="0"
     KeyTime="00:00:01.6660000"/>
                 <SplineDoubleKeyFrame KeySpline="0.5,0.5,0.5,0.5" Value="1"
     KeyTime="00:00:02.3330000"/>
              </DoubleAnimationUsingKeyFrames>




We create the red gradient box using XAML and color offsets:

           <Rectangle Stroke="{x:Null}" StrokeMiterLimit="2" x:Name="RedGradient"
     Margin="0,90,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Top"
     Width="Auto" Height="90" Opacity="1">
              <Rectangle.Fill>
              <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                 <LinearGradientBrush.GradientStops>
                    <GradientStopCollection>
                        <GradientStop Color="#FF0000" Offset="0"/>
                        <GradientStop Color="sc#1, 1, 1, 0.768538356"
     Offset="0.10256410256410256"/>
                        <GradientStop Color="#FF0000" Offset="0.60897435897435892"/>
                        <GradientStop Color="#FF0000" Offset="0.79487179487179482"/>
                        <GradientStop Color="#FF0000" Offset="1"/>
                        <GradientStop Color="#FF0000" Offset="0.25"/>
                        <GradientStop Color="#FF0000" Offset="0.44230769230769229"/>
                    </GradientStopCollection>
                 </LinearGradientBrush.GradientStops>
              </LinearGradientBrush>
              </Rectangle.Fill>
              <Rectangle.OpacityMask>
                 <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                    <LinearGradientBrush.GradientStops>
                        <GradientStopCollection>
                           <GradientStop Color="sc#1, 1, 0.987141, 0"
     Offset="0.39743589743589741"/>
                           <GradientStop Color="sc#0.7, 1, 0.658374846, 0" Offset="1"/>
                        </GradientStopCollection>
                    </LinearGradientBrush.GradientStops>
                 </LinearGradientBrush>
              </Rectangle.OpacityMask>
           </Rectangle>

By tying these effects to the keyframes, they are produced in sequence, and thus the effect
is not only that the hexatesiers rotate, but equally impressive to the viewer (though more

Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 40                                                                                        Return to Table of Contents



subtle) the entire presentation seems to fade in, each segment appearing in turn as shown
in Figure 3-16 (your book may not show the actual animation depending on how much you
paid for it).

                                                                 Figure 1-16. Animated Images




1.3.4. Hooked Yet?
In street parlance, this is just a "taste" of what can be done with XAML; in the next chapter
we'll delve more deeply into what you can produce with the Windows Presentation
Foundation; the library built by Microsoft on top of XAML and provided as part of .NET 3.
Be prepared, all your existing Windows Applications are about to look very old. I hate when
that happens.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 41                                                                                        Return to Table of Contents




                                                                                                                        Chapter 2. WPF


Every Windows program begins with an "entry point" – and in WPF that entry point is
contained within an instance of the Application class. Unlike Windows Forms, but much like
ASP.NET, WPF applications are explicitly divided between "markup" (XAML) and the "code-
behind" that together correspond to the .NET class libraries.
As you saw in the previous chapters, you can use XAML to create very powerful layouts and
displays, but WPF goes beyond that to use XAML and code-behind to create complete
applications that provide enhanced text, 2-D and 3-D graphics and much more.
The best way to think about it is this: WPF is a framework of classes provided for you by
Microsoft. You implement these classes either programmatically (by instantiating them in
code) or declaratively by using XAML.
In chapter 6 we're going to build a significant WPF business program that uses many features
of the WPF library. To prepare for that, this chapter will build on the previous chapter, and
introduce more of the features of the WPF that you are likely to use in creating your
applications.


2.1. Starting Simple: Panels
Whether you are working in ASP.NET or XAML, one challenge with every markup language
is achieving precise layout of the elements for display. The approach taken for XAML is to
use panels as touched on in the previous chapter.
Perhaps the most flexible panel is the grid, which gives you control of both columns and
rows (not unlike a table in HTML). Copy the code shown in Example 4-1. into XAML Pad and
run it. What you get should look like Figure 4-1 (only colorful).




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 42                                                                                        Return to Table of Contents



Example 2-1. Grid Example


         <Window
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title="Programming .NET 3 | Understanding Grids">
            <Grid>
                 <Grid.RowDefinitions>
                      <RowDefinition/>
                      <RowDefinition/>
                      <RowDefinition/>
                 </Grid.RowDefinitions>
                 <Grid.ColumnDefinitions>
                      <ColumnDefinition/>
                      <ColumnDefinition/>
                      <ColumnDefinition/>
                 </Grid.ColumnDefinitions>

                 <TextBlock TextBlock.FontSize="36" Background="Blue" Grid.Column="0"
         Grid.Row="0" Grid.RowSpan="2">1</TextBlock>
                 <TextBlock TextBlock.FontSize="36" Background="Gold" Grid.Column="1"
         Grid.Row="0" >2</TextBlock>
                 <TextBlock TextBlock.FontSize="36" Background="Crimson" Grid.Column="2"
         Grid.Row="0" >3</TextBlock>
                 <TextBlock TextBlock.FontSize="36" Background="White" Grid.Column="1"
         Grid.Row="1" Grid.ColumnSpan="2">4</TextBlock>
                 <TextBlock TextBlock.FontSize="36" Background="Purple" Grid.Column="0"
         Grid.Row="2" >5</TextBlock>
                 <TextBlock TextBlock.FontSize="36" Background="Green" Grid.Column="1"
         Grid.Row="2" >6</TextBlock>
                 <TextBlock TextBlock.FontSize="36" TextBlock.Foreground="White"
         Background="Black" Grid.Column="2" Grid.Row="2" >7</TextBlock>

                </Grid>

         </Window>



This example starts by declaring a Grid element, and then by declaring a set of three
RowDefinitions (each with no properties) and three ColumnDefinitions, also with no
properties.
Below these row and column definitions, you declare TextBlocks. Examine the first TextBlock.
Its fontsize is set to 36 (this will be used for the numeral), its background color is set (which
is much more effective when you can see the colors!), and then its position in the grid is set
(column and row). Finally, its text is set. Note also that some text blocks include a rowspan
or a colspan attribute.
The first TextBlock will, therefore have a numeral "1" with a font size of 36; a background of
blue; the block will be placed in column 0, row 0 of the grid and will span two rows. All of this
is consistent with what we see in Figure 4-1.
Interestingly the grid itself has no colors; it is the Textblocks that bring the colors and are
placed inside the grid; the grid just supplies the structure.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 43                                                                                        Return to Table of Contents



                                                                     Figure 2-1. A colorful grid




2.1.1. DockPanel
The DockPanel specializes in "docking" its contents to specific edges of the panel, as
illustrated in Example 4-2. . Take special note of the DockPanel declaration (in bold) which
has the attribute LastChildFill="True" – this ensures that the last child of the panel will be
centered as "fill" for the panel.

Example 2-2. A DockPanel


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Layout: DockPanel">

             <DockPanel LastChildFill="True">
             <TextBlock DockPanel.Dock="Top" Background="LightCoral" >I am the
         top...</TextBlock>
             <TextBlock DockPanel.Dock="Bottom" Background="LightCoral" >I am the
         bottom...</TextBlock>
             <TextBlock DockPanel.Dock="Left" VerticalAlignment="Center">I am the
         left...</TextBlock>
             <TextBlock DockPanel.Dock="Right" VerticalAlignment="Center">I am the
         Right...</TextBlock>
             <Button Height="40" Width="200">I am the Fill (or the center)</Button>
             </DockPanel>
         </Window>



As promised, we placed a Button as the final element in the DockPanel, and it was dutifully
centered, as shown in Figure 4-2




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 44                                                                                        Return to Table of Contents



                                         Figure 2-2. A simple DockPanel with top and bottom specified firsts




2.1.1.1. Order of Declaration is important
If we change the dock panel slightly, and declare the left and right text blocks before the top
and bottom text blocks, we change the area devoted to each. You can imagine that by doing
so, the dock panel devotes a full column to each the left and the right, and then allocates to
bottom and top only what remains, thereby foreshortening the area for top and bottom, as
shown in Figure 4-3


       NOTE
       To create this effect, modify the code in Example 4-2. so that the first two text blocks
       swap places with the second two (that is, right and left are declared before top and
       bottom.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 45                                                                                        Return to Table of Contents



                                                       Figure 2-3. DockPanel with left and right first.




If you modify the declaration of the right and left to set the background color

     background="lightblue"

it is easy to see that the area of the right and left column is exactly the area taken away from
the top and bottom. You can almost imagine a full column extending up to the top and down
to the bottom as imagined in Figure 4-4

                                                          Figure 2-4. Dock Panel Imagined columns




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 46                                                                                        Return to Table of Contents




2.1.1.2. DockPanels Are Pervasive
You can see how the DockPanel could be instrumental in many applications; with the left (or
right) column reserved for a menu or site-map, the top reserved for a header or tabs, the
bottom reserved for a status bar and the center holding the presentation of the contents of
the application.

2.1.2. StackPanel
StackPanel can be used alone, or inside other containers. Later we'll use a StackPanel inside
a Button, but for now, we'll show one off inside a DockPanel, as shown in Example 4-3.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 47                                                                                        Return to Table of Contents



Example 2-3. Stack Panel Inside a Dock Panel


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

              Title="Programming .NET 3 | Layout: StackPanel and the FlowDocumentReader">

              <DockPanel LastChildFill="True">

               <TextBlock DockPanel.Dock="Top" Background="White"
         TextBlock.FontFamily="Verdana" TextBlock.FontSize="48" VerticalAlignment="Center">
                   <Image Source="http://www.oreilly.com/images/oreilly/oreilly.gif"
         Width="287" Height="67"/>
               </TextBlock>
               <TextBlock DockPanel.Dock="Bottom" Background="DarkRed" Foreground="White" >
                   © 2006, O'Reilly Media, Inc.
                   All trademarks and registered trademarks appearing on oreilly.com are the
         property of their respective owners.
               </TextBlock>
               <StackPanel DockPanel.Dock="Left" VerticalAlignment="Center" Margin="5">
                    <Image Source="http://www.oreilly.com/catalog/covers/059652921X_cat.gif"
         Height="223" Width="180" />
               </StackPanel>
               <FlowDocumentReader>
                   <FlowDocument>
                      <Paragraph>
                         <Bold></Bold>
                      </Paragraph>
                      <Paragraph>
                         <Paragraph.FontFamily>Verdana</Paragraph.FontFamily>
                         <Paragraph.FontSize>36</Paragraph.FontSize>
                         <Bold>Getting Started with .NET 3.0</Bold>
                      </Paragraph>
                      <Paragraph>
                         <Paragraph.FontFamily>Verdana</Paragraph.FontFamily>
                         <Paragraph.FontSize>18</Paragraph.FontSize>
                         <Bold>Writing Your First .NET 3.0 Application</Bold>
                      </Paragraph>
                      <Paragraph>
                         <Paragraph.FontFamily>Verdana</Paragraph.FontFamily>
                         <Paragraph.FontSize>18</Paragraph.FontSize>
                         By Jesse Liberty and Alex Horovitz<LineBreak />
                         September 2006<LineBreak />
                         Pages: 56 <LineBreak />
                     </Paragraph>
                     <Paragraph>
                        Learn how to create more dynamic user experiences and build secure
         web services using Windows Communication Foundation (WCF) and Windows Presentation
         Foundation (WPF), two of the foundational pillars of .NET 3.0, with this succinct
         and well-written PDF document.
                     </Paragraph>
                     <Paragraph>
                        Co-authored by best-selling author Jesse Liberty, this document gets
         right to the point helping you build a meaningful Windows application. It walks you
         through the terminology, concepts, and software you need to get started and then
         jumps to creating Me!Trade, a portfolio management tool.
                     </Paragraph>
                     <Paragraph>
                        As a bonus, this Short Cut also introduces two additional pillars of
         .NET 3.0: Windows Workflow Foundation and Windows Card Services.
                     </Paragraph>
                     <Paragraph>
                        Take the mystery out of .NET 3.0 and get started today.
                    </Paragraph>
                </FlowDocument>
              </FlowDocumentReader>
            </DockPanel>
         </Window>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 48                                                                                        Return to Table of Contents




In Example 5-3 we create a DockPanel. A TextBlock is docked to the top, holding an image
with the O'Reilly logo. A TextBlock is docked to the bottom holding the trademark
notification. We then see the StackPanel docked to the left of the DockPanel, and within that
StackPanel we place an ImageSource to hold the book cover image. Finally, a
FlowDocumentReader is placed as the final element in the DockPanel (and thus is centered
and fills the rest of the DockPanel) providing all the neat text manipulation that comes with
this powerful tool, as shown in Figure 4-5

                                       Figure 2-5. Incorporating a FlowDocumentReader into the simple app




2.1.3. Canvas and ViewBox
When discussing simple 2-D graphics, we are particularly fond of little green men. To get
started, we'll use the Canvas layout control, which allows for absolute positioning of child
elements. This control is greatly enhanced by placing it within a ViewBox control which is
designed to allow the user to stretch and scale its child elements as illustrated in Example
4-4.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 49                                                                                        Return to Table of Contents



Example 2-4. Canvas and ViewBox – Little Green Men


         <Window
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title="Programming .NET 3 | Layout: I'm So Happy!">

             <Viewbox>
                   <Canvas Width="180" Height="180" VerticalAlignment="Center">
                        <Ellipse Canvas.Left="10" Canvas.Top="10" Width="160" Height="160"
                             Fill="LimeGreen" Stroke="Black" />
                        <Ellipse Canvas.Left="45" Canvas.Top="50" Width="25" Height="25"
                             Fill="Black" Stroke="Black" />
                        <Ellipse Canvas.Left="77.5" Canvas.Top="50" Width="25" Height="25"
                             Fill="Black" Stroke="Black" />
                        <Ellipse Canvas.Left="110" Canvas.Top="50" Width="25" Height="25"
                             Fill="Black" Stroke="Black" />
                        <Path Data="M 50,100 A 30,30 900 0 0 130,100" Stroke="Black"/>
                   </Canvas>
             </Viewbox>
         </Window>



An Ellipse object draws an ellipse (surprise!) and you place it on the canvas using its position
with relation to the upper left corner of the canvas.


       NOTE
       All shape objects (Ellipse, Line, Path, Polygon, Polyline and Rectangle) share three
       common properties:

            •   Stroke: how the shape's outline will be drawn
            •   StrokeThickness: the thickness of the shape's outline
            •   Fill: how the shape's interior will be painted

       All of the properties for coordinates and vertices are measured in device-
       independent pixels.

The Viewbox allows you to stretch and resize its contents. In our case, the contents are the
canvas on which we'll draw our little green man. (I grew up being called four-eyes, think of
this as my revenge!). Because we've placed our canvas in a ViewBox resizing is automagic, as
shown by starting with Figure 4-6 and then stretching the view box to render Figure 4-7

                                                                       Figure 2-6. LGM Small




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                   Page 50                                                                                                 Return to Table of Contents




                                                                             Figure 2-7. Large LGM




2.1.4. Control Presentation
WPF and XAML give you tremendous and precise control[*] (you should pardon the
expression) over the appearance of the control. Start with a simple button as shown in
Example 4-5.
        [*] Despite the incredible breadth of the English Language, and resorting to the astonishingly useful VisualThesaurus (http://www.VisualThesaurus.com) – there really is no
        better word than control in this sentence!




Example 2-5. A simple button


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Adding flavor to controls">
             <StackPanel Height="200">

                      <Button Width="200" VerticalAlignment="Center">Press Me!</Button>
                </StackPanel>

         </Window>



What is rendered is a button, as shown in Figure 4-8. No surprises


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 51                                                                                        Return to Table of Contents




                                                                   Figure 2-8. Standard Button




We can now style this button using gradients, to improve (and professionalize) its look both
when unpressed, and while the user is depressing the button, as shown in Example 4-6.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 52                                                                                        Return to Table of Contents



Example 2-6. Adding Gradients to the Button class


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Adding flavor to controls">

              <Window.Resources>

                   <LinearGradientBrush x:Key="ButtonGradient"
                                        StartPoint="0,0"
                                        EndPoint="0,1">

                     <GradientStop Color="#FDB6CADF"
                                   Offset="0" />
                    <GradientStop Color="#FCC3C5FF"
                                   Offset="0.1" />
                    <GradientStop Color="#FCC4D0EF"
                                   Offset="0.3" />
                    <GradientStop Color="#FDB7C2DF"
                                   Offset="0.6" />
                    <GradientStop Color="#FE95B3CF"
                                   Offset="0.8" />
                    <GradientStop Color="#FE96AACF"
                                   Offset="1" />
                 </LinearGradientBrush>

                 <LinearGradientBrush x:Key="ButtonUpGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                       <GradientStop Color="Transparent"
                                     Offset="0" />
                       <GradientStop Color="#33000000"
                                     Offset="1" />

                 </LinearGradientBrush>

                 <LinearGradientBrush x:Key="ButtonDownGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                       <GradientStop Color="#10000000"
                                     Offset="0" />
                       <GradientStop Color="#20000000"
                                     Offset="1" />

                 </LinearGradientBrush>

                 <LinearGradientBrush x:Key="ButtonDisabledGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                       <GradientStop Color="#10302A90"
                                     Offset="0" />
                       <GradientStop Color="#10201040"
                                     Offset="1" />

                   </LinearGradientBrush>

                   <!-- BUTTON TEMPLATE -->

                   <Style TargetType="{x:Type Button}">
                      <Setter Property="Template">
                        <Setter.Value>
                           <ControlTemplate TargetType="{x:Type Button}">
                              <Border x:Name="OuterBorder"
                                       CornerRadius="3"
                                       Background="{DynamicResource ButtonGradient}">
                                 <Border x:Name="InnerBorder"




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 53                                                                                        Return to Table of Contents




                                  CornerRadius="3"
                                  Background="{DynamicResource ButtonUpGradient}"
                                  Padding="{TemplateBinding Padding}">
                                  <ContentPresenter x:Name="ContentSite"
                                                    HorizontalAlignment="Center"
                                                    VerticalAlignment="Center" />
                               </Border>
                            </Border>
                            <ControlTemplate.Triggers>
                               <Trigger Property="IsPressed" Value="true">
                                  <Setter TargetName="InnerBorder"
                                          Property="Background"
                                          Value="{DynamicResource ButtonDownGradient}" />
                               </Trigger>
                               <Trigger Property="IsEnabled" Value="false">
                                   <Setter TargetName="InnerBorder"
                                      Property="Background"
                                      Value="{DynamicResource ButtonDisabledGradient}" />
                                  <Setter Property="BorderBrush" Value="Silver" />
                                   <Setter Property="Foreground" Value="SlateGray" />
                               </Trigger>
                            </ControlTemplate.Triggers>
                         </ControlTemplate>
                     </Setter.Value>
                   </Setter>
                   <Setter Property="Height" Value="18" />
                   <Setter Property="Foreground" Value="MidnightBlue" />
                </Style>
            </Window.Resources>
            <StackPanel Height="200">

               <Button Width="200"
                       VerticalAlignment="Center">Press Me!</Button>
            </StackPanel>
         </Window>



This code will be a lot more familiar to those readers who are comfortable with Cascading
Style Sheets than to those who come to WPF from Windows Forms.


       NOTE
       For more on CSS we strongly recommend CSS The Definitive Guide (3rd Edition) by
       Eric Meyer (O'Reilly Media, 0596527330) for a solid introduction, and The Zen of CSS
       Design: Visual Enlightenment for the Web by Dave Shea and Molly Holzschlag (Peachpit
       Press, 032130347) for insight into how CSS can help you create magnificent web sites.

Let's walk through this XAML section by section to see what it does.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 54                                                                                        Return to Table of Contents




                                                                 Linear Gradient


    A linear gradient paints a color along a line, with that color changing gradually as
    it moves along the line. (The gradual change can be interrupted by abrupt changes
    to a new color using GradientStop objects).
    The linear gradient is typically along a diagonal, though this is not required. In any
    case, the line for the linear gradient is determined by a start point and an end
    point, typically designated by a pair of x,y coordinates, designating the upper left
    and lower right of the area being filled, as illustrated in


                                                 Figure 2-9. Linear Gradient Illustration From Microsoft




The first set of steps is to declare the Window, put in the customary namespaces and then
to declare a Resources section. Resources provide the ability to share styles or elements
throughout the UI, and they must be explicitly declared. In this case, we are declaring
resources for the Window...

     <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Programming .NET 3 | Adding flavor to controls">

         <Window.Resources>



2.1.4.1. The Resource Section
The first resource we are declaring is a LinearGradientBrush, which you can easily guess is a
specialized brush for creating LinearGradients; that is, gradients that fall off at a steady rate.
You declare the start and end point (see side bar on Linear Gradients) and within the
definition of the Brush you declare one or more GraidentStop elements. These correspond
to the collection of GraidentStop objects associated with a LinearGradient brush object, and
each Gradient stop specifies both a color and an offset along the gradient axis. In short, the
Brush determines the rate of change of the gradient, and the stops determine the color
transitions and where along the gradient the colors change.

            <LinearGradientBrush x:Key="ButtonGradient"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 55                                                                                        Return to Table of Contents



                                               StartPoint="0,0"
                                               EndPoint="0,1">

                 <GradientStop Color="#FDB6CADF"
                               Offset="0" />

You declare LinearGradientBrush objects for each state of the button: the button itself, then
the Button when pressed (ButtonDownGradient), when released (ButtonUpGradient), and,
for completeness, when disabled (ButtonDisabledGradient).

2.1.4.2. Styles
The first line in the next section indicates that we are setting a style and that the target of the
style is a Button. The target is set by the property TargetType, and identified by the Type
property within the namespace http://schemas.microsoft.com/winfx/2006/xaml (for which
we created the alias "x," at the top of the file).

     <Style TargetType="{x:Type Button}">

Below this line we add a Setter element. Setters are used to apply a Style or a Trigger to
elements of a specific type (in our case, all Butons). The setter declares the attributes to be
set, the target type and the values we'll set for the attribute.
Here is how the setter is used in our case line by line

                                                            Table 2-1. Setter Element Line By Line

                                                      Property is a required field, names the attribute being set. In this case, we
         Setter Property="Template">                  are indicating that this is a template for how buttons should look inside the
                                                      scope of this declaration.
                                                      Opening of the required value element which indicates the value for the attribute (in case
        <Setter.Value>                                for the template attribute)

                                                      The value will be set by using a ControlTemplate whose target type is a Button.
        <ControlTemplate                              ControlTemplates are part of the WPF
        TargetType="{x:Type Button}">



                                                      This button will have an outer border defined as having a corner
        <Border x:Name="OuterBorder"
                                                      radius of 3 (that is, it will be a rounded-rectangle) and the
        CornerRadius="3"
                                                      gradient will be defined in this local resource dictionary and thus
        Background="{StaticResource
        ButtonGradient}">                             is static.
                                                      Not to reader, to see the effect of the rounding, try changing the
                                                      CornerRadius value to 10, making the button look more like a
                                                      bullet.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 56                                                                                        Return to Table of Contents




                                                      Property is a required field, names the attribute being set. In this case, we
         Setter Property="Template">                  are indicating that this is a template for how buttons should look inside the
                                                      scope of this declaration.

                                                      Within the outer border definition we define the inner border
        <Border x:Name="InnerBorder"
                CornerRadius="10"                     which also sets the background, but this time using the
        Background="{StaticResource
        ButtonUpGradient}"                            buttonUpGradient.
        Padding="{TemplateBinding                     Padding is used to put padding around the content.
        Padding}">
                                                      ContentPresenter is used to display the text of the button, and
           <ContentPresenter
        x:Name="ContentSite"                          all of this (innerBorder) is wrapped within the outerBorder Border
        HorizontalAlignment="Center"                  element
        VerticalAlignment="Center" />
        </Border>




                                                      Triggers are used to fire off events on the controls that this template is describing (in our
        <ControlTemplate.Triggers>                    case, buttons)

                                                      When the button is pressed, this trigger causes the ButtonDownGradient to be drawn in the
        <Trigger Property="IsPressed"                 InnerBorder
                 Value="true">
           <Setter
        TargetName="InnerBorder"
                   Property="Background"

        Value="{DynamicResource
        ButtonDownGradient}" />
        </Trigger>


                                                      This trigger is fired if the IsEnabled property is set to false. In that case, the InnerBorder
        <Trigger Property="IsEnabled"                 background property is set to the StaticResource value ButtonDisabledGradient and the
                 Value="false">                       BorderBrush is set to Silver and the Foreground color is set to SlateGray.
           <Setter
        TargetName="InnerBorder"
                   Property="Background"
        Value="{StaticResource
        ButtonDisabledGradient}" />
           <Setter
        Property="BorderBrush"
                   Value="Silver" />
           <Setter Property="Foreground"
                   Value="SlateGray" />
        </Trigger>


                                                      All the open tags we've been working with are closed and the setter is complete
                            </Trigger>

        </ControlTemplate.Triggers>
                 </ControlTemplate>
              </Setter.Value>
           </Setter>


                                                      Two more setters are used to set general style properties of the button
        <Setter Property="Height"
                  Value="18" />
          <Setter Property="Foreground"
                  Value="MidnightBlue" />




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 57                                                                                        Return to Table of Contents




                                                      Property is a required field, names the attribute being set. In this case, we
         Setter Property="Template">                  are indicating that this is a template for how buttons should look inside the
                                                      scope of this declaration.
                                                      The style element is closed off, the Resources element is closed off and a stackPanel is created
                </Style>                              in which a button is created.. That finishes off the Window.
             </Window.Resources>
             <StackPanel Height="200">

               <Button Width="200"
        VerticalAlignment="Center">Press
        Me!</Button>
        </StackPanel>
        </Window>




All of this looks a bit daunting at first, but notice that at no time did you have to go into a
drawing program and to create an image button; you described an image button in XAML
and it was drawn for you based on that description. That is pretty neat. The result is shown
in Figure 4-10

                                                                   Figure 2-10. Gradient Button




2.1.4.3. Making Effects More Pronounced
We strongly encourage you to "play" with these examples to make the effects more
pronounced and see what happens. For example, I modified the colors in the gradient,
substituting primary rainbow colors,

     <LinearGradientBrush x:Key="ButtonGradient"
                                StartPoint="0,0"
                                EndPoint="0,1">

                 <GradientStop Color="Red"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 58                                                                                        Return to Table of Contents



                             Offset="0" />
               <GradientStop Color="Orange"
                             Offset="0.1" />
               <GradientStop Color="Yellow"
                             Offset="0.3" />
               <GradientStop Color="Green"
                             Offset="0.6" />
               <GradientStop Color="Blue"
                             Offset="0.8" />
               <GradientStop Color="Violet"
                             Offset="1" />
            </LinearGradientBrush>

and greatly increased the size of the button

              <Setter Property="Height" Value="40" />
               <Setter Property="Foreground" Value="BLUE" />
            </Style>
         </Window.Resources>
         <StackPanel Height="400">

to make the gradient effect much more obvious, as shown in Figure 4-11

                                                                   Figure 2-11. Rainbow Button




2.1.4.4. Using Built-in graphic primitives Inside Controls
To really master how your controls appear you can combine 2-D graphics with built-in
controls and make what look like image buttons but are actually drawn dynamically and
declaratively as illustrated in Example 4-7.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 59                                                                                        Return to Table of Contents



Example 2-7. Combining Graphics with Controls


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Programming Methodology Graphic">

            <StackPanel Height="200">
               <Button Width="200" VerticalAlignment="Center">
                 <StackPanel Orientation="Horizontal">
                     <Canvas Width="30"
                            Height="30"
                            VerticalAlignment="Center"
                            Margin="3">
                       <Ellipse Canvas.Left="1"
                                Canvas.Top="1"
                                Width="30"
                                Height="30"
                                Fill="White"
                                Stroke="Black" />
                       <Ellipse Canvas.Left="4"
                                Canvas.Top="4"
                                Width="24"
                                Height="24"
                                Fill="Black"
                                Stroke="Black" />
                       <Ellipse Canvas.Left="8"
                                Canvas.Top="8"
                                Width="16"
                                Height="16"
                                Fill="Blue"
                                Stroke="Blue" />
                       <Ellipse Canvas.Left="11"
                                Canvas.Top="11"
                                Width="10"
                                Height="10"
                                Fill="Red"
                                Stroke="Red" />
                       <Ellipse Canvas.Left="14"
                                Canvas.Top="14"
                                Width="4"
                                Height="4"
                                Fill="Yellow"
                                Stroke="Yellow" />
                    </Canvas>
                    <TextBlock VerticalAlignment="Center"> Ready, Fire, Aim!</TextBlock>
                 </StackPanel>
               </Button>
            </StackPanel>
         </Window>



In Example 4-7. we insert a StackPanel inside a Button control (as promised earlier in the
chapter). Within the stack panel we place a number of ellipse elements, creating a classic
"bulls-eye" as shown in Figure 4-12

                                                                   Figure 2-12. Ready Fire Aim




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 60                                                                                        Return to Table of Contents




2.2. Resources
Resources provide your XAML with a way to define and share styles or elements. You can
share resources at the page (window) level, or throughout an entire application (or even
across an entire system!).
The definition of the resource section of your XAML is referred to as the Resource Dictionary.
To create a resource that is scoped to a single window you use the element

     <Window.Resources>

As shown in Example 4-8.

Example 2-8. A static resource scoped to a single window


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Resources">
             <Window.Resources>
               <SolidColorBrush x:Key="GreenBrush" Color="Green" />
             </Window.Resources>
             <Viewbox>
                   <TextBlock Foreground="{StaticResource GreenBrush}">
                        Little Green Men
                   </TextBlock>
             </Viewbox>
         </Window>



The resource is applied to a TextBlock by applying setting the foreground value to the
resource itself. The keyword StaticResource indicates that the resource is pre-defined (the
alternative is a dynamic resource which will be set at run time and may be dependent on the
state of other objects on the page). The result of applying the GreenBrush resource to the
TextBlock is shown in Figure 4-13

                                                     Figure 2-13. StaticResource used to color the text




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 61                                                                                        Return to Table of Contents




2.3. Transformations
While there is much that can be written about 2-D graphics, one of the more interesting (and
at times confusing) aspects of taking control of graphics is transformations – the art of
transforming the up/down orientation of the page.
WPF makes simple transformations very simple, as shown in Example 4-9.

Example 2-9. Simple Transform


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Transformations: Rotate">
                    <Border Margin="30"
           HorizontalAlignment="Left" VerticalAlignment="Top"
           BorderBrush="Black" BorderThickness="1" >
           <StackPanel Orientation="Vertical">
              <Button Content="Top Button" Opacity="1" />
              <Button Content="Middle Button" Opacity="1" />
              <Button Content="Rotated Button">
              <Button.RenderTransform>
                 <RotateTransform Angle="45" />
              </Button.RenderTransform>
             </Button>

           </StackPanel>
         </Border>
         </Window>



In this example, we create Three Buttons. The third button has a RenderTransform applied
to it, and the RenderTransform has a child element: RotateTransform whose attribute is an
angle (in this case 45 degrees). The button is rendered rotated 45° clock-wise, as shown in
Figure 4-14.

                                                              Figure 2-14. Simple Transformation




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 62                                                                                        Return to Table of Contents




2.4. Animation
The power of transformations is greatly enhanced when combined with animation – rotate
an object? Interesting. Rotate an object in front of my eyes? Much more interesting.
To animate an object in the WPF that object must meet just three requirements:

  1. It must be a dependency property (see sidebar)
  2. It must belong to a class that inherits from DependencyObject and implements
     IAnimatable (Controls such as Button, Panel and Shape all inherit from
     DependencyObject, and implement IAnimatable, so this is almost never a problem)
  3. There must be a compatible animation type available (or you can create your own)



                                           Dependency And Attached Properties


    Dependency properties exist to allow for the creation of "attached properties," –
    that is the ability of one class to "attach" properties to another. This is what allows
    a canvas (for example) to "attach" properties to an Ellips (for example) so that you
    can write

         <Canvas Width="180" Height="180"
         VerticalAlignment="Center">
            <Ellipse Canvas.Left="10" Canvas.Top="10" Width="160"
         Height="160"
                   Fill="LimeGreen" Stroke="Black" />

    As you did in Example 4-4. even though Ellipse does not have a Left or Top property.

The typical steps for animation are to pick a property to animate. In the next example we'll
animate the Button's angle, which is of type Double and so we'll use a DoubleAnimation to
create a transition between two double values (typically referred to as the From and To
properties). You must also specify a Duration – the tiem it takes to go from the starting value
to the destination value. The longer the time, the slower the animation.
The second step is to create a Storyboard which designates where to apply the animation
(the TargtName) which designates the object to animate (in our next case, the button).
Finally, the StoryBoard must be associated with a Trigger – an event that will kick off the
animation. This is all illustrated in Example 4-10.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 63                                                                                        Return to Table of Contents



Example 2-10. Rotating a Button on Click


         <Page
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title=" Programming .NET 3 | Graphics: Animated Rotation"
           Background="White" Margin="50">
           <StackPanel>

                <Button Content="Slow Spinning Button" Width="200"
                  RenderTransformOrigin="0.5,0.5">
                  <Button.RenderTransform>
                    <RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
                  </Button.RenderTransform>
                  <Button.Triggers>
                    <EventTrigger RoutedEvent="Button.Click">
                      <BeginStoryboard>
                        <Storyboard>
                           <DoubleAnimation
                             Storyboard.TargetName="AnimatedRotateTransform"
                             Storyboard.TargetProperty="Angle"
                             To="360" Duration="0:0:5" FillBehavior="Stop" />
                        </Storyboard>
                      </BeginStoryboard>
                    </EventTrigger>
                  </Button.Triggers>
                 </Button>

           </StackPanel>
         </Page>



If you put this in XAML Pad and click the button, it will rotate through a full rotation in 5
seconds.

     <Storyboard>
       <DoubleAnimation
        Storyboard.TargetName="AnimatedRotateTransform"
        Storyboard.TargetProperty="Angle"
        To="360" Duration="0:0:5" FillBehavior="Stop" />
     </Storyboard>

The animation will be set off by clicking on the button

     <EventTrigger RoutedEvent="Button.Click">




2.4.1.

2.4.1.1. Simultaneous Animations
Your StoryBoard need not be restricted to running a single DoubleAnimation, nor need it
stop after a single well defined event (one complete rotation). You can combine movement
vertically with movement horizontally to create diagonal movement, and you can repeat
that movement indefinitely, as shown in Example 4-11.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 64                                                                                        Return to Table of Contents



Example 2-11. Diagonal Movement Through Paired DoubleAnimations


         <Window
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title="Programming .NET 3 | Simple LGM Animation"
           Background="White" Margin="50">

                <Window.Triggers>
                     <EventTrigger RoutedEvent="Window.Loaded">
                        <BeginStoryboard Name="LGMMoverStoryboard" >
                        <Storyboard>
                         <DoubleAnimation
                                  Storyboard.TargetName="LGMCanvas"
                                  Storyboard.TargetProperty="Height"
                                  From="10" To="600" Duration="0:0:5" RepeatBehavior="Forever" />

                            <DoubleAnimation
                                    Storyboard.TargetName="LGMCanvas"
                                    Storyboard.TargetProperty="Width"
                                    From="10" To="600" Duration="0:0:5" RepeatBehavior="Forever" />
                          </Storyboard>

                      </BeginStoryboard>
                      </EventTrigger>
                </Window.Triggers>

                       <Canvas Width="180" Height="180"
                               VerticalAlignment="Center" x:Name="LGMCanvas">
                            <Ellipse Canvas.Left="10" Canvas.Top="10" Width="160" Height="160"
                                Fill="LimeGreen" Stroke="Black" />
                            <Ellipse Canvas.Left="45" Canvas.Top="50" Width="25" Height="25"
                                Fill="Black" Stroke="Black" />
                            <Ellipse Canvas.Left="77.5" Canvas.Top="50" Width="25" Height="25"
                                Fill="Black" Stroke="Black" />
                            <Ellipse Canvas.Left="110" Canvas.Top="50" Width="25" Height="25"
                                Fill="Black" Stroke="Black" />
                            <Path Data="M 50,100 A 30,30 900 0 0 130,100" Stroke="Black"/>

                 </Canvas>
         </Window>



Notice that the trigger for this event is loading the window itself; this animation begins as
soon as the program begins, and never ends until the program is closed,

     <EventTrigger RoutedEvent="Window.Loaded">




2.4.2. A Composite Control
With the WPF controls and drawing capabilities and resources under your belt, you can mix
and match them and then combine them, adding subtle animation to create composite-
controls that provide you with very powerful presentation mechanics that you can reuse in
many different formats. To illustrate this idea, we'll create a slider that displays images of the
presidents of the United States retrieved from the White House Web site in this chapter, and
then reuse this code in our business example in the next chapter. The code is shown,
complete in Example 4-12. .




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 65                                                                                        Return to Table of Contents



Example 2-12. Composite Control: Image Slider


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | US Presidents"
            Background="White"
            Margin="50">
            <Window.Resources>

                   <LinearGradientBrush x:Key="ListBoxGradient"
                                        StartPoint="0,0"
                                        EndPoint="0,1">

                       <GradientStop Color="#90000000"
                                     Offset="0" />
                       <GradientStop Color="#40000000"
                                     Offset="0.005" />
                       <GradientStop Color="#10000000"
                                     Offset="0.04" />
                       <GradientStop Color="#20000000"
                                     Offset="0.945" />
                       <GradientStop Color="#60FFFFFF"
                                     Offset="1" />

                   </LinearGradientBrush>


                   <Style x:Key="SpecialListStyle"
                          TargetType="{x:Type ListBox}">
                      <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBox}" >
                               <Border     BorderBrush="Gray"
                                  BorderThickness="1"
                                  CornerRadius="6"
                                  Background="{DynamicResource ListBoxGradient}" >
                                  <ScrollViewer VerticalScrollBarVisibility="Disabled"
                                     HorizontalScrollBarVisibility="Auto">
                                     <StackPanel IsItemsHost="True"
                                         Orientation="Horizontal"
                                         HorizontalAlignment="Left" />
                                  </ScrollViewer>
                               </Border>
                            </ControlTemplate>
                        </Setter.Value>
                      </Setter>
                   </Style>

                   <Style x:Key="SpecialListItem"
                          TargetType="{x:Type ListBoxItem}">
                      <Setter Property="MaxHeight"
                              Value="75" />
                      <Setter Property="MinHeight"
                              Value="75" />
                      <Setter Property="Opacity"
                              Value=".75" />
                      <Style.Triggers>
                         <EventTrigger RoutedEvent="Mouse.MouseEnter">
                            <EventTrigger.Actions>
                               <BeginStoryboard>
                                  <Storyboard>
                                     <DoubleAnimation Duration="0:0:0.2"
                                        Storyboard.TargetProperty="MaxHeight"
                                        To="85" />
                                     <DoubleAnimation Duration="0:0:0.2"
                                        Storyboard.TargetProperty="Opacity"
                                        To="1.0" />
                                  </Storyboard>
                              </BeginStoryboard>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 66                                                                                        Return to Table of Contents




                             </EventTrigger.Actions>
                          </EventTrigger>

                        <EventTrigger RoutedEvent="Mouse.MouseLeave">
                            <EventTrigger.Actions>
                               <BeginStoryboard>
                                  <Storyboard>
                                     <DoubleAnimation Duration="0:0:1"
                                        Storyboard.TargetProperty="MaxHeight" />
                                     <DoubleAnimation Duration="0:0:0.2"
                                        Storyboard.TargetProperty="Opacity" />
                                  </Storyboard>
                               </BeginStoryboard>
                            </EventTrigger.Actions>
                        </EventTrigger>
                     </Style.Triggers>
                   </Style>


            </Window.Resources>
            <Grid Width="300"
                  Height="150">
               <StackPanel>
                  <TextBlock FontSize="14">United States Presidents</TextBlock>
                  <ListBox Style="{StaticResource SpecialListStyle}"
                            Grid.Row="1"
                            Grid.ColumnSpan="3"
                            Name ="PhotoListBox"
                            Margin="0,0,0,20"

                                ItemsSource="{Binding }"
                                ItemContainerStyle="{StaticResource SpecialListItem}"
                                SelectedIndex="0">
                          <ListBoxItem>
                             <Image Source=
                             "https://www.naymz.com/media/images/306/portrait-portrait.jpg" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                              "http://www.whitehouse.gov/history/presidents/images/bc42.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                              <Image Source=
                                "http://www.whitehouse.gov/history/presidents/images/gb41.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/rr40.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jc39.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gf38.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/rn37.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/lj36.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jk35_1.gif" />
                          </ListBoxItem>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 67                                                                                        Return to Table of Contents




                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/de34.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ht33.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/fr32.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/hh31.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/cc30.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wh29.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ww28.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/tr26.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wt27.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wm25.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gc2224.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/bh23.gif" />
                          </ListBoxItem>

                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ca21.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jg20.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/rh19.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ug18.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ag17.gif"                                    />
                          </ListBoxItem>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 68                                                                                        Return to Table of Contents




                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/al16.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                              <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jb16.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/fp14.gif" />
                          </ListBoxItem>

                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/mf13.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/zt12.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jp11.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jt10.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wh9.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/mb8.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/aj7.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ja6.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jm5.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jm4.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/tj3.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ja2.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gw1.gif" />
                          </ListBoxItem>

                    </ListBox>
              </StackPanel>
           </Grid>
         </Window>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 69                                                                                        Return to Table of Contents




Nothing in this code is new, it has just been put together in new ways. We start with declaring
a resource section in which we declare a LinearGradientBrush with GradientStops for the
colors we want along the gradient.
A Style is created for the List and targeted at the ListBox, setting the Border thickness to Grey
and rounding the corners. The Vertical Scroll Bar is turned off, the Horizontal scroll bar is set
to automatic (so that if the width of the control is insufficient to show all the images the user
can scroll through them).
A Second style is created in the resources for the items in the list box. Their minimum and
maximum height is set as well as their opacity, and a trigger is set for pasing the mouse over
the item. When the event fires (when the user hovers over an image) an animation begins
which inflates the image to its maximum height and increases the images opacity to 100%.
The second trigger fires when the user's mouse moves away: the image deflates to the
minimum size and the opacity reduces to 75%, making the image somewhat less vivid. The
effect is very pronounced, and can be seen quite clearly in Figure 4-15

                                                                    Figure 2-15. US Presidents




2.5. Data Binding
Sooner or later (sooner if you are writing typical commercial applications), you need to
associate your presentation widgets with persistent data. That data may come from the
Internet, or it may come from XML files, email, your operating system, or -- most often -- from
a database. Okay, let's be blunt; most often from a relational database, and if you're
programming in the Microsoft world, we'll go so far as to say, most often from SQL Server
(though both authors have certainly written commercial applications that used gigabytes of
data from databases that were not written in Redmond!)


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 70                                                                                        Return to Table of Contents



The ability to bind a control to a data source is critical to creating efficient professional
programs, and WPF would be nothing more than a very impressive toy if it did not support
the sophisticated data-binding that ASP.NET and Windows Forms programmers have grown
accustomed to.

2.5.1.

2.5.1.1. Switching to Visual Studio
For the next example, we're going to combine XAML and a business class. Fire up Visual
Studio and create a new WPF application named CheckOut. Begin by creating a new class
ShoppingCartItem.cs as shown in Example 4-13.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                    Page 71                                                                                                     Return to Table of Contents



Example 2-13. Shopping CartItem.cs


         using System;
         using System.Collections.Generic;
         using System.Text;

         namespace CheckOut
         {
            public class ShoppingCartItem
            {
               private string item, value, shortDescription;
               private int sku;

                   public ShoppingCartItem(
                      string item,
                      string value,
                      string shortDescription,
                      int sku)
                   {
                      this.item = item;
                      this.value = value;
                      this.shortDescription = shortDescription;
                      this.sku = sku;
                   }


                   public string Item
                   {
                      get { return this.item; }
                      set { this.item = value; }
                   }

                   public string Value
                   {
                      get { return this.value; }
                      set { this.value = value; }
                   }

                   public string ShortDescription
                   {
                      get { return this.shortDescription; }
                      set { this.shortDescription = value; }
                   }

                   public int SKU
                   {
                      get { return this.sku; }
                      set { this.sku = value; }
                   }

              }
         }




This class has nothing but four values: three strings and an integer. In keeping with accepted
Data Hiding rules, we've made all four private member variables, and provided properties

for accessing the four values.[                                  ]




        [ ] For a discussion on whether or not this is in fact good design or just mindless superstition, see Jesse's article, Programmer Superstitions at http://simple-talk.com/author/
        jesse-liberty/


In the Window1.xaml file add the XAML code to define the presentation layer as shown in
Example 4-14.


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 72                                                                                        Return to Table of Contents




Example 2-14. XAML for Shopping Cart


         <Window x:Class="CheckOut.Window1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:CheckOut"
             Title="Programming .NET 3 | Data Binding 101" Height="100" Width="380" >
            <Window.Resources>
               <local:ShoppingCartItem x:Key="Cart"
                                       SKU="1568"
                                       Item="Photograph"
                                       Value="$19.99"
                                       ShortDescription="A beautiful picture of a dolphin"/>
            </Window.Resources>


              <Grid DataContext="{StaticResource Cart}"
                    Margin="3"
                    Width="360"
                    HorizontalAlignment="Left">
                 <Grid.RowDefinitions>
                    <RowDefinition Height="20"/>
                    <RowDefinition Height="20"/>
                    <RowDefinition/>
                 </Grid.RowDefinitions>
                 <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="40"/>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="40"/>
                 </Grid.ColumnDefinitions>

                   <TextBlock Grid.Column="0"
                              Grid.Row="0">SKU</TextBlock>
                   <TextBlock Grid.Column="1"
                             Grid.Row="0">Item</TextBlock>
                   <TextBlock Grid.Column="2"
                             Grid.Row="0">Description</TextBlock>
                   <TextBlock Grid.Column="3"
                              Grid.Row="0">Price</TextBlock>



                   <TextBlock Grid.Column="0"
                              Grid.Row="1"
                              Text="{Binding Path=SKU}" />
                   <TextBlock Grid.Column="1"
                              Grid.Row="1"
                              Text="{Binding Path=Item}" />
                   <TextBlock Grid.Column="2"
                              Grid.Row="1"
                              Text="{Binding Path=ShortDescription}" />
                   <TextBlock Grid.Column="3"
                              Grid.Row="1"
                              Text="{Binding Path=Value}" />

              </Grid>

         </Window>



In the resources section you declare an instance of a shopping art, setting the various
properties declaratively. You then create a grid, setting its DataContext to the Cart you
declared in the resources section (and thus binding the data from the resources section to
the presentation you are now declaring).


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 73                                                                                        Return to Table of Contents



You define a pair of rows and four columns. That done you define your first four TextBlocks,
assigning them to the four columns, all within the first row; these serve as headers.
In the second set of TextBlocks you set the Text using the binding syntax,

     <TextBlock Grid.Column="0"
               Grid.Row="1"
               Text="{Binding Path=SKU}" />

This sets the TextBlock into column 0 of Row 1 and states that the Text will come from binding
to a data source whose path is set in the resource whose name was defined earlier as "SKU".
We saw that definition of SKU in the Resources section,

     <Window.Resources>
       <local:ShoppingCartItem x:Key="Cart"
                               SKU="1568"

In this case, the value for SKU is defined in place, but it could also be dynamically retrieved
from a database or web service.
When you run this, a window is opened, and the grid is filled with both the header row and
the second row bound to the "ShoppingCartItem" as shown in Figure 4-16

                                                    Figure 2-16. The results of our simple data binding




2.5.2. Binding to a list
To create a list of items in the shopping cart, you'll rename your ShoppingCart class to
ShoppingCartList and create a new class ShoppingCart which will derive from (and allow you
to instantiate) a List<ShoppingCartItems>. To be explicit, the code in your
ShoppingCartItem.cs file now looks like Example 4-15.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 74                                                                                        Return to Table of Contents



Example 2-15. ShoppingCartItem.cs


         using System;
         using System.Collections.Generic;
         using System.Text;

         namespace CheckOutList
         {
            public class ShoppingCart : List<ShoppingCartItem>
            {
                           }


              public class ShoppingCartItem
              {
                 private string item, value, shortDescription;
                 private int sku;

                   public ShoppingCartItem()
                               {
                               item = string.Empty;
                               value = string.Empty;
                               shortDescription = string.Empty;
                               sku = -1;
                   }

                   public ShoppingCartItem(
                      string item,
                      string value,
                      string shortDescription,
                      int sku)
                   {
                      this.item = item;
                      this.value = value;
                      this.shortDescription = shortDescription;
                      this.sku = sku;
                   }


                   public string Item
                   {
                      get { return this.item; }
                      set { this.item = value; }
                   }

                   public string Value
                   {
                      get { return this.value; }
                      set { this.value = value; }
                   }

                   public string ShortDescription
                   {
                      get { return this.shortDescription; }
                      set { this.shortDescription = value; }
                   }

                   public int SKU
                   {
                      get { return this.sku; }
                      set { this.sku = value; }
                   }

              }
         }




Make sure you include a default constructor for your ShoppingCartItem class.


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 75                                                                                        Return to Table of Contents



Your next step is to modify the resources in your XAML file to create a collection of
ShoppingCartItems,

     <Window.Resources>
        <local:ShoppingCart x:Key="Cart">
          <local:ShoppingCartItem SKU="1568"
                                  Item="Photograph"
                                  Value="$19.99"
                                  ShortDescription="A beautiful picture of a dolphin"/>
          <local:ShoppingCartItem SKU="1569"
                                  Item="Matting"
                                  Value="$29.99"
                                  ShortDescription="1 inch double matting"/>
          <local:ShoppingCartItem SKU="1570"
                                  Item="Frame"
                                  Value="$39.99"
                                  ShortDescription="Natural Wood Frame ( 8 x 11 )"/>
          <local:ShoppingCartItem SKU="1571"
                                  Item="UV Glass"
                                  Value="$9.99"
                                  ShortDescription="UV Glass for 8 x 11 frame"/>
        </local:ShoppingCart>
     </Window.Resources>

You are now ready to display these items. You can't just use TextBlocks in a grid, since in
theory (eventually) you won't know how many items you're going to display.
What you want to do is to create a listBox, and display the items in the list box. That doesn't
mean you have to give up control of the display layout, howevr. While a DataTemplate in a
listbox can only have one control within it (in our case, a Stack panel whose orientation will
be Horizontal to hold one "row"), that control can itself have many child controls.
We'll give the StackPanel four child StackPanels, each set to a Vertical orientation, and each
with a width equal to that of the header column so that our values line up nicely, as shown
in Example 4-16.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 76                                                                                        Return to Table of Contents



Example 2-16. XAML for Displaying a list of items


         <Window x:Class="CheckOutList.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:CheckOutList"
                Title="CheckOutList" Height="300" Width="430"
            >
           <Window.Resources>
              <local:ShoppingCart x:Key="Cart">
                 <local:ShoppingCartItem SKU="1568"
                                         Item="Photograph"
                                         Value="$19.99"
                                    ShortDescription="A beautiful picture of a dolphin"/>
                 <local:ShoppingCartItem SKU="1569"
                                         Item="Matting"
                                         Value="$29.99"
                                         ShortDescription="1 inch double matting"/>
                 <local:ShoppingCartItem SKU="1570"
                                         Item="Frame"
                                         Value="$39.99"
                                         ShortDescription="Natural Wood Frame ( 8 x 11 )"/>
                 <local:ShoppingCartItem SKU="1571"
                                         Item="UV Glass"
                                         Value="$9.99"
                                         ShortDescription="UV Glass for 8 x 11 frame"/>
              </local:ShoppingCart>
           </Window.Resources>

              <!-- the heading -->
              <Grid DataContext="{StaticResource Cart}"
                   Margin="15"
                   Width="430"
                    HorizontalAlignment="Left">
                <Grid.RowDefinitions>
                   <RowDefinition Height="20"/>
                   <RowDefinition Height="200"/>
                   <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                   <ColumnDefinition Width="40"/>
                   <ColumnDefinition Width="100"/>
                   <ColumnDefinition Width="180" />
                   <ColumnDefinition Width="40"/>
                </Grid.ColumnDefinitions>

                   <TextBlock Grid.Column="0"
                             Grid.Row="0">SKU</TextBlock>
                   <TextBlock Grid.Column="1"
                             Grid.Row="0">Item</TextBlock>
                   <TextBlock Grid.Column="2"
                             Grid.Row="0">Description</TextBlock>
                   <TextBlock Grid.Column="3"
                             Grid.Row="0">Price</TextBlock>

              <!-- the list box to display all the contents of the cart -->
                <ListBox Grid.Column="0"
                             Grid.Row="1"
                             Grid.ColumnSpan="4"
                             ItemsSource="{Binding}"
                             Width="360">
                   <ListBox.ItemTemplate>
                      <DataTemplate>

                              <!-- the outer StackPanel (one per row) -->
                               <StackPanel Orientation="Horizontal" Width="350">

                                  <!-- the inner stack panels – one per column -->
                                   <StackPanel Orientation="Vertical" Width="40">
                                      <TextBlock Text="{Binding Path=SKU}" />




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 77                                                                                        Return to Table of Contents




                                    </StackPanel>
                                    <StackPanel Orientation="Vertical" Width="100">
                                       <TextBlock Text="{Binding Path=Item}" />
                                    </StackPanel>
                                     <StackPanel Orientation="Vertical" Width="170">
                                       <TextBlock Text="{Binding Path=ShortDescription}" />
                                    </StackPanel>
                                    <StackPanel Orientation="Vertical" Width="40">
                                       <TextBlock Text="{Binding Path=Value}" />
                                    </StackPanel>

                          </StackPanel>
                       </DataTemplate>
                    </ListBox.ItemTemplate>
                 </ListBox>


            </Grid>
         </Window>




The leap of imagination you must make is that we can bind to an unknown number of items,
and this list box will simply add each item, one by one, with the outer stack panel describing
what each entry in the list box looks like, and the inner stack panels describing what each
"column" of information (the sku, item, short description and value" look like and where they
are placed. The result is shown in Figure 4-17.

                                                                    Figure 2-17. Check out List




2.5.3. Master Detail
One of the most common and powerful data representation is the master/detail or order/
detail record. A classic example is looking at my recent orders on Amazon.com (http://
www.Amazon.com) as shown in Figure 4-18.


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 78                                                                                        Return to Table of Contents



                                                           Figure 2-18. Amazon Order with Details




As you can see, each order can have within it more than one item. These items themselves
have valuable information, including shipping date (or estimated delivery date) etc. It is very
common to have this kind of master (order) / detail relationship throughout virtually any
serious business database.
In the next example, we envision that some detail is too big to put into the list box, and must
be reserved for when the user clicks on an item and thereby asks to see more information.
We'll modify the previous example, first by changing the ShoppingCartItem class to add a
property long description,

     public string LongDescription
      {
         get { return this.longDescription; }
         set { this.longDescription = value; }
      }

You will, of course, need to add a private string as backing data, and update both constructors.
That done, you'll make more substantial changes to the Widnow1.xaml page. The first change
is to ad a LongDescription to each ShoppingCartItem in the Resources, for example,



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 79                                                                                        Return to Table of Contents




     <local:ShoppingCartItem SKU="1570"
                     Item="Frame"
                     Value="$39.99"
                     ShortDescription="Natural Wood Frame ( 8 x 11 )"
                     LongDescription="Hewn from natural growth forest,                                       hand cut." />

You need to modify the Grid's row definition to make room for the details below the list box.
Let's shorten the list box row from 200 to 100, and add a row for the description,

     <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="100"/>
        <RowDefinition Height="20"/>
        <RowDefinition/>
     </Grid.RowDefinitions>

While we're fussing, we can make the headers bold, by adding the FontWeight style to each
header's TextBlock,

     <TextBlock Grid.Column="0" FontWeight ="Bold"
               Grid.Row="0">SKU</TextBlock>



2.5.3.1. Event Handling
In order for the FullDescription to be displayed when the user clicks on an item in the list box,
we need to take the following steps

  1. Add an event handler to Window1.xaml.cs (the code behind for the window)
  2. Add a delegate to the ListBox telling it which event handler to call when its selection
     changes
  3. Add a TextBlock in the form into which we can place the long description when a choice
     is made in the list box.

Let's begin by adding the TextBlock we need on the form. Below the list box, but before we
close the grid, we'll add two TextBlocks: one as a header for the long description, and the
second to hold the long description when the user clicks in the list box.

     <TextBlock Grid.Column="0" Grid.ColumnSpan="2" FontWeight="Bold"
               Grid.Row="2">Full Description</TextBlock>
     <TextBlock Grid.Column="0"
               Grid.ColumnSpan="4"
               Grid.Row="3"
               Name="LongDescriptionLabel" />


Next, modify the listbox declaration to call a method that you'll add to the code-behind file,

     <ListBox Grid.Column="0"
             Grid.Row="1"
             Grid.ColumnSpan="4"
             ItemsSource="{Binding}"
             SelectionChanged="ShoppingCartSelection"
             Width="360">




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 80                                                                                        Return to Table of Contents



You must now implement the ShoppingCartSelection method in Window1.xaml.cs. It will
examine the ListBox control, see what was selected, extract from that object (which will be
of type ShoppingCartItem) the LongDescription and place that long description into the
TextBlock you just added to the form. The code is shown in Example 4-17.

Example 2-17. ShoppingCartSelection in Window1.xaml.cs


         private void ShoppingCartSelection(object sender, RoutedEventArgs e)
         {
            ListBox lb = sender as ListBox;
            ShoppingCartItem scItem = lb.SelectedItem as ShoppingCartItem;
            LongDescriptionLabel.Text = scItem.LongDescription.ToString();
         }




                          The old C hacker in me is tempted to write the method as follows,

                                     private void ShoppingCartSelection(
                                        object sender, RoutedEventArgs e)
                                     {
                                       LongDescriptionLabel.Text =
                                           ((sender as ListBox).SelectedItem as
                               ShoppingCartItem).LongDescription.ToString();
                                     }

                          But that would be evil.

The complete XAML code is shown in listing [To come]
When the user clicks on an item in the list box, the SelectionChanged event is fired, and
ShoppingCartSelection is called in Window1.xaml.cs. The list box is retrieved, the selected
ShoppingCartItem is identified and from that the LongDescription is extracted. That string
is then placed into the TextBlock and displayed, as shown in Figure 4-19

                                                            Figure 2-19. Master Detail List Binding




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 81                                                                                        Return to Table of Contents




                                                                                                                        Chapter 3. WPF


Every Windows program begins with an "entry point" — and in WPF that entry point is
contained within an instance of the Application class. Unlike Windows Forms, but much like
ASP.NET, WPF applications are explicitly divided between "markup" (XAML) and the "code-
behind" that together correspond to the .NET class libraries.
As you saw in the previous chapters, you can use XAML to create very powerful layouts and
displays, but WPF goes beyond that to use XAML and code-behind to create complete
applications that provide enhanced text, 2-D and 3-D graphics and much more.
The best way to think about it is this: WPF is a framework of classes provided for you by
Microsoft. You implement these classes either programmatically (by instantiating them in
code) or declaratively by using XAML.
In chapter 6 we're going to build a significant WPF business program that uses many features
of the WPF library. To prepare for that, this chapter will build on the previous chapter, and
introduce more of the features of the WPF that you are likely to use in creating your
applications.


3.1. Starting Simple: Panels
Whether you are working in ASP.NET or XAML, one challenge with every markup language
is achieving precise layout of the elements for display. The approach taken for XAML is to
use panels as touched on in the previous chapter.
Perhaps the most flexible panel is the grid, which gives you control of both columns and
rows (not unlike a table in HTML). Copy the code shown in Example 5-1 into XAML Pad and
run it. What you get should look like Figure 5-1 (only colorful).




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 82                                                                                        Return to Table of Contents



Example 3-1. Grid Example


           <Window
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Title="Programming .NET 3 | Understanding Grids">
              <Grid>
                   <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                   </Grid.RowDefinitions>
                   <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                   </Grid.ColumnDefinitions>

                  <TextBlock TextBlock.FontSize="36" Background="Blue" Grid.Column="0" Grid.Row
         ="0" Grid.RowSpan="2">1</TextBlock>
                  <TextBlock TextBlock.FontSize="36" Background="Gold" Grid.Column="1" Grid.Row
         ="0" >2</TextBlock>
                  <TextBlock TextBlock.FontSize="36" Background="Crimson" Grid.Column="2" Grid
         .Row="0" >3</TextBlock>
                  <TextBlock TextBlock.FontSize="36" Background="White" Grid.Column="1" Grid.
         Row="1" Grid.ColumnSpan="2">4</TextBlock>
                  <TextBlock TextBlock.FontSize="36" Background="Purple" Grid.Column="0" Grid.
         Row="2" >5</TextBlock>
                  <TextBlock TextBlock.FontSize="36" Background="Green" Grid.Column="1" Grid.
         Row="2" >6</TextBlock>
                  <TextBlock TextBlock.FontSize="36" TextBlock.Foreground="White" Background
         ="Black" Grid.Column="2" Grid.Row="2" >7</TextBlock>

                </Grid>

         </Window>



This example starts by declaring a Grid element, and then by declaring a set of three
RowDefinitions (each with no properties) and three ColumnDefinitions, also with no
properties.
Below these row and column definitions, you declare TextBlocks. Examine the first TextBlock.
Its fontsize is set to 36 (this will be used for the numeral), its background color is set (which
is much more effective when you can see the colors!), and then its position in the grid is set
(column and row). Finally, its text is set. Note also that some text blocks include a rowspan
or a colspan attribute.
The first TextBlock will, therefore have a numeral "1" with a font size of 36; a background of
blue; the block will be placed in column 0, row 0 of the grid and will span two rows. All of this
is consistent with what we see in Figure 5-1.
Interestingly the grid itself has no colors; it is the Textblocks that bring the colors and are
placed inside the grid; the grid just supplies the structure.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 83                                                                                        Return to Table of Contents



                                                                     Figure 3-1. A colorful grid




3.1.1. DockPanel
The DockPanel specializes in "docking" its contents to specific edges of the panel, as
illustrated in Example 5-2. Take special note of the DockPanel declaration (in bold) which has
the attribute LastChildFill="True" — this ensures that the last child of the panel will be
centered as "fill" for the panel.

Example 3-2. A DockPanel


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Layout: DockPanel">

             <DockPanel LastChildFill="True">
             <TextBlock DockPanel.Dock="Top" Background="LightCoral" >I am the top...
         </TextBlock>
             <TextBlock DockPanel.Dock="Bottom" Background="LightCoral" >I am the bottom...
         </TextBlock>
             <TextBlock DockPanel.Dock="Left" VerticalAlignment="Center">I am the left...
         </TextBlock>
             <TextBlock DockPanel.Dock="Right" VerticalAlignment="Center">I am the Right...
         </TextBlock>
             <Button Height="40" Width="200">I am the Fill (or the center)</Button>
             </DockPanel>
         </Window>



As promised, we placed a Button as the final element in the DockPanel, and it was dutifully
centered, as shown in Figure 5-2




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 84                                                                                        Return to Table of Contents



                                         Figure 3-2. A simple DockPanel with top and bottom specified firsts




3.1.1.1. Order of Declaration is important
If we change the dock panel slightly, and declare the left and right text blocks before the top
and bottom text blocks, we change the area devoted to each. You can imagine that by doing
so, the dock panel devotes a full column to each the left and the right, and then allocates to
bottom and top only what remains, thereby foreshortening the area for top and bottom, as
shown in Figure 5-3


       NOTE
       To create this effect, modify the code in Example 5-2 so that the first two text blocks
       swap places with the second two (that is, right and left are declared before top and
       bottom.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 85                                                                                        Return to Table of Contents



                                                       Figure 3-3. DockPanel with left and right first.




If you modify the declaration of the right and left to set the background color

     background="lightblue"

it is easy to see that the area of the right and left column is exactly the area taken away from
the top and bottom. You can almost imagine a full column extending up to the top and down
to the bottom as imagined in Figure 5-4

                                                          Figure 3-4. Dock Panel Imagined columns




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 86                                                                                        Return to Table of Contents




3.1.1.2. DockPanels Are Pervasive
You can see how the DockPanel could be instrumental in many applications; with the left (or
right) column reserved for a menu or site-map, the top reserved for a header or tabs, the
bottom reserved for a status bar and the center holding the presentation of the contents of
the application.

3.1.2. StackPanel
StackPanel can be used alone, or inside other containers. Later we'll use a StackPanel inside
a Button, but for now, we'll show one off inside a DockPanel, as shown in Example 5-3




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 87                                                                                        Return to Table of Contents



Example 3-3. Stack Panel Inside a Dock Panel


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Layout: StackPanel and the FlowDocumentReader">

              <DockPanel LastChildFill="True">

               <TextBlock DockPanel.Dock="Top" Background="White" TextBlock.FontFamily
         ="Verdana" TextBlock.FontSize="48" VerticalAlignment="Center">
                   <Image Source="http://www.oreilly.com/images/oreilly/oreilly.gif" Width
         ="287" Height="67"/>
               </TextBlock>
               <TextBlock DockPanel.Dock="Bottom" Background="DarkRed" Foreground="White" >
                   © 2006, O'Reilly Media, Inc.
                   All trademarks and registered trademarks appearing on oreilly.com are the
         property of their respective owners.
               </TextBlock>
               <StackPanel DockPanel.Dock="Left" VerticalAlignment="Center" Margin="5">
                   <Image Source="http://www.oreilly.com/catalog/covers/059652921X_cat.gif"
         Height="223" Width="180" />
               </StackPanel>
               <FlowDocumentReader>
                   <FlowDocument>
                      <Paragraph>
                         <Bold></Bold>
                      </Paragraph>
                      <Paragraph>
                         <Paragraph.FontFamily>Verdana</Paragraph.FontFamily>
                         <Paragraph.FontSize>36</Paragraph.FontSize>
                         <Bold>Getting Started with .NET 3.0</Bold>
                      </Paragraph>
                      <Paragraph>
                         <Paragraph.FontFamily>Verdana</Paragraph.FontFamily>
                         <Paragraph.FontSize>18</Paragraph.FontSize>
                         <Bold>Writing Your First .NET 3.0 Application</Bold>
                      </Paragraph>
                      <Paragraph>
                         <Paragraph.FontFamily>Verdana</Paragraph.FontFamily>
                         <Paragraph.FontSize>18</Paragraph.FontSize>
                         By Jesse Liberty and Alex Horovitz<LineBreak />
                         September 2006<LineBreak />
                         Pages: 56 <LineBreak />
                      </Paragraph>
                      <Paragraph>
                         Learn how to create more dynamic user experiences and build secure
         web services using Windows Communication Foundation (WCF) and Windows Presentation
         Foundation (WPF), two of the foundational pillars of .NET 3.0, with this succinct
         and well-written PDF document.
                      </Paragraph>
                      <Paragraph>
                         Co-authored by best-selling author Jesse Liberty, this document gets
         right to the point helping you build a meaningful Windows application. It walks you
         through the terminology, concepts, and software you need to get started and then
         jumps to creating Me!Trade, a portfolio management tool.
                      </Paragraph>
                      <Paragraph>
                         As a bonus, this Short Cut also introduces two additional pillars of
         .NET 3.0: Windows Workflow Foundation and Windows Card Services.
                      </Paragraph>
                      <Paragraph>
                         Take the mystery out of .NET 3.0 and get started today.
                      </Paragraph>
                   </FlowDocument>
               </FlowDocumentReader>
            </DockPanel>
         </Window>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 88                                                                                        Return to Table of Contents



In Example 5-3 we create a DockPanel. A TextBlock is docked to the top, holding an image
with the O'Reilly logo. A TextBlock is docked to the bottom holding the trademark
notification. We then see the StackPanel docked to the left of the DockPanel, and within that
StackPanel we place an ImageSource to hold the book cover image. Finally, a
FlowDocumentReader is placed as the final element in the DockPanel (and thus is centered
and fills the rest of the DockPanel) providing all the neat text manipulation that comes with
this powerful tool, as shown in Figure 5-5

                                       Figure 3-5. Incorporating a FlowDocumentReader into our simple app




3.1.3. Canvas and ViewBox
When discussing simple 2-D graphics, we are particularly fond of little green men. To get
started, we'll use the Canvas layout control, which allows for absolute positioning of child
elements. This control is greatly enhanced by placing it within a ViewBox control which is
designed to allow the user to stretch and scale its child elements as illustrated in Example
5-4




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 89                                                                                        Return to Table of Contents



Example 3-4. Canvas and ViewBox — Little Green Men


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Layout: I'm So Happy!">

                <Viewbox>
                                    <Canvas Width="180" Height="180" VerticalAlignment="Center">
                                 <Ellipse Canvas.Left="10" Canvas.Top="10" Width="160" Height="160"
                                       Fill="LimeGreen" Stroke="Black" />
                                 <Ellipse Canvas.Left="45" Canvas.Top="50" Width="25" Height="25"
                                       Fill="Black" Stroke="Black" />
                                 <Ellipse Canvas.Left="77.5" Canvas.Top="50" Width="25" Height="25"
                                       Fill="Black" Stroke="Black" />
                                 <Ellipse Canvas.Left="110" Canvas.Top="50" Width="25" Height="25"
                                       Fill="Black" Stroke="Black" />
                                 <Path Data="M 50,100 A 30,30 900 0 0 130,100" Stroke="Black"/>

                   </Canvas>
             </Viewbox>
         </Window>



An Ellipse object draws an ellipse (surprise!) and you place it on the canvas using its position
with relation to the upper left corner of the canvas.


       NOTE
       All shape objects (Ellipse, Line, Path, Polygon, Polyline and Rectangle) share three
       common properties:

            •   Stroke: how the shape's outline will be drawn
            •   StrokeThickness: the thickness of the shape's outline
            •   Fill: how the shape's interior will be painted

       All of the properties for coordinates and vertices are measured in device-
       independent pixels.

The Viewbox allows you to stretch and resize its contents. In our case, the contents are the
canvas on which we'll draw our little green man. (I grew up being called four-eyes, think of
this as my revenge!). Because we've placed our canvas in a ViewBox resizing is automagic, as
shown by starting with Figure 5-6 and then stretching the view box to render Figure 5-7

                                                                       Figure 3-6. LGM Small




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                  Page 90                                                                                                 Return to Table of Contents




                                                                            Figure 3-7. Large LGM




3.1.4. Control Presentation
WPF and XAML give you tremendous and precise control[*] (you should pardon the
expression) over the appearance of the control. Start with a simple button as shown in
Example 5-5
        [*] Despite the incredible breadth of the English Language, and resorting to the astonishingly useful VisualThesaurus (http://www.VisualThesaurus.com) — there really is
        no better word than control in this sentence!




Example 3-5. A simple button


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Adding flavor to controls">
             <StackPanel Height="200">


                      <Button Width="200" VerticalAlignment="Center">Press Me!</Button>
                </StackPanel>

         </Window>



What is rendered is a button, as shown in Figure 5-8. No surprises

Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 91                                                                                        Return to Table of Contents




                                                                   Figure 3-8. Standard Button




We can now style this button using gradients, to improve (and professionalize) its look both
when unpressed, and while the user is depressing the button, as shown in Example 5-6




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 92                                                                                        Return to Table of Contents



Example 3-6. Adding Gradients to the Button class


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Adding flavor to controls">

              <Window.Resources>

                   <LinearGradientBrush x:Key="ButtonGradient"
                                        StartPoint="0,0"
                                        EndPoint="0,1">

                     <GradientStop Color="#FDB6CADF"
                                   Offset="0" />
                     <GradientStop Color="#FCC3C5FF"
                                   Offset="0.1" />
                     <GradientStop Color="#FCC4D0EF"
                                   Offset="0.3" />
                     <GradientStop Color="#FDB7C2DF"
                                   Offset="0.6" />
                     <GradientStop Color="#FE95B3CF"
                                   Offset="0.8" />
                     <GradientStop Color="#FE96AACF"
                                   Offset="1" />
                   </LinearGradientBrush>

                 <LinearGradientBrush x:Key="ButtonUpGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                      <GradientStop Color="Transparent"
                                    Offset="0" />
                      <GradientStop Color="#33000000"
                                    Offset="1" />

                 </LinearGradientBrush>

                 <LinearGradientBrush x:Key="ButtonDownGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                      <GradientStop Color="#10000000"
                                    Offset="0" />
                      <GradientStop Color="#20000000"
                                    Offset="1" />

                 </LinearGradientBrush>

                 <LinearGradientBrush x:Key="ButtonDisabledGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                      <GradientStop Color="#10302A90"
                                    Offset="0" />
                      <GradientStop Color="#10201040"
                                    Offset="1" />

                 </LinearGradientBrush>


                   <!-- BUTTON TEMPLATE -->

                   <Style TargetType="{x:Type Button}">
                      <Setter Property="Template">
                        <Setter.Value>
                           <ControlTemplate TargetType="{x:Type Button}">
                              <Border x:Name="OuterBorder"
                                       CornerRadius="3"
                                       Background="{DynamicResource ButtonGradient}">




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 93                                                                                        Return to Table of Contents




                               <Border x:Name="InnerBorder"
                                  CornerRadius="3"
                                  Background="{DynamicResource ButtonUpGradient}"
                                  Padding="{TemplateBinding Padding}">
                                  <ContentPresenter x:Name="ContentSite"
                                                    HorizontalAlignment="Center"
                                                    VerticalAlignment="Center" />
                               </Border>
                            </Border>
                            <ControlTemplate.Triggers>
                               <Trigger Property="IsPressed" Value="true">
                                  <Setter TargetName="InnerBorder"
                                          Property="Background"
                                          Value="{DynamicResource ButtonDownGradient}" />
                               </Trigger>
                               <Trigger Property="IsEnabled" Value="false">
                                  <Setter TargetName="InnerBorder"
                                      Property="Background"
                                      Value="{DynamicResource ButtonDisabledGradient}" />
                                  <Setter Property="BorderBrush" Value="Silver" />
                                  <Setter Property="Foreground" Value="SlateGray" />
                               </Trigger>
                            </ControlTemplate.Triggers>
                         </ControlTemplate>
                     </Setter.Value>
                   </Setter>
                   <Setter Property="Height" Value="18" />
                   <Setter Property="Foreground" Value="MidnightBlue" />
                </Style>
            </Window.Resources>
            <StackPanel Height="200">

               <Button Width="200"
                       VerticalAlignment="Center">Press Me!</Button>
            </StackPanel>
         </Window>



This code will be a lot more familiar to those readers who are comfortable with Cascading
Style Sheets than to those who come to WPF from Windows Forms.


       NOTE
       For more on CSS we strongly recommend CSS The Definitive Guide (3rd Edition) by
       Eric Meyer (O'Reilly Media, 0596527330) for a solid introduction, and The Zen of CSS
       Design: Visual Enlightenment for the Web by Dave Shea and Molly Holzschlag (Peachpit
       Press, 032130347) for insight into how CSS can help you create magnificent web sites.

Let's walk through this XAML section by section to see what it does.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 94                                                                                        Return to Table of Contents




                                                                 Linear Gradient


    A linear gradient paints a color along a line, with that color changing gradually as
    it moves along the line. (The gradual change can be interrupted by abrupt changes
    to a new color using GradientStop objects).
    The linear gradient is typically along a diagonal, though this is not required. In any
    case, the line for the linear gradient is determined by a start point and an end
    point, typically designated by a pair of x,y coordinates, designating the upper left
    and lower right of the area being filled, as illustrated in


                                                 Figure 3-9. Linear Gradient Illustration From Microsoft




The first set of steps is to declare the Window, put in the customary namespaces and then
to declare a Resources section. Resources provide the ability to share styles or elements
throughout the UI, and they must be explicitly declared. In this case, we are declaring
resources for the Window...

     <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Programming .NET 3 | Adding flavor to controls">

         <Window.Resources>



3.1.4.1. The Resource Section
The first resource we are declaring is a LinearGradientBrush, which you can easily guess is a
specialized brush for creating LinearGradients; that is, gradients that fall off at a steady rate.
You declare the start and end point (see side bar on Linear Gradients) and within the
definition of the Brush you declare one or more GraidentStop elements. These correspond
to the collection of GraidentStop objects associated with a LinearGradient brush object, and
each Gradient stop specifies both a color and an offset along the gradient axis. In short, the
Brush determines the rate of change of the gradient, and the stops determine the color
transitions and where along the gradient the colors change.

              <LinearGradientBrush x:Key="ButtonGradient"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 95                                                                                        Return to Table of Contents



                                               StartPoint="0,0"
                                               EndPoint="0,1">

                 <GradientStop Color="#FDB6CADF"
                               Offset="0" />

You declare LinearGradientBrush objects for each state of the button: the button itself, then
the Button when pressed (ButtonDownGradient), when released (ButtonUpGradient), and,
for completeness, when disabled (ButtonDisabledGradient).

3.1.4.2. Styles
The first line in the next section indicates that we are setting a style and that the target of the
style is a Button. The target is set by the property TargetType, and identified by the Type
property within the namespace http://schemas.microsoft.com/winfx/2006/xaml (for which
we created the alias "x," at the top of the file).

     <Style TargetType="{x:Type Button}">

Below this line we add a Setter element. Setters are used to apply a Style or a Trigger to
elements of a specific type (in our case, all Butons). The setter declares the attributes to be
set, the target type and the values we'll set for the attribute.
Here is how the setter is used in our case line by line

                                                            Table 3-1. Setter Element Line By Line

                                                      Property is a required field, names the attribute being set. In this case, we
         Setter Property="Template">                  are indicating that this is a template for how buttons should look inside the
                                                      scope of this declaration.
                                                      Opening of the required value element which indicates the value for the attribute (in case
        <Setter.Value>                                for the template attribute)

                                                      The value will be set by using a ControlTemplate whose target type is a Button.
        <ControlTemplate                              ControlTemplates are part of the WPF
        TargetType="{x:Type Button}">



                                                      This button will have an outer border defined as having a corner
        <Border x:Name="OuterBorder"
                                                      radius of 3 (that is, it will be a rounded-rectangle) and the
        CornerRadius="3"
                                                      gradient will be defined in this local resource dictionary and thus
        Background="{StaticResource
        ButtonGradient}">                             is static.
                                                      Not to reader, to see the effect of the rounding, try changing the
                                                      CornerRadius value to 10, making the button look more like a
                                                      bullet.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 96                                                                                        Return to Table of Contents




                                                      Property is a required field, names the attribute being set. In this case, we
         Setter Property="Template">                  are indicating that this is a template for how buttons should look inside the
                                                      scope of this declaration.

                                                      Within the outer border definition we define the inner border
        <Border x:Name="InnerBorder"
                CornerRadius="10"                     which also sets the background, but this time using the
        Background="{StaticResource
        ButtonUpGradient}"                            buttonUpGradient.
        Padding="{TemplateBinding                     Padding is used to put padding around the content.
        Padding}">
                                                      ContentPresenter is used to display the text of the button, and
           <ContentPresenter
        x:Name="ContentSite"                          all of this (innerBorder) is wrapped within the outerBorder Border
        HorizontalAlignment="Center"                  element
        VerticalAlignment="Center" />
        </Border>




                                                      Triggers are used to fire off events on the controls that this template is describing (in our
        <ControlTemplate.Triggers>                    case, buttons)

                                                      When the button is pressed, this trigger causes the ButtonDownGradient to be drawn in the
        <Trigger Property="IsPressed"                 InnerBorder
                 Value="true">
           <Setter
        TargetName="InnerBorder"
                   Property="Background"

        Value="{DynamicResource
        ButtonDownGradient}" />
        </Trigger>


                                                      This trigger is fired if the IsEnabled property is set to false. In that case, the InnerBorder
        <Trigger Property="IsEnabled"                 background property is set to the StaticResource value ButtonDisabledGradient and the
                 Value="false">                       BorderBrush is set to Silver and the Foreground color is set to SlateGray.
           <Setter
        TargetName="InnerBorder"
                   Property="Background"
        Value="{StaticResource
        ButtonDisabledGradient}" />
           <Setter
        Property="BorderBrush"
                   Value="Silver" />
           <Setter Property="Foreground"
                   Value="SlateGray" />
        </Trigger>


                                                      All the open tags we've been working with are closed and the setter is complete
                            </Trigger>

        </ControlTemplate.Triggers>
                 </ControlTemplate>
              </Setter.Value>
           </Setter>


                                                      Two more setters are used to set general style properties of the button
        <Setter Property="Height"
                  Value="18" />
          <Setter Property="Foreground"
                  Value="MidnightBlue" />




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 97                                                                                        Return to Table of Contents




                                                      Property is a required field, names the attribute being set. In this case, we
         Setter Property="Template">                  are indicating that this is a template for how buttons should look inside the
                                                      scope of this declaration.
                                                      The style element is closed off, the Resources element is closed off and a stackPanel is created
                </Style>                              in which a button is created.. That finishes off the Window.
             </Window.Resources>
             <StackPanel Height="200">

               <Button Width="200"
        VerticalAlignment="Center">Press
        Me!</Button>
        </StackPanel>
        </Window>




All of this looks a bit daunting at first, but notice that at no time did you have to go into a
drawing program and to create an image button; you described an image button in XAML
and it was drawn for you based on that description. That is pretty neat. The result is shown
in Figure 5-10

                                                                   Figure 3-10. Gradient Button




3.1.4.3. Making Effects More Pronounced
We strongly encourage you to "play" with these examples to make the effects more
pronounced and see what happens. For example, I modified the colors in the gradient,
substituting primary rainbow colors,

     <LinearGradientBrush x:Key="ButtonGradient"
                                StartPoint="0,0"
                                EndPoint="0,1">

                 <GradientStop Color="Red"



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 98                                                                                        Return to Table of Contents



                             Offset="0" />
               <GradientStop Color="Orange"
                             Offset="0.1" />
               <GradientStop Color="Yellow"
                             Offset="0.3" />
               <GradientStop Color="Green"
                             Offset="0.6" />
               <GradientStop Color="Blue"
                             Offset="0.8" />
               <GradientStop Color="Violet"
                             Offset="1" />
            </LinearGradientBrush>

and greatly increased the size of the button

              <Setter Property="Height" Value="40" />
               <Setter Property="Foreground" Value="BLUE" />
            </Style>
        </Window.Resources>
        <StackPanel Height="400">

to make the gradient effect much more obvious, as shown in Figure 5-11

                                                                   Figure 3-11. Rainbow Button




3.1.4.4. Using Built-in graphic primitives Inside Controls
To really master how your controls appear you can combine 2-D graphics with built-in
controls and make what look like image buttons but are actually drawn dynamically and
declaratively as illustrated in Example 5-7




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 99                                                                                        Return to Table of Contents



Example 3-7. Combining Graphics with Controls


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Programming Methodology Graphic">

            <StackPanel Height="200">
               <Button Width="200" VerticalAlignment="Center">
                               <StackPanel Orientation="Horizontal">
                     <Canvas Width="30"
                            Height="30"
                            VerticalAlignment="Center"
                            Margin="3">
                       <Ellipse Canvas.Left="1"
                                 Canvas.Top="1"
                                 Width="30"
                                 Height="30"
                                 Fill="White"
                                 Stroke="Black" />
                       <Ellipse Canvas.Left="4"
                                 Canvas.Top="4"
                                 Width="24"
                                 Height="24"
                                 Fill="Black"
                                 Stroke="Black" />
                       <Ellipse Canvas.Left="8"
                                 Canvas.Top="8"
                                 Width="16"
                                 Height="16"
                                 Fill="Blue"
                                 Stroke="Blue" />
                       <Ellipse Canvas.Left="11"
                                 Canvas.Top="11"
                                 Width="10"
                                 Height="10"
                                 Fill="Red"
                                 Stroke="Red" />
                       <Ellipse Canvas.Left="14"
                                 Canvas.Top="14"
                                 Width="4"
                                 Height="4"
                                 Fill="Yellow"
                                 Stroke="Yellow" />
                    </Canvas>
                    <TextBlock VerticalAlignment="Center"> Ready, Fire, Aim!</TextBlock>
                 </StackPanel>
               </Button>
            </StackPanel>
         </Window>



In Example 5-7 we insert a StackPanel inside a Button control (as promised earlier in the
chapter). Within the stack panel we place a number of ellipse elements, creating a classic
"bulls-eye" as shown in Figure 5-12

                                                                   Figure 3-12. Ready Fire Aim




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 100                                                                                       Return to Table of Contents




3.2. Resources
Resources provide your XAML with a way to define and share styles or elements. You can
share resources at the page (window) level, or throughout an entire application (or even
across an entire system!).
The definition of the resource section of your XAML is referred to as the Resource Dictionary.
To create a resource that is scoped to a single window you use the element

     <Window.Resources>

As shown in Example 5-8

Example 3-8. A static resource scoped to a single window


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Resources">
             <Window.Resources>
                        <SolidColorBrush x:Key="GreenBrush" Color="Green" />
                        </Window.Resources>
             <Viewbox>
                   <TextBlock Foreground="{StaticResource GreenBrush}">
                        Little Green Men
                   </TextBlock>
             </Viewbox>
         </Window>



The resource is applied to a TextBlock by applying setting the foreground value to the
resource itself. The keyword StaticResource indicates that the resource is pre-defined (the
alternative is a dynamic resource which will be set at run time and may be dependent on the
state of other objects on the page). The result of applying the GreenBrush resource to the
TextBlock is shown in Figure 5-13

                                                     Figure 3-13. StaticResource used to color the text




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 101                                                                                       Return to Table of Contents




3.3. Transformations
While there is much that can be written about 2-D graphics, one of the more interesting (and
at times confusing) aspects of taking control of graphics is transformations — the art of
transforming the up/down orientation of the page.
WPF makes simple transformations very simple, as shown in Example 5-9

Example 3-9. Simple Transform


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | Transformations: Rotate">
                   <Border Margin="30"
            HorizontalAlignment="Left" VerticalAlignment="Top"
            BorderBrush="Black" BorderThickness="1" >
           <StackPanel Orientation="Vertical">
             <Button Content="Top Button" Opacity="1" />
             <Button Content="Middle Button" Opacity="1" />
             <Button Content="Rotated Button">
              <Button.RenderTransform>
               <RotateTransform Angle="45" />
              </Button.RenderTransform>
             </Button>

           </StackPanel>
         </Border>
         </Window>



In this example, we create Three Buttons. The third button has a RenderTransform applied
to it, and the RenderTransform has a child element: RotateTransform whose attribute is an
angle (in this case 45 degrees). The button is rendered rotated 45° clock-wise, as shown in
Figure 5-14

                                                              Figure 3-14. Simple Transformation




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 102                                                                                       Return to Table of Contents




3.4. Animation
The power of transformations is greatly enhanced when combined with animation — rotate
an object? Interesting. Rotate an object in front of my eyes? Much more interesting.
To animate an object in the WPF that object must meet just three requirements:

  1. It must be a dependency property (see sidebar)
  2. It must belong to a class that inherits from DependencyObject and implements
     IAnimatable (Controls such as Button, Panel and Shape all inherit from
     DependencyObject, and implement IAnimatable, so this is almost never a problem)
  3. There must be a compatible animation type available (or you can create your own)



                                           Dependency And Attached Properties


    Dependency properties exist to allow for the creation of "attached properties," —
    that is the ability of one class to "attach" properties to another. This is what allows
    a canvas (for example) to "attach" properties to an Ellips (for example) so that you
    can write

         <Canvas Width="180" Height="180" VerticalAlignment="Center">
            <Ellipse Canvas.Left="10" Canvas.Top="10" Width="160" Height="160"
                   Fill="LimeGreen" Stroke="Black" />

    As you did in Example 5-4 even though Ellipse does not have a Left or Top property.

The typical steps for animation are to pick a property to animate. In the next example we'll
animate the Button's angle, which is of type Double and so we'll use a DoubleAnimation to
create a transition between two double values (typically referred to as the From and To
properties). You must also specify a Duration — the tiem it takes to go from the starting value
to the destination value. The longer the time, the slower the animation.
The second step is to create a Storyboard which designates where to apply the animation
(the TargtName) which designates the object to animate (in our next case, the button).
Finally, the StoryBoard must be associated with a Trigger — an event that will kick off the
animation. This is all illustrated in Example 5-10




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 103                                                                                       Return to Table of Contents



Example 3-10. Rotating a Button on Click


         <Page
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title=" Programming .NET 3 | Graphics: Animated Rotation"
           Background="White" Margin="50">
           <StackPanel>

                <Button Content="Slow Spinning Button" Width="200"
                 RenderTransformOrigin="0.5,0.5">
                 <Button.RenderTransform>
                   <RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
                 </Button.RenderTransform>
                 <Button.Triggers>
                    <EventTrigger RoutedEvent="Button.Click">
                     <BeginStoryboard>
                       <Storyboard>
                          <DoubleAnimation
                            Storyboard.TargetName="AnimatedRotateTransform"
                            Storyboard.TargetProperty="Angle"
                            To="360" Duration="0:0:5" FillBehavior="Stop" />
                       </Storyboard>
                     </BeginStoryboard>
                   </EventTrigger>
                 </Button.Triggers>
                </Button>

           </StackPanel>
         </Page>



If you put this in XAML Pad and click the button, it will rotate through a full rotation in 5
seconds.

     <Storyboard>
       <DoubleAnimation
        Storyboard.TargetName="AnimatedRotateTransform"
        Storyboard.TargetProperty="Angle"
         To="360" Duration="0:0:5" FillBehavior="Stop" />
     </Storyboard>

The animation will be set off by clicking on the button

     <EventTrigger RoutedEvent="Button.Click">




3.4.1.

3.4.1.1. Simultaneous Animations
Your StoryBoard need not be restricted to running a single DoubleAnimation, nor need it
stop after a single well defined event (one complete rotation). You can combine movement
vertically with movement horizontally to create diagonal movement, and you can repeat
that movement indefinitely, as shown in Example 5-11




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 104                                                                                       Return to Table of Contents



Example 3-11. Diagonal Movement Through Paired DoubleAnimations


         <Window
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title="Programming .NET 3 | Simple LGM Animation"
           Background="White" Margin="50">

                <Window.Triggers>
                      <EventTrigger RoutedEvent="Window.Loaded">
                        <BeginStoryboard Name="LGMMoverStoryboard">
                                  <Storyboard>
                                  <DoubleAnimation
                                  Storyboard.TargetName="LGMCanvas"
                                  Storyboard.TargetProperty="Height"
                                  From="10" To="600" Duration="0:0:5" RepeatBehavior="Forever" />

                                          <DoubleAnimation
                                          Storyboard.TargetName="LGMCanvas"
                                          Storyboard.TargetProperty="Width"
                                          From="10" To="600" Duration="0:0:5" RepeatBehavior="Forever" />
                                          </Storyboard>

                                 </BeginStoryboard>
                      </EventTrigger>
                </Window.Triggers>

                         <Canvas Width="180" Height="180"
                                  VerticalAlignment="Center" x:Name="LGMCanvas">
                              <Ellipse Canvas.Left="10" Canvas.Top="10" Width="160" Height="160"
                                     Fill="LimeGreen" Stroke="Black" />
                              <Ellipse Canvas.Left="45" Canvas.Top="50" Width="25" Height="25"
                                     Fill="Black" Stroke="Black" />
                              <Ellipse Canvas.Left="77.5" Canvas.Top="50" Width="25" Height="25"
                                     Fill="Black" Stroke="Black" />
                              <Ellipse Canvas.Left="110" Canvas.Top="50" Width="25" Height="25"
                                     Fill="Black" Stroke="Black" />
                              <Path Data="M 50,100 A 30,30 900 0 0 130,100" Stroke="Black"/>
                           </Canvas>
         </Window>



Notice that the trigger for this event is loading the window itself; this animation begins as
soon as the program begins, and never ends until the program is closed,

     <EventTrigger RoutedEvent="Window.Loaded">




3.4.2. A Composite Control
With the WPF controls and drawing capabilities and resources under your belt, you can mix
and match them and then combine them, adding subtle animation to create composite-
controls that provide you with very powerful presentation mechanics that you can reuse in
many different formats. To illustrate this idea, we'll create a slider that displays images of the
presidents of the United States retrieved from the White House Web site in this chapter, and
then reuse this code in our business example in the next chapter. The code is shown,
complete in Example 5-12.




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 105                                                                                       Return to Table of Contents



Example 3-12. Composite Control: Image Slider


         <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Programming .NET 3 | US Presidents"
            Background="White"
            Margin="50">
            <Window.Resources>

                 <LinearGradientBrush x:Key="ListBoxGradient"
                                      StartPoint="0,0"
                                      EndPoint="0,1">

                      <GradientStop Color="#90000000"
                                    Offset="0" />
                      <GradientStop Color="#40000000"
                                    Offset="0.005" />
                      <GradientStop Color="#10000000"
                                    Offset="0.04" />
                      <GradientStop Color="#20000000"
                                    Offset="0.945" />
                      <GradientStop Color="#60FFFFFF"
                                    Offset="1" />

                   </LinearGradientBrush>


                   <Style x:Key="SpecialListStyle"
                          TargetType="{x:Type ListBox}">
                      <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBox}" >
                               <Border BorderBrush="Gray"
                                  BorderThickness="1"
                                  CornerRadius="6"
                                  Background="{DynamicResource ListBoxGradient}" >
                                  <ScrollViewer VerticalScrollBarVisibility="Disabled"
                                      HorizontalScrollBarVisibility="Auto">
                                      <StackPanel IsItemsHost="True"
                                        Orientation="Horizontal"
                                        HorizontalAlignment="Left" />
                                  </ScrollViewer>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                      </Setter>
                   </Style>

                   <Style x:Key="SpecialListItem"
                          TargetType="{x:Type ListBoxItem}">
                      <Setter Property="MaxHeight"
                              Value="75"/>
                      <Setter Property="MinHeight"
                              Value="75" />
                      <Setter Property="Opacity"
                              Value=".75" />
                      <Style.Triggers>
                        <EventTrigger RoutedEvent="Mouse.MouseEnter">
                            <EventTrigger.Actions>
                              <BeginStoryboard>
                                 <Storyboard>
                                    <DoubleAnimation Duration="0:0:0.2"
                                       Storyboard.TargetProperty="MaxHeight"
                                       To="85" />
                                     <DoubleAnimation Duration="0:0:0.2"
                                       Storyboard.TargetProperty="Opacity"
                                       To="1.0" />
                                 </Storyboard>
                              </BeginStoryboard>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 106                                                                                       Return to Table of Contents




                             </EventTrigger.Actions>
                          </EventTrigger>

                     <EventTrigger RoutedEvent="Mouse.MouseLeave">
                         <EventTrigger.Actions>
                            <BeginStoryboard>
                               <Storyboard>
                                  <DoubleAnimation Duration="0:0:1"
                                     Storyboard.TargetProperty="MaxHeight" />
                                  <DoubleAnimation Duration="0:0:0.2"
                                     Storyboard.TargetProperty="Opacity" />
                               </Storyboard>
                             </BeginStoryboard>
                         </EventTrigger.Actions>
                     </EventTrigger>
                  </Style.Triggers>
                </Style>
            </Window.Resources>
             <Grid Width="300"
                   Height="150">
                <StackPanel>
                   <TextBlock FontSize="14">United States Presidents</TextBlock>
                   <ListBox Style="{StaticResource SpecialListStyle}"
                             Grid.Row="1"
                             Grid.ColumnSpan="3"
                             Name ="PhotoListBox"
                             Margin="0,0,0,20"

                                 ItemsSource="{Binding}"
                                 ItemContainerStyle="{StaticResource SpecialListItem}"
                                 SelectedIndex="0">
                          <ListBoxItem>
                              <Image Source=
                                 "https://www.naymz.com/media/images/306/portrait-portrait.jpg" />
                          </ListBoxItem>
                          <ListBoxItem>
                              <Image Source=
                                 "http://www.whitehouse.gov/history/presidents/images/bc42.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                              <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gb41.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/rr40.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jc39.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gf38.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/rn37.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/lj36.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jk35_1.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 107                                                                                       Return to Table of Contents




                          "http://www.whitehouse.gov/history/presidents/images/de34.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ht33.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/fr32.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/hh31.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/cc30.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wh29.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ww28.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/tr26.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wt27.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wm25.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gc2224.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/bh23.gif" />
                          </ListBoxItem>

                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ca21.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jg20.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/rh19.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ug18.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ag17.gif"                                    />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 108                                                                                       Return to Table of Contents




                          "http://www.whitehouse.gov/history/presidents/images/al16.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jb16.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/fp14.gif" />
                          </ListBoxItem>

                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/mf13.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/zt12.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jp11.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                              <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jt10.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/wh9.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/mb8.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/aj7.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ja6.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jm5.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/jm4.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/tj3.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/ja2.gif" />
                          </ListBoxItem>
                          <ListBoxItem>
                             <Image Source=
                          "http://www.whitehouse.gov/history/presidents/images/gw1.gif" />
                          </ListBoxItem>

                 </ListBox>
              </StackPanel>
           </Grid>
         </Window>




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 109                                                                                       Return to Table of Contents



Nothing in this code is new, it has just been put together in new ways. We start with declaring
a resource section in which we declare a LinearGradientBrush with GradientStops for the
colors we want along the gradient.
A Style is created for the List and targeted at the ListBox, setting the Border thickness to Grey
and rounding the corners. The Vertical Scroll Bar is turned off, the Horizontal scroll bar is set
to automatic (so that if the width of the control is insufficient to show all the images the user
can scroll through them).
A Second style is created in the resources for the items in the list box. Their minimum and
maximum height is set as well as their opacity, and a trigger is set for pasing the mouse over
the item. When the event fires (when the user hovers over an image) an animation begins
which inflates the image to its maximum height and increases the images opacity to 100%.
The second trigger fires when the user's mouse moves away: the image deflates to the
minimum size and the opacity reduces to 75%, making the image somewhat less vivid. The
effect is very pronounced, and can be seen quite clearly in Figure 5-15

                                                                    Figure 3-15. US Presidents




3.5. Data Binding
Sooner or later (sooner if you are writing typical commercial applications), you need to
associate your presentation widgets with persistent data. That data may come from the
Internet, or it may come from XML files, email, your operating system, or -- most often -- from
a database. Okay, let's be blunt; most often from a relational database, and if you're
programming in the Microsoft world, we'll go so far as to say, most often from SQL Server
(though both authors have certainly written commercial applications that used gigabytes of
data from databases that were not written in Redmond!)
The ability to bind a control to a data source is critical to creating efficient professional
programs, and WPF would be nothing more than a very impressive toy if it did not support


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 110                                                                                       Return to Table of Contents



the sophisticated data-binding that ASP.NET and Windows Forms programmers have grown
accustomed to.

3.5.1.

3.5.1.1. Switching to Visual Studio
For the next example, we're going to combine XAML and a business class. Fire up Visual
Studio and create a new WPF application named CheckOut. Begin by creating a new class
ShoppingCartItem.cs as shown in Example 5-13




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                    Page 111                                                                                                    Return to Table of Contents



Example 3-13. Shopping Cart Item.cs


         using System;
         using System.Collections.Generic;
         using System.Text;

         namespace CheckOut
         {
            public class ShoppingCartItem
            {
               private string item, value, shortDescription;
               private int sku;

                   public ShoppingCartItem(
                      string item,
                      string value,
                      string shortDescription,
                      int sku)
                   {
                      this.item = item;
                      this.value = value;
                      this.shortDescription = shortDescription;
                      this.sku = sku;
                   }


                   public string Item
                   {
                      get { return this.item; }
                      set { this.item = value; }
                   }

                   public string Value
                   {
                      get { return this.value; }
                      set { this.value = value; }
                   }

                   public string ShortDescription
                   {
                      get { return this.shortDescription; }
                      set { this.shortDescription = value; }
                   }

                   public int SKU
                   {
                      get { return this.sku; }
                      set { this.sku = value; }
                   }

              }
         }



This class has nothing but four values: three strings and an integer. In keeping with accepted
Data Hiding rules, we've made all four private member variables, and provided properties

for accessing the four values.[                                  ]




        [ ] For a discussion on whether or not this is in fact good design or just mindless superstition, see Jesse's article, Programmer Superstitions at http://simple-talk.com/author/
        jesse-liberty/


In the Window1.xaml file add the XAML code to define the presentation layer as shown in
Example 5-14


Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 112                                                                                       Return to Table of Contents



Example 3-14. XAML for Shopping Cart


         <Window x:Class="CheckOut.Window1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:CheckOut"
             Title="Programming .NET 3 | Data Binding 101" Height="100" Width="380" >
           <Window.Resources>
              <local:ShoppingCartItem x:Key="Cart"
                                      SKU="1568"
                                      Item="Photograph"
                                      Value="$19.99"
                                      ShortDescription="A beautiful picture of a dolphin"/>
           </Window.Resources>


              <Grid DataContext="{StaticResource Cart}"
                    Margin="3"
                    Width="360"
                    HorizontalAlignment="Left">
                <Grid.RowDefinitions>
                    <RowDefinition Height="20"/>
                    <RowDefinition Height="20"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="40"/>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition />
                    <ColumnDefinition Width="40"/>
                </Grid.ColumnDefinitions>

                   <TextBlock Grid.Column="0"
                              Grid.Row="0">SKU</TextBlock>
                   <TextBlock Grid.Column="1"
                              Grid.Row="0">Item</TextBlock>
                   <TextBlock Grid.Column="2"
                              Grid.Row="0">Description</TextBlock>
                   <TextBlock Grid.Column="3"
                              Grid.Row="0">Price</TextBlock>



                   <TextBlock Grid.Column="0"
                              Grid.Row="1"
                              Text="{Binding Path=SKU}" />
                   <TextBlock Grid.Column="1"
                              Grid.Row="1"
                              Text="{Binding Path=Item}" />
                   <TextBlock Grid.Column="2"
                              Grid.Row="1"
                              Text="{Binding Path=ShortDescription}" />
                   <TextBlock Grid.Column="3"
                              Grid.Row="1"
                              Text="{Binding Path=Value}" />

              </Grid>

         </Window>



In the resources section you declare an instance of a shopping art, setting the various
properties declaratively. You then create a grid, setting its DataContext to the Cart you
declared in the resources section (and thus binding the data from the resources section to
the presentation you are now declaring).



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 113                                                                                       Return to Table of Contents



You define a pair of rows and four columns. That done you define your first four TextBlocks,
assigning them to the four columns, all within the first row; these serve as headers.
In the second set of TextBlocks you set the Text using the binding syntax,

     <TextBlock Grid.Column="0"
                Grid.Row="1"
                Text="{Binding Path=SKU}" />

This sets the TextBlock into column 0 of Row 1 and states that the Text will come from binding
to a data source whose path is set in the resource whose name was defined earlier as "SKU".
We saw that definition of SKU in the Resources section,

     <Window.Resources>
       <local:ShoppingCartItem x:Key="Cart"
                               SKU="1568"

In this case, the value for SKU is defined in place, but it could also be dynamically retrieved
from a database or web service.
When you run this, a window is opened, and the grid is filled with both the header row and
the second row bound to the "ShoppingCartItem" as shown in Figure 5-16

                                                    Figure 3-16. The results of our simple data binding




3.5.2. Binding to a list
To create a list of items in the shopping cart, you'll rename your ShoppingCart class to
ShoppingCartList and create a new class ShoppingCart which will derive from (and allow you
to instantiate) a List<ShoppingCartItems>. To be explicit, your ShoppingCartItem.cs file now
looks like




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 114                                                                                       Return to Table of Contents



Example 3-15. ShoppingCartItem.cs


         using System;
         using System.Collections.Generic;
         using System.Text;

         namespace CheckOutList
         {
            public class ShoppingCart : List<ShoppingCartItem>
                           {
                           }


              public class ShoppingCartItem
              {
                 private string item, value, shortDescription;
                 private int sku;

                   public ShoppingCartItem()
                               {
                               item = string.Empty;
                               value = string.Empty;
                               shortDescription = string.Empty;
                               sku = -1;
                               }

                   public ShoppingCartItem(
                      string item,
                      string value,
                      string shortDescription,
                      int sku)
                   {
                      this.item = item;
                      this.value = value;
                      this.shortDescription = shortDescription;
                      this.sku = sku;
                   }


                   public string Item
                   {
                      get { return this.item; }
                      set { this.item = value; }
                   }

                   public string Value
                   {
                      get { return this.value; }
                      set { this.value = value; }
                   }

                   public string ShortDescription
                   {
                      get { return this.shortDescription; }
                      set { this.shortDescription = value; }
                   }

                   public int SKU
                   {
                      get { return this.sku; }
                      set { this.sku = value; }
                   }

              }
         }



Make sure you include a default constructor for your ShoppingCartItem class.



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 115                                                                                       Return to Table of Contents



Your next step is to modify the resources in your XAML file to create a collection of
ShoppingCartItems,

     <Window.Resources>
        <local:ShoppingCart x:Key="Cart">
          <local:ShoppingCartItem SKU="1568"
                                  Item="Photograph"
                                  Value="$19.99"
                                  ShortDescription="A beautiful picture of a dolphin"/>
          <local:ShoppingCartItem SKU="1569"
                                  Item="Matting"
                                  Value="$29.99"
                                  ShortDescription="1 inch double matting"/>
          <local:ShoppingCartItem SKU="1570"
                                  Item="Frame"
                                  Value="$39.99"
                                  ShortDescription="Natural Wood Frame ( 8 x 11)"/>
          <local:ShoppingCartItem SKU="1571"
                                  Item="UV Glass"
                                  Value="$9.99"
                                  ShortDescription="UV Glass for 8 x 11frame"/>
       </local:ShoppingCart>
     </Window.Resources>

You are now ready to display these items. You can't just use TextBlocks in a grid, since in
theory (eventually) you won't know how many items you're going to display.
What you want to do is to create a listBox, and display the items in the list box. That doesn't
mean you have to give up control of the display layout, howevr. While a DataTemplate in a
listbox can only have one control within it (in our case, a Stack panel whose orientation will
be Horizontal to hold one "row"), that control can itself have many child controls.
We'll give the StackPanel four child StackPanels, each set to a Vertical orientation, and each
with a width equal to that of the header column so that our values line up nicely, as shown
in




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 116                                                                                       Return to Table of Contents



Example 3-16. XAML for Displaying a list of items


         <Window x:Class="CheckOutList.Window1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:local="clr-namespace:CheckOutList"
                  Title="CheckOutList" Height="300" Width="430"
             >
           <Window.Resources>
               <local:ShoppingCart x:Key="Cart">
                  <local:ShoppingCartItem SKU="1568"
                                          Item="Photograph"
                                          Value="$19.99"
                                     ShortDescription="A beautiful picture of a dolphin"/>
                  <local:ShoppingCartItem SKU="1569"
                                          Item="Matting"
                                          Value="$29.99"
                                          ShortDescription="1 inch double matting"/>
                   <local:ShoppingCartItem SKU="1570"
                                          Item="Frame"
                                          Value="$39.99"
                                          ShortDescription="Natural Wood Frame ( 8 x 11)"/>
                  <local:ShoppingCartItem SKU="1571"
                                          Item="UV Glass"
                                          Value="$9.99"
                                          ShortDescription="UV Glass for 8 x 11frame"/>
               </local:ShoppingCart>
           </Window.Resources>

              <!-- the heading-->
              <Grid DataContext="{StaticResource Cart}"
                   Margin="15"
                   Width="430"
                   HorizontalAlignment="Left">
               <Grid.RowDefinitions>
                   <RowDefinition Height="20"/>
                   <RowDefinition Height="200"/>
                   <RowDefinition/>
               </Grid.RowDefinitions>
               <Grid.ColumnDefinitions>
                   <ColumnDefinition Width="40"/>
                   <ColumnDefinition Width="100"/>
                   <ColumnDefinition Width="180" />
                   <ColumnDefinition Width="40"/>
                </Grid.ColumnDefinitions>

                   <TextBlock Grid.Column="0"
                             Grid.Row="0">SKU</TextBlock>
                   <TextBlock Grid.Column="1"
                             Grid.Row="0">Item</TextBlock>
                   <TextBlock Grid.Column="2"
                             Grid.Row="0">Description</TextBlock>
                   <TextBlock Grid.Column="3"
                             Grid.Row="0">Price</TextBlock>

              <!-- the list box to display all the contents of the cart -->
                             <ListBox Grid.Column="0"
                             Grid.Row="1"
                             Grid.ColumnSpan="4"
                             ItemsSource="{Binding}"
                             Width="360">
                             <ListBox.ItemTemplate>
                             <DataTemplate>

                                     <!-- the outer StackPanel (one per row) -->
                                     <StackPanel Orientation="Horizontal" Width="350">

                                     <!-- the inner stack panels — one per column -->
                                    <StackPanel Orientation="Vertical" Width="40">
                                       <TextBlock Text="{Binding Path=SKU}" />




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 117                                                                                       Return to Table of Contents




                                    </StackPanel>
                                    <StackPanel Orientation="Vertical" Width="100">
                                       <TextBlock Text="{Binding Path=Item}" />
                                    </StackPanel>
                                    <StackPanel Orientation="Vertical" Width="170">
                                       <TextBlock Text="{Binding Path=ShortDescription}" />
                                    </StackPanel>
                                    <StackPanel Orientation="Vertical" Width="40">
                                       <TextBlock Text="{Binding Path=Value}" />
                                    </StackPanel>

                                     </StackPanel>
                                     </DataTemplate>
                                     </ListBox.ItemTemplate>
                                     </ListBox>


            </Grid>
         </Window>



The leap of imagination you must make is that we can bind to an unknown number of items,
and this list box will simply add each item, one by one, with the outer stack panel describing
what each entry in the list box looks like, and the inner stack panels describing what each
"column" of information (the sku, item, short description and value" look like and where they
are placed. The result is shown in Figure 5-17

                                                                    Figure 3-17. Check out List




3.5.3. Master Detail
One of the most common and powerful data representation is the master/detail or order/
detail record. A classic example is looking at my recent orders on Amazon.com (http://
www.Amazon.com) as shown in Figure 5-18



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 118                                                                                       Return to Table of Contents



                                                           Figure 3-18. Amazon Order with Details




As you can see, each order can have within it more than one item. These items themselves
have valuable information, including shipping date (or estimated delivery date) etc. It is very
common to have this kind of master (order) / detail relationship throughout virtually any
serious business database.
In the next example, we envision that some detail is too big to put into the list box, and must
be reserved for when the user clicks on an item and thereby asks to see more information.
We'll modify the previous example, first by changing the ShoppingCartItem clas to add a
property long description,

     public string LongDescription
      {
         get { return this.longDescription; }
         set { this.longDescription = value; }
      }

You will, of course, need to add a private string as backing data, and update both constructors.
That done, you'll make more substantial changes to the Widnow1.xaml page. The first change
is to ad a LongDescription to each ShoppingCartItem in the Resources, for example,



Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 119                                                                                       Return to Table of Contents




     <local:ShoppingCartItem SKU="1570"
                      Item="Frame"
                      Value="$39.99"
                      ShortDescription="Natural Wood Frame ( 8 x 11)"
                      LongDescription="Hewn from natural growth forest,                                       hand cut." />

You need to modify the Grid's row definition to make room for the details below the list box.
Let's shorten the list box row from 200 to 100, and add a row for the description,

     <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="100"/>
        <RowDefinition Height="20"/>
       <RowDefinition/>
     </Grid.RowDefinitions>

While we're fussing, we can make the headers bold, by adding the FontWeight style to each
header's TextBlock,

     <TextBlock Grid.Column="0" FontWeight ="Bold"
                Grid.Row="0">SKU</TextBlock>



3.5.3.1. Event Handling
In order for the FullDescription to be displayed when the user clicks on an item in the list box,
we need to take the following steps

  1. Add an event handler to Window1.xaml.cs (the code behind for the window)
  2. Add a delegate to the ListBox telling it which event handler to call when its selection
     changes
  3. Add a TextBlock in the form into which we can place the long description when a choice
     is made in the list box.

Let's begin by adding the TextBlock we need on the form. Below the list box, but before we
close the grid, we'll add two TextBlocks: one as a header for the long description, and the
second to hold the long description when the user clicks in the list box.

     <TextBlock Grid.Column="0" Grid.ColumnSpan="2" FontWeight="Bold"
                Grid.Row="2">Full Description</TextBlock>
     <TextBlock Grid.Column="0"
                Grid.ColumnSpan="4"
                Grid.Row="3"
                Name="LongDescriptionLabel" />

Next, modify the listbox declaration to call a method that you'll add to the code-behind file,

     <ListBox Grid.Column="0"
              Grid.Row="1"
              Grid.ColumnSpan="4"
              ItemsSource="{Binding}"
              SelectionChanged="ShoppingCartSelection"
              Width="360">




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.
Programming .NET 3.0                 Page 120                                                                                       Return to Table of Contents



You must now implement the ShoppingCartSelection method in Window1.xaml.cs. It will
examine the ListBox control, see what was selected, extract from that object (which will be
of type ShoppingCartItem) the LongDescription and place that long description into the
TextBlock you just added to the form. The code is shown in Example 5-17

Example 3-17. ShoppingCartSelection in Window1.xaml.cs


         private void ShoppingCartSelection(object sender, RoutedEventArgs e)
         {
            ListBox lb = sender as ListBox;
            ShoppingCartItem scItem = lb.SelectedItem as ShoppingCartItem;
            LongDescriptionLabel.Text = scItem.LongDescription.ToString();
         }




                         The old C hacker in me is tempted to write the method as follows,

                                    private void ShoppingCartSelection(
                                       object sender, RoutedEventArgs e)
                                    {
                                      LongDescriptionLabel.Text =
                                          ((sender as ListBox).SelectedItem as ShoppingCartItem).LongDescription.
                              ToString();
                                    }

                         But that would be evil.

The complete XAML code is shown in listing Example 5-18
When the user clicks on an item in the list box, the SelectionChanged event is fired, and
ShoppingCartSelection is called in Window1.xaml.cs. The list box is retrieved, the selected
ShoppingCartItem is identified and from that the LongDescription is extracted. That string
is then placed into the TextBlock and displayed, as shown in Figure 5-19

                                                            Figure 3-19. Master Detail List Binding




Programming .NET 3.0
Programming .NET 3.0 By ISBN: 059652756X Publisher: O'Reilly                                                     Prepared for SUNDIN DAN, Safari ID: cisco.alumni@yahoo.com
Print Publication Date: 2007/02/26                                                                              User number: 851621 Copyright 2007, Safari Books Online, LLC.
Reproduction, transmission and/or redistribution in any form by any means without the prior written permission from the publisher is prohibited.

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:100
posted:3/31/2010
language:English
pages:122
Description: In programming in .net you learn how to write program in .net technology