Windows Presentation Foundation 4.5 Cookbook - Pavel Yosifovich - E-Book

Windows Presentation Foundation 4.5 Cookbook E-Book

Pavel Yosifovich

0,0
47,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.
Mehr erfahren.
Beschreibung

Windows Presentation Foundation (WPF) provides developers with a unified programming model for building rich Windows smart client user experiences that incorporate UI, media, and documents.WPF has become the leading technology for developing rich client applications on the Windows platform, packed with features and capabilities. However, WPF is big; in fact, it's huge, causing a steep learning curve for the beginner and even for those already using some WPF features.Windows Presentation Foundation 4.5 Cookbook provides clear recipes for common WPF tasks. It includes detailed explanations and code examples for customizing and enhancing the basic scenarios, while gaining a deep understanding of WPF mechanics and capabilities.WPF is different and requires a different mind-set and approach. This book provides recipes and insights not only in its design but also its practical implementation details.Starting from the foundations of WPF, such as dependency properties and XAML, the book touches on all major WPF aspects, such as controls and layout, resources, and digs deep into its unprecedented data binding capabilities.The book shows data and control templates in action, which allow full customizations of displayed data and controls in a declarative way. Supported by styles and resources makes data binding all the more powerful. The Model View View-Model pattern is presented as an effective way of maximizing decoupling of components, while providing an elegant way of expanding applications while maintaining a tight grip on complexity.The later parts discuss custom elements and controls ñ the ultimate customization mechanism, and looks at multithreading issues, and how .NET 4.5 task parallelism features can enhance application performance.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 531

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Table of Contents

Windows Presentation Foundation 4.5 Cookbook
Credits
About the Author
About the Reviewers
www.PacktPub.com
Support files, eBooks, discount offers and more
Why Subscribe?
Free Access for Packt account holders
Instant Updates on New Packt Books
Preface
What this book covers
What you need for this book
Who this book is for
Conventions
Reader feedback
Customer support
Downloading the example code
Errata
Piracy
Questions
1. Foundations
Introduction
XAML
XAML and compilation
Dependency properties
Creating custom type instances in XAML
Getting ready
How to do it...
How it works...
There's more...
Creating a dependency property
Getting ready
How to do it...
How it works...
There's more...
Property value inheritance
Why "dependency"?
Dependency property levels
Using an attached property
Getting ready
How to do it...
How it works...
There's more...
Why an attached property?
Does the declaring type "own" the property?
See also
Creating an attached property
Getting ready
How to do it...
How it works...
There's more...
Reusing existing attached properties
See also
Accessing a static property from XAML
Getting ready
How to do it...
How it works...
There's more...
Creating a custom markup extension
Getting ready
How to do it...
How it works...
There's more...
Don't go overboard
Handling routed events
Getting ready
How to do it...
How it works...
There's more...
Stopping bubbling or tunneling
Attached events
2. Resources
Introduction
Using logical resources
Getting ready
How to do it...
How it works...
There's more...
Adding or deleting resources dynamically
Modifying resources
Resources that use other resources
Non-shared resources
Other locations for resources
Dynamically binding to a logical resource
Getting ready
How to do it...
How it works...
There's more...
Using user-selected colors and fonts
Getting ready
How to do it...
How it works...
There's more...
Using binary resources
Getting ready
How to do it...
How it works...
There's more...
Embedded Resource
Accessing binary resources in code
Getting ready
How to do it...
How it works...
There's more...
Accessing binary resources from another assembly
Getting ready
How to do it...
How it works...
There's more...
Managing logical resources
Getting ready
How to do it...
How it works...
There's more...
Duplicated keys
3. Layout and Panels
Introduction
The layout process
Coordinates systems in WPF
Creating a table-like user interface
Getting ready
How to do it...
How it works...
There's more...
Shared row/column size
Placement in the same cell
The power of the Grid
Adding rows/columns dynamically
The UniformGrid
Dynamically sizing grid rows/columns
Getting ready
How to do it...
How it works...
There's more...
Creating a scrollable user interface
Getting ready
How to do it...
How it works...
There's more...
Creating a border around panels and elements
Getting ready
How to do it...
How it works...
Placing elements in exact positions
Getting ready
How to do it...
How it works...
There's more...
Canvas has no background
Canvas is not limited to its bounds
Adding/removing elements to a panel dynamically
Getting ready
How to do it...
How it works...
Creating a tabbed user interface
Getting ready
How to do it...
How it works...
There's more...
Implementing drag-and-drop
Getting ready
How to do it...
How it works...
There's more...
Built-in drag-and-drop
Drag-and-drop to other applications
4. Using Standard Controls
Introduction
Working with text
Getting ready
How to do it...
How it works...
There's more...
Using content controls
Getting ready
How to do it...
How it works...
There's more...
Headered content controls
See also
Displaying images
Getting ready
How to do it...
How it works...
There's more...
See also
Creating tooltips
Getting ready
How to do it...
How it works...
There's more...
Deeper tooltip customization
Realistic tooltips
Creating a list of items
Getting ready
How to do it…
How it works...
There's more...
Creating a standard menu
Getting ready
How to do it…
How it works...
There's more...
Other MenuItem properties and events
Creating a context menu
Getting ready
How to do it…
How it works...
There's more...
Selecting options with checkboxes and radio buttons
Getting ready
How to do it…
How it works...
Manipulating tab order and focus
Getting ready
How to do it…
How it works...
There's more...
Keyboard focus versus logical focus
5. Application and Windows
Introduction
Creating a window
Getting ready
How to do it...
How it works...
There's more...
Selecting the startup window dynamically
Accessing command line arguments
Creating a dialog box
Getting ready
How to do it...
How it works...
There's more...
Modeless dialogs
Using the common dialog boxes
Getting ready
How to do it...
How it works...
There's more...
What about colors and fonts?
The Windows API Code Pack
Creating ownership between windows
Getting ready
How to do it...
How it works...
There's more...
Creating a custom shaped window
Getting ready
How to do it...
How it works...
There's more...
What about reusability?
Creating a single instance application
Getting ready
How to do it...
How it works...
There's more...
Handling an unhandled exception
Getting ready
How to do it...
How it works...
There's more...
6. Data Binding
Introduction
Element to element binding
Getting ready
How to do it...
How it works...
There's more...
Binding mode
Update source trigger
Updating the source or target manually
Binding to a single object
Getting ready
How to do it...
How it works...
There's more...
When bindings fail
Other ways of getting a source binding object
Implementing INotifyPropertyChanged
Implementing SetProperty with Visual Studio 2012 and C# 5.0
Binding to a collection
Getting ready
How to do it...
How it works...
There's more...
Synchronizing selected items
Data binding and the Items property are mutually exclusive
What about "real" data?
Using data templates
Getting ready
How to do it...
How it works...
There's more...
Data type based data templates
Data template selectors
Using value converters
Getting ready
How to do it...
How it works...
There's more...
Using converters for debugging
Formatting strings
Customizing with data triggers
Creating a master-detail view
Getting ready
How to do it...
How it works...
There's more...
A simpler selected item binding
Sorting and filtering bound collections
Getting ready
How to do it...
How it works...
There's more...
More features of ICollectionView
Live shaping
Grouping bound collections
Getting ready
How to do it...
How it works...
There's more...
Grouping by a non-property
See also
Binding to multiple properties
Getting ready
How to do it...
How it works...
There's more...
Binding hierarchical data to a TreeView
Getting ready
How to do it...
How it works...
There's more...
Presenting data in a grid
Getting ready
How to do it...
How it works...
There's more...
Editing with a template-based column
Selecting, resizing, and sorting
Other customization options
Validating data
Getting ready
How to do it...
How it works...
There's more...
Custom validation rules
Custom error template
Using data annotations
7. Commands and MVVM
Introduction
Using routed commands
Getting ready
How to do it...
How it works...
There's more...
Built-in implementations
Command sources
Alternative ICommand implementations
Implementing a basic MVVM application
Getting ready
How to do it...
How it works...
There's more...
Implementing ICommand
Blendability
Building a simple MVVM framework
Getting ready
How to do it...
How it works...
There's more...
Non-ICommandSource elements and other events
What about Prism?
Building a complete MVVM style application
Getting ready
How to do it...
How it works...
There's more...
MVVM implementations
Creating an undo/redo system
Getting ready
How to do it...
How it works...
8. Styles, Triggers, and Control Templates
Introduction
Creating and using styles
Getting ready
How to do it...
How it works...
There's more...
Style inheritance
Other places to set styles
Applying a style automatically
Getting ready
How to do it...
How it works...
There's more...
Creating a property trigger
Getting ready
How to do it...
How it works...
There's more...
Trigger limitations
When to use triggers
Other locations of triggers
Trigger priorities
See also
Using data triggers
Getting ready
How to do it...
How it works...
Creating an event trigger
Getting ready
How to do it...
How it works...
There's more...
Creating a multi trigger
Getting ready
How to do it...
How it works...
There's more...
Using behaviors
Getting ready
How to do it...
How it works...
There's more...
Custom behaviors
Replacing the control template of a progress bar
Getting ready
How to do it...
How it works...
There's more...
What about the control's properties?
Combining a control template with a style
Extending a template with attached properties
Can we replace just part of a template?
What about the Visual State Manager?
Replacing the control template of a scroll bar
Getting ready
How to do it...
How it works...
Customizing selection in a Selector control
Getting ready
How to do it...
How it works...
There's more...
9. Graphics and Animation
Introduction
Creating a custom shape
Getting ready
How to do it...
How it works...
There's more...
Geometries
Built-in shapes
Shapes versus geometries
Applying transforms on elements
Getting ready
How to do it...
How it works...
There's more...
Other uses for transforms
Manipulating a bitmap programmatically
Getting ready
How to do it...
How it works...
There's more...
How about higher-level access to WriteableBitmap?
See also
Creating adorners
Getting ready
How to do it...
How it works...
There's more...
Creating property-based animations
Getting ready
How to do it...
How it works...
There's more...
Alternative way to specify the animation property
More on storyboards
Animations with Expression Blend
Should I always use animations?
Creating path-based animations
Getting ready
How to do it...
How it works...
There's more...
Animation performance
Creating custom animations
Getting ready
How to do it...
How it works...
Adding animation easing to animations
Getting ready
How to do it...
How it works...
There's more...
Using custom effects with pixel shaders
Getting ready
How to do it...
How it works...
There's more...
Using the built-in effects
Other shader types
What about the BitmapEffect class and its derivatives?
10. Custom Elements
Introduction
Creating a user control
Getting ready
How to do it...
How it works...
There's more...
Optimizing converters
Adding a tunneling event
Handling standard commands in a user control
Getting ready
How to do it...
How it works...
There's more...
Creating a custom (templated) control
Getting ready
How to do it...
How it works...
There's more...
Other things to set in code
What is that Generic.xaml?
Refactoring of Generic.xaml
Customizing a default template of custom control
Getting ready
How to do it...
How it works...
Creating a custom panel
Getting ready
How to do it...
How it works...
There's more...
Where are custom panels used?
Creating a lightweight custom element
Getting ready
How to do it...
How it works...
There's more...
Dependency property ownership
More DrawingContext
11. Threading
Introduction
Updating the UI from a non-UI thread
Getting ready
How to do it...
How it works...
There's more...
Dispatcher alternative
Dispatcher enhancements in WPF 4.5
More Dispatcher
What about data binding?
Adding cancelation support
Getting ready
How to do it...
How it works...
There's more...
Never cancel by aborting a thread
Using the BackgroundWorker component
Getting ready
How to do it...
How it works...
There's more...
Did we really have to pass the argument to RunWorkerAsync?
What about the Task Parallel Library?
Adding cancellation and progress with BackgroundWorker
Getting ready
How to do it...
How it works...
There's more...
What about Parallel.For?
Using a timer to do periodic updates
Getting ready
How to do it...
How it works...
There's more...
Using C# 5.0 to perform asynchronous operations
Getting ready
How to do it...
How it works...
There's more...
What about non-CPU bound operations?
More async
Index

Windows Presentation Foundation 4.5 Cookbook

Windows Presentation Foundation 4.5 Cookbook

Copyright © 2012 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

First published: September 2012

Production Reference: 1150912

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham B3 2PB, UK.

ISBN 978-1-84968-622-8

www.packtpub.com

Cover Image by Mark Holland (<[email protected]>)

Credits

Author

Pavel Yosifovich

Reviewers

Alon Fliess

Ariel Ben Horesh

Stas Shteinbook

Dan Vestergaard

Acquisition Editor

Rukshana Khambatta

Lead Technical Editor

Kedar Bhat

Technical Editor

Madhuri Das

Project Coordinator

Yashodhan Dere

Proofreaders

Aaron Nash

Maria Gould

Indexer

Rekha Nair

Graphics

Aditi Gajjar

Production Coordinator

Shantanu Zagade

Cover Work

Shantanu Zagade

About the Author

Pavel Yosifovich is the CTO of CodeValue (http://www.codevalue.net), a software development, consulting, and training company, based in Israel. He writes, consults, and trains developers on various software development topics, from Windows internals, to .NET enterprise systems, and almost everything in between. He’s a Microsoft MVP and a frequent speaker at national events, such as Tech-Ed and DevAcademy.

In the past, he co-founded the startup company Quiksee that was acquired by Google in September 2010.

Writing a book is a tremendous effort, even if you know what you want to write (and I didn’t some of the time). It wasn’t possible without the support of my family: my wife Idit, and my kids, Daniel and Amit, and the latest recruit, Yoav. Thank you for the making the time and more than that – thank you for the support and encouragement along the way. It’s certainly easy to give up, but you wouldn’t let me – so thank you again!

About the Reviewers

Alon Fliess is the chief architect and founder of CodeValue. CodeValue is the home of software experts. CodeValue builds software tools, foundations, and products for the software industry and offers mentoring, consulting, and project development services.

Alon got his BSc degree in Electrical and Computer Engineering from the Technion, the Israel Institute of Technology. He is an expert on many Microsoft technologies, be it Windows client and server programming using C#/C++/.NET, Windows Azure Cloud Computing, or Windows internals. Microsoft has recognized his expertise and community activities and granted him two awards: Microsoft Regional Director (MRD) and a VC++ MVP.

Alon has deep knowledge and understanding of Windows and Windows Internals. He is a co-author of Windows 7 Microsoft Training Program as well as a co-author of the Introducing Windows 7 for Developers book (ISBN-10: 0735626820)

Alon delivers courses and lectures in many seminars and conferences around the world, such as TechEd Europe, TechEd USA, NDC, and in Israel. Alon is a senior Software Architect; he deals with vast and complex projects. Alon architected and designed the software for the revolutionary new line of industrial printing machine of Landa Labs. He is also the architect of one of the largest software project of the Israeli Air Force. Alon is responsible for several open-source projects.

Many thanks to Pavel and Yashodhan, who gave me the opportunity to take part in the creation of this book.

Ariel Ben Horesh is a well-known .NET expert, team leader, and community leader.

With more than 10 years of experience in the software industry, Ariel now works at CodeValue, a company he co-founded, where he creates products for developers, and consults and conducts courses around the world on UI development: WPF/SL, Web, Mobile, and UI architecture.

You can visit his blog at: http://arielbh.com

Stas Shteinbook is a senior development leader and solution architect who works at CodeValue. He has a long history in developing large enterprise applications, guiding their architecture and developing process, and creating end-to-end solutions involving rich user experience interfaces using WPF technology.

I would like to thank my family, my mother Ludmila and my father Zinoviy, for all the help and support.

Dan Vestergaard is currently working as a software engineer, with primary focus on .NET, and in particular, developing user interfaces using WPF.

He has worked in the consultant business and for several years in financial and industrial businesses. He is now a software engineer in a large world-wide industrial company, writing WPF applications for factory quality control systems.

He started working with WPF in the early beta days, back in 2006, and has loved it ever since.

www.PacktPub.com

Support files, eBooks, discount offers and more

You might want to visit www.PacktPub.com for support files and downloads related to your book.

Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at <[email protected]> for more details.

At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

http://PacktLib.PacktPub.com

Do you need instant solutions to your IT questions? PacktLib is Packt’s online digital book library. Here, you can access, read and search across Packt’s entire library of books. 

Why Subscribe?

Fully searchable across every book published by PacktCopy and paste, print and bookmark contentOn demand and accessible via web browser

Free Access for Packt account holders

If you have an account with Packt at www.PacktPub.com, you can use this to access PacktLib today and view nine entirely free books. Simply use your login credentials for immediate access.

Instant Updates on New Packt Books

Get notified! Find out when new books are published by following @PacktEnterprise on Twitter, or the Packt Enterprise Facebook page.

Preface

Windows Presentation Foundation has been in release since late 2006, as a part of the then .NET 3.0 Framework, also preinstalled on Windows Vista at the time. It promised to change the way rich client applications are written, and eventually replace the old, Win32-based Windows Forms.

WPF gained traction slowly because of its enormous breadth and the different kind of thinking that was required—using XAML, data binding, templates, and styles was very different from the classic WinForms way of working. The power of WPF was evident, but it was difficult to master, and had a steep learning curve.

Over the years things changed; developers started to get used to and appreciate the new way of doing things. XAML began to look convenient and powerful and not just an extra thing to learn with little benefit. Still, for the newcomer, with or without WinForms experience, WPF looks daunting and uncontrollable.

Patterns have emerged, most notably the Model-View-View Model (MVVM), a variant of other existing view-data separation patterns (MVC and MVP), that made life easier (most of the time) but more importantly set a standard way of interaction of view and data; and although many implementations are possible (this is just a pattern, after all), it does let an application be built in more confidence, piece by piece.

This book holds a set of recipes that show how to do common tasks. But don’t just look at the recipes; instead, look at the other sections to deepen your understanding of WPF. No matter the number of recipes, there will always be other things an application needs that no book can cover; by understanding the foundations well, it’s possible to tackle any problem. This is why I have tried to emphasise the why, and not just the how.

WPF led to a bunch of other technologies being built on similar principles, namely Silverlight (cross browser web client development in .NET), Windows Phone 7.x (Microsoft’s Phone OS that uses a Silverlight variant), and lately Windows 8 and Windows Phone 8—all built around similar concepts such as XAML, dependency properties, templates, styles, and bindings—this shows the power and impact of WPF.

What this book covers

Chapter 1, Foundations, introduces the most important concepts in WPF. From the XAML language, to dependency properties, to attached events.

Chapter 2, Resources, discusses WPF’s unique resource system that allows any object to be placed as a resource and consequently shared in an efficient and flexible way.

Chapter 3, Layout and Panels, discusses how WPF manages layout of elements, including looking at the standard layout panels, how they work, and how they can be combined to produce complex and flexible interfaces.

Chapter 4, Using Standard Controls, looks at the major controls in WPF and how they are typically used. The content model is also discussed, along with other control families.

Chapter 5, Application and Windows, takes a look at a WPF application from a higher perspective, including application level resources and the way windows are used and managed.

Chapter 6, Data Binding, discusses the powerful and important concept of data binding and the way it’s used in WPF, including leveraging data templates, converters, and other ideas that make WPF so powerful.

Chapter 7, Commands and MVVM, looks at the way a moderately complex application might be built, by leveraging higher level abstractions known as commands (as opposed to raw events). The MVVM pattern is introduced with some implementation to show how commands, data binding and some extra ingredients can produce a complex, yet manageable, application.

Chapter 8, Styles, Triggers, and Control Templates, shows some of the ways controls can be customized in XAML only, without the need to derive new types for the sake of appearance only.

Chapter 9, Graphics and Animation, provides a tour of the major graphic and animation capabilities of WPF and how they integrate with other mechanisms such as styles and triggers.

Chapter 10, Custom Elements, shows what is required to create custom elements with the considerations that lead to a particular implementation path.

Chapter 11, Threading, discusses WPF’s support for asynchronous operations, so that the UI is responsive at all times, including the support provided in C# 5.0 for performing asynchronous operations more easily.

What you need for this book

The books assumes the reader is a .NET developer working with C# (at least version 2.0, but 3.0 is preferred), and is comfortable working with generics, virtual methods, delegates, and lambdas (C# 3.0). Some WPF exposure is assumed. Visual Studio 2010 as well as Visual Studio 2012 for some features of .NET 4.5.

Who this book is for

The book is intended for developers who are relatively new to WPF, or those who have been working with WPF for a while, but want to a get a deeper understanding of its mechanisms and concepts.

Conventions

In this book, you will find a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning.

Code words in text are shown as follows: "the typical Window class is declared as partial, meaning there may be more source files describing the same class".

A block of code is set as follows:

class Book { public string Name { get; set; } public string Author { get; set; } public decimal Price { get; set; } public int YearPublished { get; set; } }

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

<Window x:Class="CH01.CustomTypes.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CH01.CustomTypes"

New terms and important words are shown in bold. Words that you see on the screen, in menus or dialog boxes for example, appear in the text like this: "right-click on the project node and select Add and then Class…".

Note

Warnings or important notes appear in a box like this.

Tip

Tips and tricks appear like this.

Reader feedback

Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of.

To send us general feedback, simply send an e-mail to <[email protected]>, and mention the book title through the subject of your message.

If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide on www.packtpub.com/authors.

Customer support

Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Errata

Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub.com/support, selecting your book, clicking on the errata submission form link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata will be uploaded to our website, or added to any list of existing errata, under the Errata section of that title.

Piracy

Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy.

Please contact us at <[email protected]> with a link to the suspected pirated material.

We appreciate your help in protecting our authors, and our ability to bring you valuable content.

Questions

You can contact us at <[email protected]> if you are having a problem with any aspect of the book, and we will do our best to address it.

Chapter 1. Foundations

In this chapter we will cover the following:

Creating custom type instances in XAMLCreating a dependency propertyUsing an attached propertyCreating an attached propertyAccessing a static property in XAMLCreating a custom markup extensionHandling routed events

Introduction

Any attempt at mastering a technology, any technology, requires a good understanding of its foundations. This understanding makes it possible to grasp the more complex aspects of that technology; Windows Presentation Foundation (WPF) is no different.

In this first chapter, we'll discuss recipes concerning the very foundations of WPF – what makes it tick—and also along the way, what makes it unique.

XAML

The first noticeable facet of WPF is XAML (eXtensible Markup Language). XAML is an XML based language used in WPF to declaratively create user interfaces. Actually, XAML has nothing to do with UI. It's merely a declarative way of constructing objects and setting their properties. In fact, it's leveraged in other technologies, such as the Windows Workflow Foundation (WF), where it's used as a way of constructing workflows. To create objects in XAML, they must be "XAML friendly" – meaning they must have the following:

A public default constructorSettable public properties

The second item is not strictly a requirement, but the lack of settable properties would make the object a bit dull. Note that starting with .NET 4, XAML is in fact capable of handling parameterized constructors, but WPF's XAML parser currently does not leverage that capability.

XAML is not an absolute requirement. In fact, you can create an entire application using C# or VB (or whichever .NET language you fancy) without a single XAML tag. However, that would be much more difficult and error prone with high maintenance costs, not to mention the difficulty of integration with your fellow designers.

XAML is about the what, not the how. This declarative style makes things easier (granted, after some getting used to), and is a paradigm shift in software development in general (the classic example in .NET being the LINQ-based technologies). XAML is neutral—it's not C# or anything like that—so other, non-developer tools can create or manipulate it. Microsoft provides the Expression Blend tool, which at its core, is a glorified XAML producer/consumer.

XAML and compilation

What happens to a XAML file? How is it tied to the code behind file created by Visual Studio? A XAML file is compiled by a XAML compiler that produces a binary version of the XAML, known as BAML. This BAML is stored as a resource inside the assembly and is parsed at runtime in the InitializeComponent call to create the actual objects. The result is bundled with the code behind file (the typical Window class is declared as partial, meaning there may be more source files describing the same class) to produce the final code for that class.

Browsing a typical WPF application, we won't find the canonical Main method, because it's generated by WPF. It constructs the singleton Application object instance and creates the first window specified by the Application.StartupUri property (if not null). We can find that code in the file App.g.cs (g stands for generated) inside the Obj\x86\Debug sub-folder.

Dependency properties

.NET properties are nothing more than syntactic sugar over set and get methods. What those methods do is up to the property's developer. More often than not, a property is a thin wrapper over a private field, perhaps adding some validation logic in its setter.

WPF requires more out of its properties. Specifically, WPF's dependency properties provide the following:

Change notifications when the property's value is changed.Validation handler called as part of a set operation.Coercion handler that is able to "coerce" the provided value to an acceptable value.Various providers can attempt to set the property's value, but only one such provider wins at a time. Nevertheless, all values are retained. If the winning provider goes away, the property's value is set to the next winner in line.Property value inheritance down the visual tree (if so desired).No memory is allocated for a property's value if that value is never changed from its default.

These features provide the basis of some of WPF's strong features, such as data binding and animation.

On the surface, these properties look the same as any other property—a getter and a setter. But no private fields are involved, as we'll see in the following recipes.

Creating custom type instances in XAML

Sometimes there's a need to create instances of your own types, or other .NET Framework, non-WPF types within XAML. A classic example is a data binding value converter (which we'll explore in Chapter 6, Data Binding, but other scenarios might call for it).

Getting ready

Make sure you have Visual Studio 2010 up and running.

How to do it...

We'll create a simple application that creates an instance of a custom type in XAML to demonstrate the entire procedure:

Create a new WPF Application project named CH01.CustomTypes.Let's create a custom type named Book. In the Solution Explorer window, right-click on the project node and select Add and then Class…:Type Book in the Name box and click on Add: Add four simple properties to the resulting class:
class Book { public string Name { get; set; } public string Author { get; set; } public decimal Price { get; set; } public int YearPublished { get; set; } }

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.PacktPub.com. If you purchased this book elsewhere, you can visit http://www.PacktPub.com/support and register to have the files e-mailed directly to you.

Open the MainWindw.xaml file (using the Solution Explorer), which was created automatically by the project wizard. We would like to create an instance of the Book class. As a Book is not an element (does not derive from UIElement), we cannot simply create it inside our Grid. But, we can make it the Content property (that can be anything, as its type is Object) of a ContentControl-derived type, such as Button. Add a button control to the existing grid, as follows:
<Grid> <Button FontSize="20"> </Button> </Grid>
To create an instance of Book, we first need to map the .NET namespace (and assembly) where Book is defined to an XML namespace that can be used by the XAML compiler. Let's add a mapping at the top of the XAML near the default mappings added by the application wizard:
<Window x:Class="CH01.CustomTypes.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:CH01.CustomTypes"
This says that anything prefixed by the string local (we can select anything here), should be looked up in the CH01.CustomTypes namespace (in the current assembly).Now, we can finally create a Book instance. Add the following inside the Button tag:
<Button FontSize="20"> <local:Book Name="Windows Internals" Author="Mark Russinovich" Price="40" YearPublished="2009" /> </Button>
That's it. We can verify this by adding a suitable ToString implementation to the Book type, and running the application:
public override string ToString() { return string.Format("{0} by {1}\nPublished {2}", Name, Author, earPublished); }

How it works...

The XAML compiler needs to be able to resolve type names such as Button or Book. A simple name like Button is not necessarily unique, not in the XML sense and certainly not in the .NET sense (there are at least four Button types in .NET, naturally in diffrent namespaces) .

A mapping is required between an XML namespace and a .NET namespace, so that the XAML compiler can reference the correct type. By default, two XML namespaces are declared by a typical XAML file: the first, which is the default XML namespace, is mapped to the normal WPF namespaces (System.Windows, System.Windows.Controls, and so on). The other, typically with the x prefix, is mapped to the XAML namespace (System.Windows.Markup).

For our own types, we need to do similar mapping (but with a different syntax) means map the XML namespace prefix local to the .NET namespace CH01.CustomTypes. The following line:

xmlns:local="clr-namespace:CH01.CustomTypes"

This allows our Book class to be recognized and used within the XAML.

If the type was defined in a referenced assembly (not our own assembly), then the mapping would continue to something like the following:

xmlns:local="clr-namespace:CH01.CustomTypes;assembly=MyAssembly"

For example, suppose we want the ability to create instances of the System.Random type. Here's how we'd map an XML namespace to the .NET namespace and assembly where Sysem.Random resides:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

Now, we could create an instance of anything in the System namespace (that is XAML friendly) and the mscorlib assembly (such as Random):

<sys:Random x:Key="rnd" />

In this case, it's hosted in a ResourceDictionary (which is a kind of dictionary, meaning every value requires a key; we'll discuss these in more detail in the next chapter).

There's more...

It's possible to map a single XML namespace to multiple .NET namespaces. This is the same technique used by the WPF assemblies itself: a single XML namespace maps to multiple WPF namespaces, such as System.Windows, System.Windows.Controls, and System.Windws.Media.

The trick is to use the XmlnsDefinition attribute within the assembly where the exported types reside. This only works for referenced assemblies; that is, it's typically used in class library assemblies.

For example, suppose we create a MyClassLibrary class library assembly, with a type like the Book introduced earlier:

namespace MyClassLibrary { public class Book { public string Name { get; set; } public string Author { get; set; } public decimal Price { get; set; } public int YearPublished { get; set; } } }

We can make all types within this assembly and the MyClassLibrary namespace part of an XML namespace by adding the following attribute:

[assembly: XmlnsDefinition("http://mylibrary.com", "MyClassLibrary")]

The first argument to the attribute is the XML namespace name. This can be anything, but is typically some form of fictitious URL (usually a variation on the company's URL), so as to lower chances of collisions (this is exactly the same idea used by WPF). The second string is the .NET namespace mapped by this XML namespace.

Now, suppose we have another .NET namespace within that same assembly with some types declared within it:

namespace MyClassLibrary.MyOtherTypes { public class MyType1 { //... } public class MyType2 { //... } }

We can add another attribute to map the same XML namespace to the new .NET namespace:

[assembly: XmlnsDefinition("http://mylibrary.com", "MyClassLibrary.MyOtherTypes")]

This means that a single XML prefix (in some client application) can now map to multiple .NET namespaces:

xmlns:mylib="http://mylibrary.com"

This scheme can save multiple distinct XML prefix declarations. One consequence of this idea is that all public type names must be unique across the mapped .NET namespaces (as they are indeed within WPF itself).

Using an attached property

Attached properties are curious beings. There is no direct analogue to anything else in the .NET framework. The closest may be extension methods, introduced in C# 3.0. Extension methods are a way of extending a type without inheriting from it (even if that type is sealed). Attached properties are dependency properties that are defined by some type, but can be used by (almost) any other typed object. That is, they can extend a type's properties without code derivation. In this recipe, we'll see how to use an existing attached property, and in the next one we'll learn how to create a new attached property.

Getting ready

Make sure Visual Studio is up and running.

How to do it...

We'll create an application that creates a rectangle and places it inside a canvas at exact coordinates using attached properties:

Create a new WPF Application named CH01.SimpleAttached.Open the MainWindow.xaml file and create the following basic layout:
<Grid> <Canvas> <RepeatButton Content="Move" /> </Canvas> </Grid>
This creates a grid which hosts a Canvas and that canvas hosts a RepeatButton. Let's add a Rectangle element to the Canvas and place it in some position:
<Canvas> <RepeatButton Grid.Row="1" Content="Move" /> <Rectangle x:Name="_rect" Width="50" Height="50" Fill="Red" Stroke="Black" StrokeThickness="5" Canvas.Left="30" Canvas.Top="40" /> </Canvas>
Run the application. You should see something like this:The Canvas.Left and Canvas.Top are attached properties. They are defined by the Canvas type, but they can be applied to any element (technically, anything that derives from DependencyObject). In this case, these two properties are applied to the Rectangle, essentially "extending" its property set with two new properties. The syntax DefiningClassName.PropertyName is the way to access an attached property in XAML.Now let's try changing these properties in code. When the repeat button is clicked, let's move the rectangle a little bit to the right. First, let's name the Rectangle, so we can easily refer to it in code:
<Rectangle x:Name="_rect" Width="50" Height="50" Fill="Red" Stroke="Black" StrokeThickness="5" Canvas.Left="30" Canvas.Top="40" />
Add a Click event handler to the RepeatButton. In the handler, add the following code:
Canvas.SetLeft(_rect, Canvas.GetLeft(_rect) + 5);
An attached property is accessed in code using a set of static methods on the class declaring the property (in this case, the Canvas). The first argument to these methods is the intended target of the property (in this case the Rectangle). Run the application. Click on the button (and hold); you should see the rectangle moving along to the right, 5 units at a time.

How it works...

An attached property is first and foremost a dependency property, meaning it supports all the capabilities of dependency properties. However, as an attached property is "attached" to an object that did not define it, a simple property like syntax is not possible – as C# does not support the concept of attached properties natively. Instead, the declaring class provides two static methods, named DeclaringType.SetPropertyName and DeclaringType.GetPropertyName, that provide a way to set or get the property value for some object passed in as the first argument (as demonstrated in the last code snippet).

In XAML, things are simpler, as the XAML parser is aware of attached properties, and converts the simpler DeclaringType.PropertyName attribute to the aforementioned Set method.

There's more...

The actual implementation of the Set/Get static methods mentioned above is to call the regular DependencyObject.SetValue/GetValue as for a regular dependency property. This means that the code to move the rectangle could have been written as follows:

_rect.SetValue(Canvas.LeftProperty, (double)_rect.GetValue(Canvas.LeftProperty) + 5);

Why an attached property?

One may wonder why to go to all this trouble for the Left and Top properties. Would it not be simpler to define the Left and Top properties on the (for example) UIElement class and be done with it? These properties could have been normal dependency properties and enjoy the simpler syntax they carry.

The reason is, that a Left or Top property may not always make sense. In fact, it only makes sense when the element is placed within a Canvas. What if the rectangle is inside a Grid? Or a StackPanel? The Left/Top properties wouldn't make sense. This leads to the conclusion that attached properties are a kind of contextual property – they are relevant under particular circumstances, so they can be "attached" if and when actually needed.

Does the declaring type "own" the property?

The previous example may lead to a wrong conclusion. It seems Canvas.Left and the like are only relevant when the element is inside a Canvas. Similarly, the Grid.Row and Grid.Column attached properties only make sense for elements placed inside a Grid. Is this somehow necessary from an attached property point of view?

Not at all. This is just coincidence. The above properties in fact make sense only for elements placed inside their respective declaring type, but that does not have to be the case. For example, suppose we have a button with a tool tip defined:

<Button Content="Copy" ToolTip="Copy the Selected Items" />

If the button is disabled (IsEnabled set to true), the tool tip does not appear at runtime. To make it appear even if the control is disabled, we must set the ToolTipService.ShowOnDisabled attached property to true:

<Button Content="Copy" ToolTip="Copy the Selected Items" ToolTipService.ShowOnDisabled="True"/>

We set the property on the button, but it's defined in the ToolTipService class. This class is not an element (unlike the Canvas for example). In fact, it's a static class (instances of it cannot be created). So, there is no relationship between the button and the ToolTipService class, or between the ToolTip and ToolTipService classes, for that matter. The way this connection is established (so it can have some effect) will be revealed in the next recipe in this chapter.

See also

To create your own attached properties, refer to the next recipe, Creating an attached property.