Chapter 1. Introducing WPF. Objectives: Understand the motivation behind WPF. Examine the various flavors of WPF applications

Similar documents
Windows Presentation Foundation. Jim Fawcett CSE687 Object Oriented Design Spring 2018

XAML - BUTTON. The Button class represents the most basic type of button control. The hierarchical inheritance of Button class is as follows

Note: many examples in this section taken or adapted from Pro WPF 4.5 C#, Matthew MacDonald, apress, 2012, pp

XAML. Chapter 2 of Pro WPF : By Matthew MacDonald Assist Lect. Wadhah R. Baiee. College of IT Univ. of Babylon Understanding XAML

Windows Presentation Foundation Programming Using C#

10262A VB: Developing Windows Applications with Microsoft Visual Studio 2010

Introduction p. 1 Who Should Read This Book? p. 2 Software Requirements p. 3 Code Examples p. 3 How This Book Is Organized p. 4 Conventions Used in

DOT NET SYLLABUS FOR 6 MONTHS

Introduction. Thank you for picking up Silverlight 1.0 Unleashed! IN THIS CHAPTER. . Who Should Read This Book?. Software Requirements

Introduction. Part I: Silverlight Fundamentals for ASP.NET Developers 1

Chapter 13. Additional Topics in Visual Basic The McGraw-Hill Companies, Inc. All rights reserved. McGraw-Hill

Chapter 1 Getting Started with Windows Presentation Foundation

Learn to develop.net applications and master related technologies.

COPYRIGHTED MATERIAL. Contents. Part I: C# Fundamentals 1. Chapter 1: The.NET Framework 3. Chapter 2: Getting Started with Visual Studio

Apex TG India Pvt. Ltd.

ALPHAPRIMETECH 112 New South Road, Hicksville, NY 11801

Mastering VB.NET using Visual Studio 2010 Course Length: 5 days Price: $2,500

Developing Windows Applications with Microsoft Visual Studio 2010

DEVELOPING WINDOWS APPLICATIONS WITH MICROSOFT VISUAL STUDIO 2010

DE Developing Windows Applications with Microsoft Visual Studio 2010

Migrate Your Skills to Microsoft.NET Framework 2.0 and 3.0 using Visual Studio 2005 (C#)

CHANNEL9 S WINDOWS PHONE 8.1 DEVELOPMENT FOR ABSOLUTE BEGINNERS

Unit 1: Visual Basic.NET and the.net Framework

Developing Microsoft.NET Applications for Windows (Visual Basic.NET)

HCIM SUMMER WORKSHOP Introduction to C#

Exploring.Net Orcas. Contents. By Punit Ganshani

Chapters and Appendix F are PDF documents posted online at the book s Companion Website (located at

Windows 8. Rainer Stropek. System Architecture. System Architecture re of Windows Store Apps. Saves the day. software architects gmbh

Windows Presentation Foundation (WPF)

NET 3.0 and NET 3.0 contains four building blocks, shown in the figure below:

Developing Windows Applications with Microsoft Visual Studio 2010

Introduction. I hope you find this book to exhibit all of these attributes.

DOT NET Syllabus (6 Months)

DOT.NET MODULE 6: SILVERLIGHT

Visual Studio 2015: Windows Presentation Foundation (using VB.NET Language) Training Course Outline

Windows Presentation Foundation for.net Developers

DEVELOPING WEB APPLICATIONS WITH MICROSOFT VISUAL STUDIO Course: 10264A; Duration: 5 Days; Instructor-led

Part I. Integrated Development Environment. Chapter 2: The Solution Explorer, Toolbox, and Properties. Chapter 3: Options and Customizations

The C# Programming Language. Overview

Chapters are PDF documents posted online at the book s Companion Website (located at

HPE WPF and Silverlight Add-in Extensibility

Top 40.NET Interview Questions & Answers

Introduction to Microsoft.NET Framework Programming using VS 2005 (C#)

Programming in C# for Experienced Programmers

Configuring and Customizing the ArcGIS Viewer for Silverlight. Katy Dalton

Windows Presentation Foundation Visual Studio.NET 2008

CS3240 Human-Computer Interaction Lab Sheet Lab Session 3 Designer & Developer Collaboration

Introduction to Programming Microsoft.NET Framework Applications with Microsoft Visual Studio 2005 (C#)

LAYOUT. Chapter 3 of Pro WPF : By Matthew MacDonald Assist Lect. Wadhah R. Baiee. College of IT Univ. of Babylon

Developing Microsoft.NET Applications for Windows (Visual Basic.NET)

Developing Windows Applications with Microsoft Visual Studio 2010 (MS 10262)

Getting started 7. Setting properties 23

Introduction to Mobile Development

A Quick Tour GETTING STARTED WHAT S IN THIS CHAPTER?

Developing Rich Internet Applications Using Microsoft Silverlight 4

A NET Refresher

Educational Fusion. Implementing a Production Quality User Interface With JFC

A Guide to CMS Functions

PART I. The Lay of the Land. CHAPTER 1: Exploring SharePoint Designer

Advanced WCF 4.0 .NET. Web Services. Contents for.net Professionals. Learn new and stay updated. Design Patterns, OOPS Principles, WCF, WPF, MVC &LINQ

ArcGIS Viewer for Silverlight Advanced Topics

STARCOUNTER. Technical Overview

Microsoft Visual Studio 2010

2. A GUI A. uses buttons, menus, and icons B. should be easy for a user to manipulate C. both (a) and (b) D. stands for Graphic Use Interaction

Telerik Corp. Test Studio Standalone & Visual Studio Plug-In Quick-Start Guide

INTERNAL ASSESSMENT TEST 1 ANSWER KEY

Course 2D_WPF: 2D-Computer Graphics with C# + WPF Chapter C1a: The Intro Project Written in XAML and C#

Lab 7: Silverlight API

<Insert Picture Here> JavaFX 2.0

C# is intended to be a simple, modern, general-purpose, objectoriented programming language. Its development team is led by Anders Hejlsberg.

CHAPTER 1: INTRODUCING C# 3

Windows Presentation Foundation

ExecuTrain Course Outline MOC 6460A: Visual Studio 2008: Windows Presentation Foundation

20483BC: Programming in C#

Introduction to C++/CLI 3. What C++/CLI can do for you 6 The rationale behind the new syntax Hello World in C++/CLI 13

Getting Started with ExcelMVC

INTRODUCTION TO.NET. Domain of.net D.N.A. Architecture One Tier Two Tier Three Tier N-Tier THE COMMON LANGUAGE RUNTIME (C.L.R.)

Introducing C# and the.net Framework

C# Programming in the.net Framework

HPE.NET Add-in Extensibility

ArcGIS Pro SDK for.net: Advanced User Interfaces in Add-ins. Wolfgang Kaiser

Practical WPF. Learn by Working Professionals

Beginning Silverlight 5 in C #

PROGRAMMING IN VISUAL BASIC WITH MICROSOFT VISUAL STUDIO Course: 10550A; Duration: 5 Days; Instructor-led

Silverlight. Daron Yöndem

Introduction to Programming Microsoft.NET Applications with Visual Studio 2008 (C#)

ASP.NET- Enterprise Applications

Index. Alessandro Del Sole 2017 A. Del Sole, Beginning Visual Studio for Mac,

Introduction to Autodesk MapGuide EnterpriseChapter1:

After completing this appendix, you will be able to:

PTN-202: Advanced Python Programming Course Description. Course Outline

BEAWebLogic. Portal. Overview

+ Inheritance. Sometimes we need to create new more specialized types that are similar to types we have already created.

GUI in C++ PV264 Advanced Programming in C++ Nikola Beneš Jan Mrázek Vladimír Štill. Faculty of Informatics, Masaryk University.

10267A CS: Developing Web Applications Using Microsoft Visual Studio 2010

Programming in Visual Basic with Microsoft Visual Studio 2010

Getting started 7. Setting properties 23

C# Programming: From Problem Analysis to Program Design. Fourth Edition

Visual Studio 2010 Silverlight No Symbols Have Been Loaded For This Document

Xton Access Manager GETTING STARTED GUIDE

Transcription:

Chapter 1 Introducing WPF Objectives: Understand the motivation behind WPF Examine the various flavors of WPF applications Overview the services provided by WPF Examine the core WPF assemblies and namespaces Work with the Window and Application class types Learn the syntax of XAML Understand the XAML / code relationship 1-1

Chapter Overview Every few years or so, Microsoft introduces a new GUI toolkit. Since the release of.net 3.0, the latest desktop GUI toolkit is Windows Presentation Foundation (WPF). In this introductory chapter, you will understand the motivation behind WPF, learn the syntax of XAML, examine the core programming model, and survey several WPF services. Also, you will overview the WPF support provided by Visual Studio and be introduced to the role of Expression Blend. As you would expect, this chapter provides a foundation for the remainder of the class. 1-2

The Motivation Behind WPF Historically speaking, building a desktop UI under the Windows OS involved using a handful of key services: User32: Provided the code required to create windows, controls, and application infrastructure. GDI: Provided a framework for rendering 2D graphical data. DirectX: If an application required high-performance graphical rendering (multimedia applications, video games, rich interactive front ends, and so on), DirectX was the way to do so. Although Windows programmers could make use of these services using raw C/C++, many UI toolkits were introduced over the years: VB6, MFC, Windows Forms, GDI+, and so on. Each one of them was simply a wrapper around User32 / GDI. These toolkits still viewed DirectX as an external service. Windows Presentation Foundation (WPF) is a managed GUI toolkit that shipped beginning with.net 3.0. The core WPF object model is similar, but not identical to, Windows Forms. The release of WPF does not imply that Windows Forms is obsolete. In fact, the.net platform will support this API for years to come. 1-3

Before the release of WPF, UI developers were forced to master a number of related, but ultimately independent, APIs. This required developers to switch gears when moving from one task (e.g., building a main window) to another (e.g., 3D graphical rendering). The end result was a very asymmetrical way to program. Consider the GUI development world before.net 3.0: Desired Functionality Forms, dialog boxes, controls 2D graphics 3D graphics Streaming video Fixed / Flow documents Pre-.NET 3.0 Solution Windows Forms, VB6, MFC, and so on System.Drawing.dll (e.g., GDI+) or raw C-based GDI DirectX Windows Media Player API or third party APIs Third party APIs With the release of WPF, things have improved considerably. You now have a single symmetrical manner in which to interact with the necessary GUI infrastructure. Consider the GUI development world as of.net 3.0 and higher: Desired Functionality Forms, dialog boxes, controls 2D graphics 3D graphics Streaming video Fixed / Flow documents.net 3.0 and Higher Solution Windows Presentation Foundation Windows Presentation Foundation Windows Presentation Foundation Windows Presentation Foundation Windows Presentation Foundation 1-4

Beyond offering a unified programming model, WPF also provides a clear separation of concerns. It is possible to separate the look and feel of a GUI application from the programming logic that drives it. This is achieved using an XML-based grammar termed XAML ( zam-el ). While most WPF applications will make use of XAML, doing so is entirely optional. This separation of concerns (via XAML) makes it much simpler for graphical designers to build very rich, professional UIs. Graphically minded individuals can use dedicated design tools such as Microsoft Expression Blend to generate the XAML. These XAML files can then be passed to the programming team to add logic to drive the UI (event handlers, method overrides, and so on). As you will see in the class, a Microsoft Blend project uses exactly the same format as a Visual Studio project. Beyond the introduction of XAML, WPF also provides a good number of integrated services, including (but not limited to) the following: A number of layout managers that provide full control over placement and repositioning of content. A built-in style engine, which allows you to define themes for a WPF application. Native use of vector graphics, which allows an image to be automatically resized to fit the size and resolution of the screen hosting the application. A rich typography API such as support for XPS (XML Paper Specification) documents, fixed documents (WYSIWYG), flow documents, and document annotations (e.g., a Sticky Notes API). Integrated 2D and 3D rendering services / animation services, which leverage DirectX for hardware acceleration. In fact, all rendering, even the rendering of UI elements (buttons, and so on) is preformed via DirectX. Interoperability with previous UI frameworks. For example, a WPF program can use Windows Forms controls or ActiveX controls. As well, a Windows Forms app can use WPF controls. Support for audio and video media. Support for touch screen development (as of.net 4.0). 1-5

Overall, WPF can be considered a supercharged UI framework. WPF is extremely useful when you need to build highly interactive, stylized front ends. Real-time rotation of 3D bar charts, spinning a portion of a UI to a 45-degree angle, and dynamic shadowing on a rendered image are all possible. Consider the following WPF application (an example project from Expression Blend): Clicking on any of the stylized buttons on the bottom of the application will rotate and animate a 3D motorcycle prototype. Each button supports a custom animation, performed when the cursor travels over the surface. Notice the drop shadows, angled text blocks, etc. While all of this could be done without WPF, doing so would require a considerable amount of complex code. Here, a majority of the UI is driven by XAML. 1-6

Because WPF applications are so graphically intensive, a production-level WPF application may require the aid of a professional graphic designer. You may agree that most.net programmers are not the best of artists. Likewise, most artists are not the best of.net programmers. Using XAML and tools such as Visual Studio and Expression Blend, each part of the team can use dedicated tools, thus increasing efficiency in development. Remember that the same Visual Studio WPF application can be opened in Expression Blend (and vice versa). This is not to suggest that you cannot use WPF to build traditional GUIs (gray push buttons, a grid of data, a menu system, and so on). You can certainly use WPF to build traditional business applications. However, this API is strongly geared for next-generation GUI applications. WPF is closer to the Hollywood vision of what computer applications should look like (e.g., 3D spinning e-mail messages, glowing animated blocks of text, and the like). Even if you are interested in building a typical LOB application, WPF can still provide a number of key benefits. The WPF content model and template model make it very easy to customize controls. A LOB application can add a bit of eye candy (animations and visual effects) with just a few lines of XAML. 1-7

The Flavors of WPF Applications Like Windows Forms, WPF can be used to build traditional desktop applications. Some possibilities include media viewers, thick client front ends to interact with remote data sources, and word processors. At minimum, this flavor of WPF application will make use of the Window and Application types, in addition to various UI elements (status bars, menu systems, dialogs, and so on). You will learn about these types in this chapter. Like other desktop applications, WPF desktop apps can be deployed via a standard setup program or ClickOnce deployment. Of course, the target machine must have the.net 3.0 or higher runtime installed to support WPF applications. WPF desktop apps can make use of a page-based system, which allows an application to adopt a web-like navigational structure. Page navigation apps maintain Next and Previous buttons, a history list, and the ability to share data between pages. This type of WPF app makes use of various Page objects hosted within a NavigationWindow. If you are interested in this flavor of WPF program, consult Appendix C. 1-8

WPF can also be used to build a new variety of smart clients where the app is embedded into a hosting browser. This flavor of WPF is termed an XBAP (XAML Browser Application). Like navigationally based apps, XBAPs consist of a number of Page objects. They are deployed from a remote web server (like a ClickOnce app) and integrate into the navigational structure of the host. XBAPs may be hosted within Internet Explorer or Firefox. This course will not formally cover XBAP construction, however beware that everything you learn about WPF applies directly to XBAP. The fundamental difference is how an XBAP is deployed. Do be aware that Visual Studio does provide a WPF Browser Application project template which you may wish to explore. Also, look up the topic WPF XAML Browser Applications Overview in the.net Framework SDK for more information if you are interested. 1-9

The WPF and Silverlight Relationship Silverlight is a web-centric subset of.net / WPF / XAML functionality. Silverlight makes it possible to build highly interactive web plug-ins. Consider Silverlight to be Microsoft s answer to Adobe Flash. Silverlight allows developers to use C# or Visual Basic to build object-oriented plugins. Silverlight applications can run on multiple operating systems (currently Windows and Mac OS X and various Linux distributions via the open source Moonlight project). Silverlight can be hosted by multiple browsers (IE, Safari, Opera, and Firefox). This course does not directly cover Silverlight. The good news is that Silverlight apps are essentially trimmed down WPF apps. Thus, if you understand the WPF programming model, you will have no problem building Silverlight programs. Consult http://silverlight.net/ for more details. 1-10

The WPF Documentation System During the remainder of this class, you will be exposed to a good number of WPF technologies and application types. This will provide you with a solid foundation on which to build. Consult the.net Framework SDK documentation for additional information. Simply open the Windows Presentation Foundation section of the.net Framework documentation. You will find many sample projects, white papers, and code examples within the supplied WPF documentation. Also, the Controls section documents the full functionality of each WPF control (properties, methods, events). Do yourself a favor and be sure to consult the help system during this course, and once you are using WPF back in the workplace. 1-11

Core WPF Assemblies and Namespaces Like any.net technology, WPF is represented by several assemblies. The Visual Studio WPF project templates automatically set references to the core assemblies. However, if you build WPF apps using other IDEs or via msbuild.exe, you will need to set assembly references manually. The following key libraries are managed.net assemblies. WPF Assembly WindowsBase.dll PresentationCore.dll PresentationFramework.dll System.Xaml.dll Meaning in Life Defines the base infrastructure of WPF, including dependency properties support. While this assembly contains types used within the WPF framework, the majority of these types can be used within other.net applications. This assembly defines numerous types that constitute the foundation of the WPF GUI layer. This assembly the meatiest of the three defines the WPF controls types, animation and multimedia support, data binding support, and other WPF services. For all practical purposes, this is the assembly you will spend most of your time working with directly. This library (which is new to.net 4.0) provides types to process and manipulate XAML at runtime. 1-12

Although these assemblies provide hundreds of types within numerous namespaces, consider this partial list of WPF namespaces: You will encounter other namespaces during the remainder of this class. Again, consult the.net Framework SDK documentation for full details. WPF Namespace System.Windows System.Windows.Controls System.Windows.Markup System.Windows.Media System.Windows.Navigation System.Windows.Shapes Meaning in Life Here you will find core types such as Application and Window that are required by any WPF desktop project. Here you will find all of the expected WPF widgets, including types to build menu systems, tool tips, and numerous layout managers. This namespace defines a number of types that allow XAML markup and the equivalent binary format, BAML, to be parsed. Within these namespaces you will find types to work with animations, 3D rendering, text rendering, and other multimedia primitives. This namespace provides types to account for the navigation logic employed by XAML browser applications / desktop navigation apps. This namespace defines basic geometric shapes (Rectangle, Polygon, etc.) used by various aspects of the WPF framework. 1-13

The Role of the Application Class Regardless of which flavor of WPF application you create, they will all make use of the System.Windows.Application type. This class represents a global running instance of a WPF application. It encapsulates a number of core services such as handling messages, trapping unhandled exceptions, defining common application data, and more. Unlike Windows Forms, the WPF Application class exposes most services as instance-level members. Therefore, you will need to create a class extending Application. This class is commonly termed the application object. A WPF application will only have a single Application object. 1-14

The Application class defines a number of key services. Here is a partial list of important members: Application Property Current MainWindow StartupUri Properties Windows Startup Exit DispatcherUnhandledException Meaning in Life This static property provides access to the global WPF application object. This allows any window (or page) to access the application, which is very helpful in that the app object tends to define core functionality for all owned objects (resources, and so on). Allows you to get or set the main window of the WPF application. Typically used within a XAML description to define the resource containing the definition of the main window. Allows you to define application-wide variables using name / value pairs. Similar in concept to a session variable in a web app in that any part of your WPF program has access to this data. Provides access to each Window owned by the current WPF application which makes it simple to iterate over open windows to change their states. These are two key events that almost all WPF application objects will handle. This event fires when a WPF throws an unhandled exception. This is your last chance to handle the error before the user is presented with a Windows error dialog box. 1-15

The application object will define the Main() method of your program, which must be marked with the [STAThread] attribute. This attribute ensures that any legacy COM objects, ActiveX controls, and the WPF controls load into a thread-safe environment. If you do not mark your Main() method with the [STAThread] attribute, you will receive a runtime exception. Here is a simple WPF application object: // C# class MyApp : Application { [STAThread] static void Main() { // Create an instance of MyApp. // Handle events, run the application, // launch the main window, etc. } } ' VB Class MyApp Inherits Application <STAThread> _ Shared Sub Main() ' Create an instance of MyApp. ' Handle events, run the application, ' launch the main window, etc. End Sub End Class Your Main() method will be the place where you typically want to handle the Startup, Exit, and DispatcherUnhandledException events. Also, your application object can define any number of application-wide data points. You will build a more complete application object later in this chapter. For now, examine the role of the Window class. 1-16

The Role of the Window Type In addition to the Application type, most desktop WPF applications will make use of the Window type. This represents the main window of your app, as well as any custom dialog boxes. As you can see, Window gains a good deal of functionality from its inheritance chain. You will come to know the role of many of these base classes during the remainder of this class. Here is a high-level overview of the role of each class in the Window s inheritance chain. The ContentControl parent class allows derived types to host a single piece of content. WPF content can be composed of any sort of UI elements. Most WPF controls also have ContentControl in their inheritance chain. Also, the Window and Page types extend ContentControl. 1-17

The WPF content model allows you to radically change the composition of a control with minimal fuss. By way of an example, a Button could maintain an inner StackPanel as content. The StackPanel contains an Ellipse and Label. You will examine the content model in a later chapter. For now, here is a simple example in XAML. <!-- A Button containing a StackPanel as content. --> <Button Height = "150" Width = "120"> <StackPanel> <Ellipse Fill = "Orange" Height = "75" Width = "75"/> <Label Content = "OK!" FontSize = "20" HorizontalAlignment = "Center" /> </StackPanel> </Button> The Control parent class defines a number of members that give derived types (including Window) their core look and feel. Properties exist to establish the control s opacity, tab order logic, background color, font settings, and so forth. The Control type also provides the infrastructure to apply templates and styles to a UI widget. FrameworkElement is another key parent class to many UI widgets in that it provides members to control size, tooltips, mouse cursor, and other settings. This class also provides support for WPF animation and data binding services. UIElement provides the greatest amount of functionality: Events to process mouse and input focus. Properties to control focus, visibility, and geometric transformation. 1-18

Visual provides derived types the core infrastructure to render their UI output. Visual provides hit-testing support and coordinates transformation. Visual is also the connection between WPF and the DirectX subsystem. Any type extending Visual can be rendered on a Window. DependencyObject is the parent that provides derived types the ability to work with the WPF dependency property model. As you will see later, a dependency property makes it possible for a property to receive input from multiple locations. This is key part of WPF s template, animation, and data binding services. Finally, DispatcherObject provides access to the WPF app s lower-level event queue via the Dispatcher property. WPF makes use of a single-thread affinity model, hence the use of [STAThread] in your Main() method. 1-19

Building a WPF Application (XAML-free) Now that you better understand the core services provided by Application and Window, it is time to build a simple WPF application. This application will not be created using XAML (recall that XAML is technically optional). Rather, this application will take the 100% code approach. Although WPF applications are not required to use XAML, a pure code approach is not necessarily recommended. This approach does not honor the separation of concerns between GUI layout and functionality. However, it is important to understand how to work with WPF types in code, even when you are making use of XAML. Recall that the System.Windows.Application class represents a running instance of a WPF app. Unlike Windows Forms, the Application type exposes its core functionality as instance-level (rather than static) members. Thus, a WPF app will have a class type that extends Application. The other critical type is Window, which represents a topmost window or dialog box. This type is typically subclassed for strong typing. However, this is not required. Consider the following simple C# WPF app that handles some key events. The Startup event makes use of the StartupEventHandler delegate. The Exit event makes use of ExitEventHandler. It also deals with any unhandled exceptions by handling the DispatcherUnhandledException event. This event makes use of the DispatcherUnhandledExceptionEventHandler delegate, which is a member of the System.Windows.Threading namespace. Notice the incoming DispatcherUnhandledExceptionEventArgs gives access to the error information and provides a way to clear the exception. 1-20

// C# // A Simple WPF Application written without XAML. using System; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; namespace SimpleWPFApp { class MyWPFApp : Application { [STAThread] static void Main() { // Handle key events and then run the application. MyWPFApp app = new MyWPFApp(); app.startup += new StartupEventHandler(AppStartUp); app.exit += new ExitEventHandler(AppExit); app.dispatcherunhandledexception += new DispatcherUnhandledExceptionEventHandler(AppUnhandledException); } // Fires the Startup event. app.run(); } } static void AppUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { MessageBox.Show(e.Exception.Message, "Unhandled error!!"); e.handled = true; } static void AppExit(object sender, ExitEventArgs e) { MessageBox.Show("App has exited"); } static void AppStartUp(object sender, StartupEventArgs e) { // Create a Window object and set some basic properties. Window mainwindow = new Window(); mainwindow.title = "My First WPF App!"; mainwindow.height = 200; mainwindow.width = 300; mainwindow.windowstartuplocation = WindowStartupLocation.CenterScreen; mainwindow.show(); } 1-21

In VB, the previous example could be authored as so: Notice it makes use of the AddHandler statement to hook into events. This is necessary because local variables (e.g., the Application object) cannot be declared using the WithEvents keyword. ' VB ' A Simple WPF Application, written without XAML. Imports System Imports System.Windows Imports System.Windows.Controls Imports System.Windows.Threading Namespace SimpleWPFApp ' This first example defines a single class type to ' represent the application itself and the main window. Class MyWPFApp Inherits Application <STAThread> _ Shared Sub Main() ' Handle key events and then run the application. Dim app As New MyWPFApp() AddHandler app.startup, AddressOf AppStartUp AddHandler app.exit, AddressOf AppExit AddHandler app.dispatcherunhandledexception, AddressOf AppUnhandledException app.run() End Sub Shared Sub AppUnhandledException(ByVal sender As Object, _ ByVal e As DispatcherUnhandledExceptionEventArgs) MessageBox.Show(e.Exception.Message, "Unhandled error!!") e.handled = True End Sub Shared Sub AppExit(ByVal sender As object, ByVal e As ExitEventArgs) MessageBox.Show("App has exited") End Sub Shared Sub AppStartUp(ByVal sender As Object, _ ByVal e As StartUpEventArgs) ' Create a Window object and set some basic properties. Dim mainwindow As new Window() mainwindow.title = "My First WPF App!" mainwindow.height = 200 mainwindow.width = 300 mainwindow.windowstartuplocation = WindowStartupLocation.CenterScreen mainwindow.show() End Sub End Class End Namespace 1-22

Here is a strongly typed Window-derived class that encapsulates the details of the main window. Notice it extends Window and sets core properties via constructor arguments. VB programmers would author the same code statements within a Sub New(). // C# (VB code would be similar.) class MainWindow : Window { public MainWindow(string windowtitle, int height, int width) { this.title = windowtitle; this.windowstartuplocation = WindowStartupLocation.CenterScreen; this.height = height; this.width = width; this.show(); } } At this point, you can update the Startup event handler: Note you are now creating a strongly typed MainWindow object. // C# (VB code would be similar.) static void AppStartUp(object sender, StartupEventArgs e) { // Create a MainWindow object. // VB code would use the Dim keyword: // Dim wnd as New MainWindow("My better WPF App!", 200, 300) MainWindow wnd = new MainWindow("My better WPF App!", 200, 300); } 1-23

Adding UI Elements (XAML-free) Adding UI elements to a Window type is a bit different than working with Windows Forms. The core WPF controls are defined within the System.Windows.Controls namespace (not System.Windows.Forms). The events sent from WPF controls make use of various new delegates such as RoutedEventHandler. More details on routed events will come later in the class. Most importantly, any type extending ContentControl (including Window) can only contain a single UI element as content. This is a requirement of the WPF content model. When a Window requires multiple UI elements, you arrange them within one of the provided panel types: Grid, StackPanel, and so on. The panel will then be the single piece of content owned by the Window. If you do not place the UI item in a panel type, the single bit of content will be placed in the dead center of the window or page. 1-24

Here is an update to the Window class, which now contains a single Button as content. The Click event is handled via the RoutedEventHandler delegate. The Click event handler will simply terminate the entire application. The Button is added to the Window s content via AddChild(). // C# class MainWindow : Window { // The UI element. private Button btnexitapp = new Button(); } public MainWindow(string windowtitle, int height, int width) { // Configure the button and set the child control. btnexitapp.click += new RoutedEventHandler(btnExitApp_Clicked); btnexitapp.content = "Exit Application"; btnexitapp.height = 25; btnexitapp.width = 100; } this.addchild(btnexitapp); // Configure the window. this.title = windowtitle; this.windowstartuplocation = WindowStartupLocation.CenterScreen; this.height = height; this.width = width; this.show(); private void btnexitapp_clicked(object sender, RoutedEventArgs e) { // Get a handle to the current application and shut it down. Application.Current.Shutdown(); } 1-25

When you create a Window, it will automatically be added to the application s internal Windows collection. This is done via some constructor logic of the Window type. Recall that the Application.Windows property allows you to access each open window maintained by the application object. Here is a helper method that will display the title of each window owned by the WPF application. The VB code would be similar. // C# (VB code would be similar) static void DisplayTitlesOfAllOpenedWindows() { // Get a handle to the application object. Application appobject = Application.Current; } // Print the title of each window in the collection. foreach(window w in appobject.windows) MessageBox.Show(w.Title); Lab Exercise: Building a WPF Application (All Code) 1-26

Building a WPF Application Using XAML The Extensible Application Markup Language (XAML) is an XML-based grammar for describing trees of.net objects. XAML and WPF go hand in hand, but XAML can be used to describe any non-generic type that supports a default constructor. Objects defined in XAML are always created using the default constructor. A XAML description of a tree of objects maps to a runtime object model. In the case of WPF, XAML descriptions are a direct mapping to the properties and events of the type being described. The opening element defines the name of the class with XML attributes used to set the property values and event handler names. The Name attribute refers to the name of the instance of the class. Consider the following (functionally identical) manners to declare a WPF Button object. <!-- Defining a WPF Button in XAML --> <Button Name = "btnclickme" Height = "40" Width = "100" Content = "Click Me" Click = "btnclickme_click"/> // Defining the same WPF Button in C# code. // (VB code would be similar) Button btnclickme = new Button(); btnclickme.height = 40; btnclickme.width = 100; btnclickme.content = "Click Me"; btnclickme.click += new RoutedEventHandler(btnClickMe_Click); 1-27

It is possible (although not very practical) to build an entire WPF application using nothing more than XAML descriptions. Recall that XAML is not limited to the description of GUI elements. Any.NET object can be described in XAML, including a WPF s Application type, which has no associated user interface. Here is a XAML description of a Window-derived type. The XML namespaces are required and simply qualify the various WPF XAML definitions (more information will come later in this chapter on XAML namespaces). Notice that code such as event handlers can be wrapped within CDATA sections contained within <x:code> elements. It is not recommended to inject code within a XAML file, as it violates the separation of concerns. <!-- Here is the Window definition --> <Window x:class = "SimpleXamlApp.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "My Xaml App" Height = "200" Width = "300" WindowStartupLocation = "CenterScreen"> <!-- Define the button content --> <Button Width = "133" Height = "24" Name = "btnexitapp" Click = "btnexitapp_clicked" Content = "Exit Application"/> <!-- The C# implementation of the button's Click event handler. --> <x:code> <![CDATA[ private void btnexitapp_clicked(object sender, RoutedEventArgs e) { // Get a handle to the current app and shut it down. Application.Current.Shutdown(); } ]]> </x:code> </Window> 1-28

Here would be the XAML description of the Application type of the WPF application. The StartupUri property is essentially the XAML equivalent of defining a Main() method. This property is set to the XAML resource containing the definition of the main window of the application. Although it looks like we are pointing to an external file (MainWindow.xaml), in reality this is the name of an embedded binary resource (more details later). <!-- The main method seems to be missing! However, the StartupUri attribute is the functional equivalent. --> <Application x:class = "SimpleXamlApp.MyApp" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" StartupUri = "MainWindow.xaml" Exit ="AppExit"> <x:code> <![CDATA[ private void AppExit(object sender, ExitEventArgs e) { MessageBox.Show("App has exited"); } ]]> </x:code> </Application> These XAML files can now be compiled into a.net assembly using msbuild.exe and a related build script. Msbuild.exe is a command line tool that enables complex builds. In fact, Visual Studio makes use of msbuild.exe in the background. The same build script can be processed by msbuild.exe or Visual Studio. Msbuild.exe makes use of various targets that contain instructions on how to transform XAML definitions into equivalent.net code. Your next lab will illustrate how to do so. Until then, let us dig deeper into the syntax of XAML itself. 1-29

Understanding the Role of XAML Although XAML is a key aspect of WPF, few developers will need to author reams of XAML by hand. XAML, like any XML-based grammar, is verbose, tedious, and error prone. Numerous tools such as Visual Studio and Expression Blend will generate XAML on your behalf as you make use of the tool itself. Although it is true that WPF development tools will generate XAML in the background, it is important to understand the basic syntax. This will allow you to tweak the generated XAML if the need should arise. Also, XAML can be generated, loaded, parsed, and manipulated at runtime. To understand how to do so, a working knowledge of XAML s syntax is useful. It is important to recall that XAML is a general-purpose markup language and is not limited to WPF. XAML can also be found within the Windows Workflow Foundation API, where it is used to build custom activities and workflows via markup. XAML is also used within Silverlight applications. XAML is also used by the XML Paper Specification (XPS), a Microsoft technology for e-paper. 1-30

As detailed in your next lab, msbuild.exe uses XAML descriptions to generate intermediate code files used during the compilation process. As a naming convention, these file have a g infix (for generated). For example, a XAML file named MyWindow.xaml will be used by msbuild.exe to generate a C# file named MyWindow.g.cs or a VB file named MyWindow.g.vb. Within these generated files, you will find code-based equivalents for various aspects of your XAML markup. XAML files are also used to generate a compact binary form of the markup termed binary markup language (BAML). By default, the BAML is embedded into your.net assembly as a binary resource. The name of a BAML resource is identical to the name of the original XAML file. At runtime, the BAML is parsed to hydrate the state of your WPF objects (windows, applications, controls, and so on). Because of BAML, you are seldom required to ship XAML files along with your compiled WPF application. Unless you are dynamically loading external XAML files into memory, XAML files can be regarded as little more than input to msbuild.exe. 1-31

Establishing WPF-specific XML Namespaces The root element of a XAML document typically defines two XML namespaces that map to core WPF namespaces and XAML specific tokens. http://schemas.microsoft.com/winfx/2006/xaml/presentation maps a number of WPF namespaces for use by the current *.xaml file: System.Windows, System.Windows.Controls, System.Windows.Data, System.Windows.Ink, System.Windows.Media, System.Windows.Navigation, etc. http://schemas.microsoft.com/winfx/2006/xaml is used to include XAML specific tokens, as well as a subset of types within the System.Windows.Markup namespace. Here would be a <Window> that defines these two XML namespaces. Given the cascading nature of XML, all sub-elements of the <Window> have access to the same information. <Window xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> </Window> The first xmlns attribute is the primary namespace as it has not been qualified with a namespace prefix. Notice that the second xmlns attribute as been given the x prefix. This is simply to avoid ambiguity with the other namespace definitions. Like any XML prefix, the actual name is irrelevant. Thus, the following <Window> definition is also permissible although more verbose. <Window xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:xamlspecificstuff = "http://schemas.microsoft.com/winfx/2006/xaml"> </Window> 1-32

If you did use the ' XamlSpecificStuff' prefix, any XAML keyword in the defining scope would now need to make use of this rather verbose tag. Consider the following <Application> root element, which illustrates the simplicity of x as a tag prefix for the XAML-centric namespace. <Application XamlSpecificStuff:Class="SimpleXamlApp.MyApp" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns: XamlSpecificStuff = "http://schemas.microsoft.com/winfx/2006/xaml" StartupUri = "MainWindow.xaml" Exit="AppExit"> <XamlSpecificStuff:Code> <![CDATA[ private void AppExit(object sender, ExitEventArgs e) { MessageBox.Show("App has exited"); } ]]> </XamlSpecificStuff:Code> </Application> Beyond the two key XML namespaces, XAML makes it possible to define custom xmlns values that map to custom assemblies. This can be helpful when your markup needs to refer to types defined in external libraries. The clr-namespace token is used to do this very thing. You will see why this can be quite useful over the course of this class. Here is a simple example that makes the types in the System namespace of mscorlib.dll available within the current <Window>. If you are mapping to a namespace in the current assembly, the assembly qualifier is optional as seen in the second XML namespace listing. <Window xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:corlib = "clr-namespace:system;assembly=mscorlib" xmlns:mytypes = "clr-namespace:somenamespaceinmyassembly"> </Window> 1-33

The Role of XAML Type Converters WPF supports several intrinsic type converters. Their job is to map simple string values into complex objects. Consider, for example, the act of setting the Background property to the string Green. In code, the Background property expects a Brush-derived type. Furthermore, the Height and Width properties expect double values, not strings. Regardless, the following XAML works as expected. <Button Name = "mybutton" Height = "100" Width = "100" Content = "Click Me!" Background = "Green"> </Button> Behind the scenes, these string values ( 100, 100 and Green ) are transformed into doubles and a SolidColorBrush object via type converters. WPF supports numerous type converters, all of which derive from the System.ComponentModel.TypeConverter base class. For example, the BrushConverter type was used to map Green into a brush object. While you could make direct use of type converters in code, there is usually no compelling reason to do so. In the vast majority of the cases, the correct type converter will be used at compilation time. 1-34

XAML-specific Elements and Attributes Strictly speaking, XML-based grammars do not support true keywords. However, XML parsers can be programmed to look for special tokens that will be treated in a special, customized manner. The same is true for XAML as it defines a number of tokens that can be regarded as keywords in a general sense. Many of these are used to control how the XAML markup is processed at compile time via msbuild.exe. Because these XAML-specific tokens are part of the XAML namespace, many of them must take an x: prefix (x:name, x:code, x:class, and so forth). As you will see, as a convenience, some tokens such as Name do not require an x: prefix. XAML Keyword Array ClassModifier DynamicResource FieldModifier Key Name Null Static StaticResource Type Meaning in Life Used to represent a.net array type in XAML. Allows you to define the visibility of the class type (internal or public) denoted by the Class keyword. Allows you to make reference to a WPF resource that should be monitored for changes. Allows you to define the visibility of a type member (internal, public, private, protected) for any named sub-element of the root (e.g., a <Button> within a <Window> element). Allows you to establish a key value for a XAML item that will be placed into a resource dictionary. This allows you to specify the generated C# name of a given XAML element. Represents a null reference. Allows you to make reference to a static member of a type. Allows you to make reference to a WPF resource that should not be monitored for changes. This is the XAML equivalent of the C# typeof operator / VB GetType operator. It will yield a System.Type based on the supplied name. 1-35

As you have seen earlier in this chapter, the x:class and x:code tokens are XAML tokens. A Window or Application can specify an x:class attribute in its opening definition and is used to define the name of the class type in the code files. The <x:code> XAML element can be used to embed code within a XAML file. Here is a <Window> element that defines the x:class attribute: <!-- The x:class attribute will be used by msbuild.exe to Define a C# or VB class type to represent the code of this XAML. --> <Window x:class = "MyWPFApp.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> </Window> 1-36

Controlling Type / Member Naming and Visibility The x:classmodifier / x:fieldmodifer attributes allow you to control the visibility of a member in the related code file. A XAML file is often paired with a C# or VB code file where you author event handlers, helper methods, and so forth. An additional compile-time generated code file (*.g.cs / *.g.vb) will be used to contain the XAML => code object mapping, control declarations, and more. If you do not make use of the x:classmodifer / x:fieldmodifer attributes, the item will be defined using the default visibility of the.net language. In most cases, you will not need to change these defaults. As a result, you will not frequently need to make use of the x:classmodifier or x:fieldmodifer tokens. 1-37

As an example, however, consider the following use of the x:classmodifier and x:fieldmodifier attributes. This will be used by msbuild.exe to declare a code file containing an internal class with a public Button. The VB code would be similar, using the Friend keyword rather than the C#-specific internal keyword. <!-- This class will now be internal. If using a code file, the partial class must also be defined as internal. --> <Window x:class = "MyWPFApp.MainWindow" x:classmodifier="internal" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"> <!-- This button will be public in the generated code file. --> <Button x:name = "mybutton" Content = "OK" x:fieldmodifier = "public"/> </Window> // C# code (VB code would be similar) internal partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector { public System.Windows.Controls.Button mybutton; } 1-38

Notice that the previous <Button> has been defined using the x:name attribute. When you are declaring an item in XAML, you can assign a value to the x:name attribute. This becomes the name of the variable in the code file. Because the need to define names for elements is so common, XAML provides a shortcut. If the type extends FrameworkElement, you can omit the x: prefix and simply use Name. However, if the type does not extend FrameworkElement, you must use x:name. When in doubt, x:name will always work when you wish to name an element. Therefore, the previous <Button> could also be defined as follows: <Button Content="OK" Name = "mybutton" x:fieldmodifier = "public"/> 1-39

Property-Element Syntax Within the scope of an opening element, you will be able to set values to the properties and events of the type. For example, the following <Button> sets the Height and Width values and handles the Click event. The name assigned to the Click event will typically map to a method in your code file. However, this could also be a method in a <x:code> scope of the defining XAML file. <Button Name = "mybutton" Height = "100" Width = "100" Click = "mybutton_click" Content="OK"/> Here, Height, Width, and Click were assigned values that could be captured as a simple string. However, many properties of WPF classes do not operate on data that represents simple string values. For example, some properties require full-blown objects (complex brushes, pens, and so on). XAML property-element syntax allows you to assign complex object values to a property. This syntax defines a subscope scope representing a property of the defining type. Within this scope, you can describe the object to be used for the property assignment. The format follows the following template: <DefiningType> <DefiningType.PropertyOnDefiningType> <!-- data used to set property --> </DefiningType.PropertyOnDefiningType> </DefiningType> 1-40

Consider the following syntax, which sets the Background property of a Button to a LinearGradientBrush type using property-element syntax. The associated image shows you how this button would look when rendered by a XAML parser. <Button Name = "mybutton" Height = "100" Width = "100" Content = "Click Me!"> <Button.Background> <LinearGradientBrush StartPoint = "0,0" EndPoint = "1,1"> <GradientStop Color = "Blue" Offset = "0" /> <GradientStop Color = "Yellow" Offset = "0.25" /> <GradientStop Color = "Green" Offset = "0.75" /> <GradientStop Color = "Pink" Offset = "0.50" /> </LinearGradientBrush> </Button.Background> </Button> While property-element syntax is most commonly used to assign complex objects to properties, it is possible to assign simple string data too. You do not gain much by doing so, however, as you could simply use an attribute in the opening element. Thus, the following markup is functionally equivalent: <!-- OK, but verbose --> <Button x:name = "mybutton" Height = "100" Width = "100" Content = "Click Me!"> <Button.Background> Pink </Button.Background> </Button> <Button x:name = "mybutton" Height = "100" Width = "100" Content = "Click Me!" Background = "Pink"> </Button> 1-41

Attached-Property Syntax WPF also makes use of a concept termed attached property syntax. One use of attached properties is to make it possible for a sub-element to assign a property value on a parent element. In this case, the template to use looks like the following: <ParentType> <ChildType ParentType.PropertyName = "Value"> </ChildType> </ParentType> The most common use of attached-property syntax is to position UI elements within one of the WPF panel types (Grid, DockPanel, and so on). You will dive into these panels in some detail later. However, here is an example of attached-property syntax. <Window x:class = "FunWithAttachedPropeties.Window1" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "Fun with Attached Properties" Height = "300" Width = "300"> <DockPanel LastChildFill = "True"> <!-- Dock items to the panel using attached properties. --> <Label DockPanel.Dock = "Top" Name = "lblinstruction" FontSize = "15" Content = "Label One"/> <Label DockPanel.Dock = "Left" Name = "lblmake" Content = "Label Two"/> <Label DockPanel.Dock = "Right" Name = "lblcolor" Content = "Label Three"/> <Label DockPanel.Dock = "Bottom" Name = "lblpetname" Content = "Label Four"/> <Button Name = "btnok">ok</button> </DockPanel> </Window> 1-42

Understand that attached properties cannot be used as a general-purpose syntax that can be used to set any property on a parent element. The IntelliSense of Visual Studio will show you valid attached properties for a given element. In reality, attached properties are a specialized form of a WPF-specific concept termed dependency property. Thus, attached-property syntax can only work if the property supports the correct dependency property infrastructure. See Appendix B for more information on dependency properties. 1-43

The Role of XAML Markup Extensions Although the majority of property values can be assigned using strings or via property-element syntax, some property values cannot, as in the following cases: You wish to assign a property value to an object created elsewhere (in code, as a logical resource, and so forth). You wish to assign a property to a value calculated at runtime. For these and other reasons, XAML supports markup extensions. In a nutshell, markup extensions are used to set property values in nonstandard ways. Again, these nonstandard ways typically involve referring to objects allocated elsewhere or data computed at runtime. Like a type converter, markup extensions have a class-based equivalent in the WPF libraries. And like type converters, these classes seldom need to be used directly in your code. A XAML markup extension is encased within curly brackets at the time you assign a property value. Here is a general template to follow. <DefiningType DefiningTypeProperty = "{x:markupextension Value}" > </DefiningType> XAML provides a number of markup extensions, several of which you examined in the previous table of XAML tokens. For example, Array, Null, Static, Type, StaticResource, and DynamicResource are markup extensions. 1-44

You will see the use of many markup extension during the remainder of this class. In the meantime, here are a few examples. Assume you wish to set the Content property for a set of Labels. The values are to be computed at runtime, based on various static properties of the System.Environment type. As you may know, System.Environment is defined in mscorlib.dll. Therefore, you must define a new XML namespace (named CorLib) that maps to this library. Note the use of the {x:static} markup extension. <Window x:class = "FunWithMarkUpExtensions.Window1" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:corlib = "clr-namespace:system;assembly=mscorlib" Title = "Fun with Markup Extensions" Height = "300" Width = "300"> <StackPanel> <Label Content = "{x:static CorLib:Environment.MachineName}"/> <Label Content = "{x:static CorLib:Environment.OSVersion}"/> <Label Content = "{x:static CorLib:Environment.ProcessorCount}"/> </StackPanel> </Window> 1-45

Now consider the use of the {x:type} markup extension, which extracts type information for a given member: {x:type} is the XAML equivalent of calling Type.GetType(). Assume the following update to the <StackPanel> type. Notice the Labels now contain the fully qualified name of the type. <StackPanel> <Label Content = "{x:type Label}" /> <Label Content = "{x:type Page}" /> <Label Content = "{x:type CorLib:Boolean}" /> </StackPanel> Lab Exercise: Building a WPF Application (all XAML) 1-46

Separation of Concerns Using Code Files Few WPF applications will take the 100% code or 100% XAML approach as you have seen thus far. In reality, a middle of the road approach is recommended. Similar to an ASP.NET web application, WPF allows you to have a C# (or VB) file that works in conjunction with a related XAML file. The XAML file is only concerned with UI descriptions defined via markup. The code file is concerned with programming logic. Elements defined in XAML can be accessed in the code file and vice versa if required. To do so, you should assign a Name property to the XAML element. Here is the simple WPF application yet again, this time making use of code files. As a naming convention, code files have -xaml- embedded within the file name. However, this is not required. Recall from your previous lab that the auto-generated *.g.cs / *.g.vb file completes your partial class definition. The InitializeComponent() method is defined within an auto-generated *.g.cs / *.g.vb file. 1-47

// MainWindow.xaml.cs using System; using System.Windows; using System.Windows.Controls; namespace SimpleXamlApp { public partial class MainWindow : Window { public MainWindow() { // This method is defined // within the generated MainWindow.g.cs file. InitializeComponent(); } } } private void btnexitapp_clicked(object sender, RoutedEventArgs e) { // Get a handle to the current application and shut it down. Application.Current.Shutdown(); } The Application definition could also make use of the code-file approach. The XAML file would still contain the StartupUri property setting and so on. // MyApp.xaml.cs using System; using System.Windows; using System.Windows.Controls; namespace SimpleXamlApp { public partial class MyApp : Application { private void AppExit(object sender, ExitEventArgs e) { MessageBox.Show("App has exited"); } } } 1-48

The code-file approach is the default behavior of Visual Studio WPF apps. When you select the WPF project template from the File New Project menu, you are given an Application-derived type and initial Window-derived type. Each type is composed of a *.cs / *.vb file, *.xaml file, and the auto-generated *.g* file. Collectively, these three partial class definitions provide complete functionality. 1-49

Visual Studio WPF Designer Support WPF applications can be built using nothing more than a simple text editor, a.net language compiler (C#, VB), and msbuild.exe. However, doing so for a large-scale project would be tedious and error prone. Thankfully, Visual Studio has integrated WPF programming support that includes the following: WPF project templates. Integrated XAML editors. A WPF-aware Toolbox / Properties window. 1-50

The New Project dialog box provides a number of WPF project templates. The WPF Application icon is used to build a traditional desktop executable. The WPF Browser Application project template provides a starting point for XBAP development. You also have project types for custom WPF control libraries. 1-51

The WPF designer allows you to view not only the window / page itself but the underlying XAML. You can build the UI of your form using the WPF Toolbox and related VS Properties window. As an alternative, you can directly author XAML markup to change the UI of the window you are constructing. Notice the XAML editor supports the expected IntelliSense. 1-52

The XAML editor also provides the ability to generate event handlers for events declared via XAML. When you enter the name of an event for a given widget, you will find a New Event Handler pop up window. Selecting this option will generate a name for your event handler. The corresponding code file will contain the handler. The corresponding *.g.cs / *.g.vb file will contain the event wire-up logic. 1-53

As well, Visual Studio has a sophisticated Properties editor for selected WPF elements. This support is far superior to what was found in earlier versions of Visual Studio. You can now find tools to generate brushes, configure data binding, resource management and so forth. Also notice the "lightning bolt" button provides a different way to handle events (just like you would do for an ASP.NET or Windows Forms application). Be sure to take the time to explore the Properties window during your lab time. Lab Exercise: Building a WPF Application (Code Files) 1-54