Share via


Introduction to WPF

Windows Presentation Foundation (WPF) is a next-generation presentation system for building Windows client applications with visually stunning user experiences. With WPF, you can create a wide range of both standalone and browser-hosted applications. An example is the Contoso Healthcare Sample Application that is shown in the following figure.

Contoso Healthcare UI sample

The core of WPF is a resolution-independent and vector-based rendering engine that is built to take advantage of modern graphics hardware. WPF extends the core with a comprehensive set of application-development features that include Extensible Application Markup Language (XAML), controls, data binding, layout, 2-D and 3-D graphics, animation, styles, templates, documents, media, text, and typography. WPF is included in the Microsoft .NET Framework, so you can build applications that incorporate other elements of the .NET Framework class library.

This overview is intended for newcomers and covers the key capabilities and concepts of WPF. Experienced WPF developers seeking a review of WPF may also find this overview useful.

Note

For new and updated WPF features in the .NET Framework 4, see What's New in WPF Version 4.

This topic contains the following sections.

  • Programming with WPF
  • Markup and Code-Behind
  • Applications
  • Controls
  • Input and Commanding
  • Layout
  • Data Binding
  • Graphics
  • Animation
  • Media
  • Text and Typography
  • Documents
  • Customizing WPF Applications
  • WPF Best Practices
  • Summary
  • Recommended Overviews and Samples
  • Related Topics

Programming with WPF

WPF exists as a subset of .NET Framework types that are for the most part located in the System.Windows namespace. If you have previously built applications with .NET Framework using managed technologies like ASP.NET and Windows Forms, the fundamental WPF programming experience should be familiar; you instantiate classes, set properties, call methods, and handle events, all using your favorite .NET Framework programming language, such as C# or Visual Basic.

To support some of the more powerful WPF capabilities and to simplify the programming experience, WPF includes additional programming constructs that enhance properties and events: dependency properties and routed events. For more information on dependency properties, see Dependency Properties Overview. For more information on routed events, see Routed Events Overview.

Markup and Code-Behind

WPF offers additional programming enhancements for Windows client application development. One obvious enhancement is the ability to develop an application using both markup and code-behind, an experience that ASP.NET developers should be familiar with. You generally use Extensible Application Markup Language (XAML) markup to implement the appearance of an application while using managed programming languages (code-behind) to implement its behavior. This separation of appearance and behavior has the following benefits:

  • Development and maintenance costs are reduced because appearance-specific markup is not tightly coupled with behavior-specific code.

  • Development is more efficient because designers can implement an application's appearance simultaneously with developers who are implementing the application's behavior.

  • Multiple design tools can be used to implement and share XAML markup, to target the requirements of the application development contributors; Microsoft Expression Blend provides an experience that suits designers, while Visual Studio 2005 targets developers.

  • Globalization and localization for WPF applications is greatly simplified (see WPF Globalization and Localization Overview).

The following is a brief introduction to WPF markup and code-behind. For more information on this programming model, see XAML Overview (WPF) and Code-Behind and XAML in WPF.

Markup

XAML is an XML-based markup language that is used to implement an application's appearance declaratively. It is typically used to create windows, dialog boxes, pages, and user controls, and to fill them with controls, shapes, and graphics.

The following example uses XAML to implement the appearance of a window that contains a single button.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    Title="Window with Button"
    Width="250" Height="100">

  <!-- Add button to window -->
  <Button Name="button">Click Me!</Button>

</Window>

Specifically, this XAML defines a window and a button by using the Window and Button elements, respectively. Each element is configured with attributes, such as the Window element's Title attribute to specify the window's title-bar text. At run time, WPF converts the elements and attributes that are defined in markup to instances of WPF classes. For example, the Window element is converted to an instance of the Window class whose Title property is the value of the Title attribute.

The following figure shows the user interface (UI) that is defined by the XAML in the previous example.

A window that contains a button

For more information, see XAML Overview (WPF).

Since XAML is XML-based, the UI that you compose with it is assembled in a hierarchy of nested elements known as an element tree. The element tree provides a logical and intuitive way to create and manage UIs. For more information, see Trees in WPF.

Code-Behind

The main behavior of an application is to implement the functionality that responds to user interactions, including handling events (for example, clicking a menu, tool bar, or button) and calling business logic and data access logic in response. In WPF, this behavior is generally implemented in code that is associated with markup. This type of code is known as code-behind. The following example shows the code-behind and updated markup from the previous example.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.AWindow"
    Title="Window with Button"
    Width="250" Height="100">

  <!-- Add button to window -->
  <Button Name="button" Click="button_Click">Click Me!</Button>

</Window>

Namespace SDKSample

    Partial Public Class AWindow
        Inherits System.Windows.Window

        Public Sub New()

            ' InitializeComponent call is required to merge the UI
            ' that is defined in markup with this class, including 
            ' setting properties and registering event handlers
            InitializeComponent()

        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)

            ' Show message box when button is clicked
            MessageBox.Show("Hello, Windows Presentation Foundation!")

        End Sub

    End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, MessageBox

namespace SDKSample
{
    public partial class AWindow : Window
    {
        public AWindow()
        {
            // InitializeComponent call is required to merge the UI
            // that is defined in markup with this class, including 
            // setting properties and registering event handlers
            InitializeComponent();
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            // Show message box when button is clicked
            MessageBox.Show("Hello, Windows Presentation Foundation!");
        }
    }
}

In this example, the code-behind implements a class that derives from the Window class. The x:Class attribute is used to associate the markup with the code-behind class. InitializeComponent is called from the code-behind class's constructor to merge the UI that is defined in markup with the code-behind class. (InitializeComponent is generated for you when your application is built, which is why you don't need to implement it manually.) The combination of x:Class and InitializeComponent ensure that your implementation is correctly initialized whenever it is created. The code-behind class also implements an event handler for the button's Click event. When the button is clicked, the event handler shows a message box by calling the MessageBox.Show method.

The following figure shows the result when the button is clicked.

A MessageBox

For more information, see Code-Behind and XAML in WPF.

Applications

.NET Framework, System.Windows, and markup and code-behind, constitute the foundation of the WPF application development experience. Additionally, WPF has comprehensive features for creating user experiences with rich content. To package this content and deliver it to users as "applications," WPF provides types and services that are collectively known as the application model. The application model supports the development of both standalone and browser-hosted applications.

Standalone Applications

For standalone applications, you can use the Window class to create windows and dialog boxes that are accessed from menu bars and tool bars. The following figure shows a standalone application with a main window and a dialog box.

A main window and a dialog box

Additionally, you can use the following WPF dialog boxes: MessageBox, OpenFileDialog, SaveFileDialog, and PrintDialog.

For more information, see WPF Windows Overview.

Browser-Hosted Applications

For browser-hosted applications, known as XAML browser applications (XBAPs), you can create pages (Page) and page functions (PageFunction<T>) that you can navigate between using hyperlinks (Hyperlink classes). The following figure shows a page in an XBAP that is hosted in Internet Explorer 7.

Two pages of a hosted application

WPF applications can be hosted in both Microsoft Internet Explorer 6 and Internet Explorer 7. WPF offers the two following options for alternative navigation hosts:

  • Frame, to host islands of navigable content in either pages or windows.

  • NavigationWindow, to host navigable content in an entire window.

For more information, see Navigation Overview.

The Application Class

Both XBAPs and standalone applications are often complex enough to require additional application-scoped services, including startup and lifetime management, shared properties, and shared resources. The Application class encapsulates these services and more, and it can be implemented by just using XAML, as shown in the following example.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    StartupUri="MainWindow.xaml" />

This markup is the application definition for a standalone application, and instructs WPF to create an Application object that automatically opens MainWindow when the application is started.

A key concept to understand about Application is that it provides a common platform of support for both standalone and browser-hosted applications. For example, the preceding XAML could be used by a browser-hosted application to automatically navigate to a page when an XBAP is started, as shown in the following example.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    StartupUri="HomePage.xaml" />

For more information, see Application Management Overview.

Security

Because XBAPs are hosted in a browser, security is important. In particular, a partial-trust security sandbox is used by XBAPs to enforce restrictions that are less than or equal to the restrictions imposed on HTML-based applications. Furthermore, each HTML feature that is safe to run from XBAPs in partial trust has been tested using a comprehensive security process, detailed in WPF Security Strategy - Security Engineering.

Still, a majority of WPF features can be safely executed from XBAPs, as described in WPF Partial Trust Security.

Controls

The user experiences that are delivered by the application model are constructed controls. In WPF, "control" is an umbrella term that applies to a category of WPF classes that are hosted in either a window or a page, have a user interface (UI), and implement some behavior.

For more information, see Controls.

WPF Controls by Function

The built-in WPF controls are listed here.

Input and Commanding

Controls most often detect and respond to user input. The WPF input system uses both direct and routed events to support text input, focus management, and mouse positioning. For more information, see Input Overview.

Applications often have complex input requirements. WPF provides a command system that separates user input actions from the code that responds to those actions. For more information, see Commanding Overview.

Layout

When you create a UI, you arrange your controls by location and size to form a layout. A key requirement of any layout is to adapt to changes in window size and display settings. Rather than forcing you to write the code to adapt a layout in these circumstances, WPF provides a first-class, extensible layout system for you.

The cornerstone of the layout system is relative positioning, which increases the ability to adapt to changing window and display conditions. In addition, the layout system manages the negotiation between controls to determine the layout. The negotiation is a two-step process: first, a control tells its parent what location and size it requires; second, the parent tells the control what space it can have.

The layout system is exposed to child controls through base WPF classes. For common layouts such as grids, stacking, and docking, WPF includes several layout controls:

  • Canvas: Child controls provide their own layout.

  • DockPanel: Child controls are aligned to the edges of the panel.

  • Grid: Child controls are positioned by rows and columns.

  • StackPanel: Child controls are stacked either vertically or horizontally.

  • VirtualizingStackPanel: Child controls are virtualized and arranged on a single line that is either horizontally or vertically oriented.

  • WrapPanel: Child controls are positioned in left-to-right order and wrapped to the next line when there are more controls on the current line than space allows.

The following example uses a DockPanel to lay out several TextBox controls.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.LayoutWindow"
    Title="Layout with the DockPanel" Height="143" Width="319">

  <!--DockPanel to layout four text boxes--> 
  <DockPanel>
    <TextBox DockPanel.Dock="Top">Dock = "Top"</TextBox>
    <TextBox DockPanel.Dock="Bottom">Dock = "Bottom"</TextBox>
    <TextBox DockPanel.Dock="Left">Dock = "Left"</TextBox>
    <TextBox Background="White">This TextBox "fills" the remaining space.</TextBox>
  </DockPanel>

</Window>

The DockPanel allows the child TextBox controls to tell it how to arrange them. To do this, the DockPanel implements a Dock property that is exposed to the child controls to allow each of them to specify a dock style.

Note

A property that is implemented by a parent control for use by child controls is a WPF construct called an attached property (see Attached Properties Overview).

The following figure shows the result of the XAML markup in the preceding example.

DockPanel page

For more information, see Layout System. For an introductory sample, see WPF Layout Gallery Sample.

Data Binding

Most applications are created to provide users with the means to view and edit data. For WPF applications, the work of storing and accessing data is already provided for by technologies such as Microsoft SQL Server and ADO.NET. After the data is accessed and loaded into an application's managed objects, the hard work for WPF applications begins. Essentially, this involves two things:

  1. Copying the data from the managed objects into controls, where the data can be displayed and edited.

  2. Ensuring that changes made to data by using controls are copied back to the managed objects.

To simplify application development, WPF provides a data binding engine to automatically perform these steps. The core unit of the data binding engine is the Binding class, whose job is to bind a control (the binding target) to a data object (the binding source). This relationship is illustrated by the following figure.

Basic data binding diagram

The following example demonstrates how to bind a TextBox to an instance of a custom Person object. The Person implementation is shown in the following code.

Namespace SDKSample

    Class Person

        Private _name As String = "No Name"

        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(ByVal value As String)
                _name = value
            End Set
        End Property

    End Class

End Namespace
namespace SDKSample
{
    class Person
    {
        string name = "No Name";

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
}

The following markup binds the TextBox to an instance of a custom Person object.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.DataBindingWindow">


...


<!-- Bind the TextBox to the data source (TextBox.Text to Person.Name) -->
<TextBox Name="personNameTextBox" Text="{Binding Path=Name}" />


...


</Window>
Imports System.Windows ' Window

Namespace SDKSample

    Partial Public Class DataBindingWindow
        Inherits Window

        Public Sub New()
            InitializeComponent()

            ' Create Person data source
            Dim person As Person = New Person()

            ' Make data source available for binding
            Me.DataContext = person

        End Sub

    End Class

End Namespace
using System.Windows; // Window

namespace SDKSample
{
    public partial class DataBindingWindow : Window
    {
        public DataBindingWindow()
        {
            InitializeComponent();

            // Create Person data source
            Person person = new Person();

            // Make data source available for binding
            this.DataContext = person;
        }
    }
}

In this example, the Person class is instantiated in code-behind and is set as the data context for the DataBindingWindow. In markup, the Text property of the TextBox is bound to the Person.Name property (using the "{Binding ... }" XAML syntax). This XAML tells WPF to bind the TextBox control to the Person object that is stored in the DataContext property of the window.

The WPF data binding engine provides additional support that includes validation, sorting, filtering, and grouping. Furthermore, data binding supports the use of data templates to create custom UI for bound data when the UI displayed by the standard WPF controls is not appropriate.

For more information, see Data Binding Overview. For an introductory sample, see Data Binding Demo.

Graphics

WPF introduces an extensive, scalable, and flexible set of graphics features that have the following benefits:

  • Resolution-independent and device-independent graphics. The basic unit of measurement in the WPF graphics system is the device independent pixel, which is 1/96th of an inch, regardless of actual screen resolution, and provides the foundation for resolution-independent and device-independent rendering. Each device-independent pixel automatically scales to match the dots-per-inch (dpi) setting of the system it renders on.

  • Improved precision. The WPF coordinate system is measured with double-precision floating-point numbers rather than single-precision. Transformations and opacity values are also expressed as double-precision. WPF also supports a wide color gamut (scRGB) and provides integrated support for managing inputs from different color spaces.

  • Advanced graphics and animation support. WPF simplifies graphics programming by managing animation scenes for you; there is no need to worry about scene processing, rendering loops, and bilinear interpolation. Additionally, WPF provides hit-testing support and full alpha-compositing support.

  • Hardware acceleration. The WPF graphics system takes advantage of graphics hardware to minimize CPU usage.

2-D Shapes

WPF provides a library of common vector-drawn 2-D shapes, such as the rectangles and ellipses that are shown in the following illustration.

Ellipses and rectangles

An interesting capability of shapes is that they are not just for display; shapes implement many of the features that you expect from controls, including keyboard and mouse input. The following example shows the MouseUp event of an Ellipse being handled.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.EllipseEventHandlingWindow"
    Title="Click the Ellipse">
    <Ellipse Name="clickableEllipse" Fill="Blue" MouseUp="clickableEllipse_MouseUp" />
</Window>
Imports System.Windows ' Window, MessageBox
Imports System.Windows.Input ' MouseButtonEventArgs

Namespace SDKSample

    Public Class EllipseEventHandlingWindow
        Inherits Window

        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub clickableEllipse_MouseUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
            MessageBox.Show("You clicked the ellipse!")
        End Sub

    End Class

End Namespace
using System.Windows; // Window, MessageBox
using System.Windows.Input; // MouseButtonEventHandler

namespace SDKSample
{
    public partial class EllipseEventHandlingWindow : Window
    {
        public EllipseEventHandlingWindow()
        {
            InitializeComponent();
        }

        void clickableEllipse_MouseUp(object sender, MouseButtonEventArgs e)
        {
            // Display a message
            MessageBox.Show("You clicked the ellipse!");
        }
    }
}

The following figure shows what is produced by the preceding code.

A window with the text "you clicked the ellipse!"

For more information, see Shapes and Basic Drawing in WPF Overview. For an introductory sample, see Shape Elements Sample.

2-D Geometries

The 2-D shapes provided by WPF cover the standard set of basic shapes. However, you may need to create custom shapes to facilitate the design of a customized UI. For this purpose, WPF provides geometries. The following figure demonstrates the use of geometries to create a custom shape that can be drawn directly, used as a brush, or used to clip other shapes and controls.

Path objects can be used to draw closed or open shapes, multiple shapes, and even curved shapes.

Geometry objects can be used for clipping, hit-testing, and rendering 2-D graphic data.

Various uses of a Path

For more information, see Geometry Overview. For an introductory sample, see Geometries Sample.

2-D Effects

A subset of WPF 2-D capabilities includes visual effects, such as gradients, bitmaps, drawings, painting with videos, rotation, scaling, and skewing. These are all achieved with brushes; the following figure shows some examples.

Illustration of different brushes

For more information, see WPF Brushes Overview. For an introductory sample, see Brushes Sample.

3-D Rendering

WPF also includes 3-D rendering capabilities that integrate with 2-D graphics to allow the creation of more exciting and interesting UIs. For example, the following figure shows 2-D images rendered onto 3-D shapes.

Visual3D sample screen shot

For more information, see 3-D Graphics Overview. For an introductory sample, see 3-D Solids Sample.

Animation

WPF animation support lets you make controls grow, shake, spin, and fade, to create interesting page transitions, and more. You can animate most WPF classes, even custom classes. The following figure shows a simple animation in action.

Images of an animated cube

For more information, see Animation Overview. For an introductory sample, see Animation Example Gallery.

Media

One way to convey rich content is through the use of audiovisual media. WPF provides special support for images, video, and audio.

Images

Images are common to most applications, and WPF provides several ways to use them. The following figure shows a UI with a list box that contains thumbnail images. When a thumbnail is selected, the image is shown full-size.

Thumbnail images and a full-size image

For more information, see Imaging Overview.

Video and Audio

The MediaElement control is capable of playing both video and audio, and it is flexible enough to be the basis for a custom media player. The following XAML markup implements a media player.

<MediaElement 
  Name="myMediaElement" 
  Source="media/wpf.wmv" 
  LoadedBehavior="Manual" 
  Width="350" Height="250" />

The window in the following figure shows the MediaElement control in action.

A MediaElement control with audio and video

For more information, see Graphics and Multimedia.

Text and Typography

To facilitate high-quality text rendering, WPF offers the following features:

  • OpenType font support.

  • ClearType enhancements.

  • High performance that takes advantage of hardware acceleration.

  • Integration of text with media, graphics, and animation.

  • International font support and fallback mechanisms.

As a demonstration of text integration with graphics, the following figure shows the application of text decorations.

Text with various text decorations

For more information, see Typography in WPF.

Documents

WPF has native support for working with three types of documents: flow documents, fixed documents, and XML Paper Specification (XPS) documents. WPF also provides the services to create, view, manage, annotate, package, and print documents.

Flow Documents

Flow documents are designed to optimize viewing and readability by dynamically adjusting and reflowing content when window size and display settings change. The following XAML markup shows the definition of a FlowDocument.

<FlowDocument xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">

  <Paragraph FontSize="18" FontWeight="Bold">Flow Document</Paragraph>

  <Paragraph>
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
    nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi
    enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
    nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
  </Paragraph>


...


</FlowDocument>

The following example demonstrates how to load a flow document into a FlowDocumentReader for viewing, searching, and printing.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.FlowDocumentReaderWindow"
    Title="Flow Document Reader">
  <FlowDocumentReader Name="flowDocumentReader" />
</Window>
Imports System.Windows 'Window
Imports System.Windows.Documents 'FlowDocument
Imports System.IO 'FileStream, FileMode
Imports System.Windows.Markup 'XamlReader

Namespace SDKSample

    Public Class FlowDocumentReaderWindow
        Inherits Window

        Public Sub New()
            Me.InitializeComponent()
            Using stream1 As FileStream = New FileStream("AFlowDocument.xaml", _
                FileMode.Open, FileAccess.Read)
                Dim document1 As FlowDocument = _
                    TryCast(XamlReader.Load(stream1), FlowDocument)
                Me.flowDocumentReader.Document = document1
            End Using
        End Sub

    End Class

End Namespace
using System.Windows; // Window
using System.Windows.Documents; // FlowDocument
using System.IO; // FileStream, FileMode
using System.Windows.Markup; // XamlReader

namespace SDKSample
{
    public partial class FlowDocumentReaderWindow : System.Windows.Window
    {
        public FlowDocumentReaderWindow()
        {
            InitializeComponent();

            // Open the file that contains the FlowDocument
            using (FileStream xamlFile = new FileStream("AFlowDocument.xaml", 
                FileMode.Open, FileAccess.Read))
            {
                // Parse the file with the XamlReader.Load method
                FlowDocument content = XamlReader.Load(xamlFile) as FlowDocument;

                // Set the Document property to the parsed FlowDocument object
                this.flowDocumentReader.Document = content;
            }
        }
    }
}

The following example shows the result.

A FlowDocument within a FlowDocumentReader control

For more information, see Flow Document Overview.

Fixed Documents

Fixed documents are intended for applications that require a precise "what you see is what you get" (WYSIWYG) presentation, particularly with respect to printing. Typical uses for fixed documents include desktop publishing, word processing, and form layout, where adherence to the original page design is critical.

Fixed documents maintain the precise arrangement of their content in a device-independent manner. For example, a fixed document that is displayed on a 96 dots-per-inch (dpi) display appears the same as when it is printed to either a 600 dpi laser printer or a 4800 dpi photo typesetter. The layout remains the same in all cases, although the document's quality varies depending on the capabilities of each device.

For more information, see Documents in WPF.

XPS Documents

XML Paper Specification (XPS) documents build on WPF's fixed documents. XPS documents are described with an XML-based schema that is essentially a paginated representation of electronic paper. XPS is an open, cross-platform document format that is designed to facilitate the creation, sharing, printing, and archiving of paginated documents. Important features of the XPS technology include the following:

  • Packaging of XPS documents as ZipPackage files that conform to the Open Packaging Conventions (OPC).

  • Hosting in both standalone and browser-based applications.

  • Manual generation and manipulation of XPS documents from WPF applications.

  • High-fidelity rendering by targeting maximum output device quality.

  • Windows Vista print spooling.

  • Direct routing of documents to XPS-compatible printers.

  • UI integration with DocumentViewer.

The following figure shows an XPS document that is displayed by a DocumentViewer.

An XPS document within a DocumentViewer control

DocumentViewer also allows users to change the view, search, and print XPS documents.

For more information, see Documents in WPF.

Annotations

Annotations are notes or comments that are added to documents to flag information or to highlight items of interest for later reference. Although writing notes on printed documents is easy, the ability to "write" notes on electronic documents is often limited or unavailable. In WPF, however, an annotations system is provided to support sticky notes and highlights. Additionally, these annotations can be applied to documents hosted in the DocumentViewer control, as shown in the following figure.

Annotation styling

For more information, see Annotations Overview.

Packaging

The WPF System.IO.Packaging APIs allow your applications to organize data, content, and resources into single, portable, easy-to-distribute, and easy-to-access ZIP documents. Digital signatures can be included to authenticate items that are contained in a package and to verify that the signed item was not tampered with or modified. You can also encrypt packages by using rights management in order to restrict access to protected information.

For more information, see Documents in WPF.

Printing

The .NET Framework includes a printing subsystem that WPF augments with support for enhanced print system control. Printing enhancements include the following:

  • Real-time installation of remote print servers and queues.

  • Dynamic discovery of printer capabilities.

  • Dynamic setting of printer options.

  • Print job rerouting and reprioritizing.

XPS documents also have a key performance enhancement. The existing Microsoft Windows Graphics Device Interface (GDI) print path typically requires two conversions:

  • The first conversion of a document into a print processor format, such as Enhanced Metafile (EMF).

  • A second conversion into the page description language of the printer, such as Printer Control Language (PCL) or PostScript.

However, XPS documents avoid these conversions because one component of the XPS file format is a print processor language and a page description language. This support helps to reduce both spool file size and networked printer loads.

For more information, see Printing Overview.

Customizing WPF Applications

Up to this point, you've seen the core WPF building blocks for developing applications. You use the application model to host and deliver application content, which consists mainly of controls. To simplify the arrangement of controls in a UI, and to ensure the arrangement is maintained in the face of changes to window size and display settings, you use the WPF layout system. Because most applications allow users to interact with data, you use data binding to reduce the work of integrating your UI with data. To enhance the visual appearance of your application, you use the comprehensive range of graphics, animation, and media support provided by WPF. Finally, if your application operates over text and documents, you can use the WPF text, typography, document, annotation, packaging, and printing capabilities.

Often, though, the basics are not enough for creating and managing a truly distinct and visually stunning user experience. The standard WPF controls may not integrate with the desired appearance of your application. Data may not be displayed in the most effective way. Your application's overall user experience may not be suited to the default look and feel of Windows themes. In many ways, a presentation technology needs visual extensibility as much as any other kind of extensibility.

For this reason, WPF provides a variety of mechanisms for creating unique user experiences, including a rich content model for controls, triggers, control and data templates, styles, UI resources, and themes and skins.

Content Model

The main purpose of a majority of the WPF controls is to display content. In WPF, the type and number of items that can constitute the content of a control is referred to as the control's content model. Some controls can contain a single item and type of content; for example, the content of a TextBox is a string value that is assigned to the Text property. The following example sets the content of a TextBox.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.TextBoxContentWindow"
    Title="TextBox Content">


...


<TextBox Text="This is the content of a TextBox." />


...


</Window>

The following figure shows the result.

A TextBox control that contains text

Other controls, however, can contain multiple items of different types of content; the content of a Button, specified by the Content property, can contain a variety of items including layout controls, text, images, and shapes. The following example shows a Button with content that includes a DockPanel, a Label, a Border, and a MediaElement.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.ButtonContentWindow"
    Title="Button Content">


...


<Button Margin="20">
  <!-- Button Content -->
  <DockPanel Width="200" Height="180">
    <Label DockPanel.Dock="Top" HorizontalAlignment="Center">Click Me!</Label>
    <Border Background="Black" BorderBrush="Yellow" BorderThickness="2" 
      CornerRadius="2" Margin="5">
      <MediaElement Source="media/wpf.wmv" Stretch="Fill" />
    </Border>
  </DockPanel>
</Button>


...


</Window>

The following figure shows the content of this button.

A button that contains multiple types of content

For more information on the kinds of content that is supported by various controls, see WPF Content Model.

Triggers

Although the main purpose of XAML markup is to implement an application's appearance, you can also use XAML to implement some aspects of an application's behavior. One example is the use of triggers to change an application's appearance based on user interactions. For more information, see "Triggers" in Styling and Templating.

Control Templates

The default UIs for WPF controls are typically constructed from other controls and shapes. For example, a Button is composed of both ButtonChrome and ContentPresenter controls. The ButtonChrome provides the standard button appearance, while the ContentPresenter displays the button's content, as specified by the Content property.

Sometimes the default appearance of a control may be incongruent with the overall appearance of an application. In this case, you can use a ControlTemplate to change the appearance of the control's UI without changing its content and behavior.

For example, the following example shows how to change the appearance of a Button by using a ControlTemplate.

<Window 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.ControlTemplateButtonWindow"
  Title="Button with Control Template" Height="158" Width="290">

  <!-- Button using an ellipse -->
  <Button Content="Click Me!" Click="button_Click">
    <Button.Template>
      <ControlTemplate TargetType="{x:Type Button}">
        <Grid Margin="5">
          <Ellipse Stroke="DarkBlue" StrokeThickness="2">
            <Ellipse.Fill>
              <RadialGradientBrush Center="0.3,0.2" RadiusX="0.5" RadiusY="0.5">
                <GradientStop Color="Azure" Offset="0.1" />
                <GradientStop Color="CornflowerBlue" Offset="1.1" />
              </RadialGradientBrush>
            </Ellipse.Fill>
          </Ellipse>
          <ContentPresenter Name="content" HorizontalAlignment="Center" 
            VerticalAlignment="Center"/>
        </Grid>
      </ControlTemplate>
    </Button.Template>

  </Button>

</Window>
Imports System.Windows ' Window, RoutedEventArgs, MessageBox

Namespace SDKSample

    Public Class ControlTemplateButtonWindow
        Inherits Window

        Public Sub New()

            InitializeComponent()

        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            MessageBox.Show("Hello, Windows Presentation Foundation!")
        End Sub

    End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, MessageBox

namespace SDKSample
{
    public partial class ControlTemplateButtonWindow : Window
    {
        public ControlTemplateButtonWindow()
        {
            InitializeComponent();
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            // Show message box when button is clicked
            MessageBox.Show("Hello, Windows Presentation Foundation!");
        }
    }
}

In this example, the default button UI has been replaced with an Ellipse that has a dark blue border and is filled using a RadialGradientBrush. The ContentPresenter control displays the content of the Button, "Click Me!" When the Button is clicked, the Click event is still raised as part of the Button control's default behavior. The result is shown in the following figure.

An elliptical button and a second window

For more information, see ControlTemplate. For an introductory sample, see Styling with ControlTemplates Sample.

Data Templates

Whereas a control template lets you specify the appearance of a control, a data template lets you specify the appearance of a control's content. Data templates are frequently used to enhance how bound data is displayed. The following figure shows the default appearance for a ListBox that is bound to a collection of Task objects, where each task has a name, description, and priority.

A list box with the default appearance

The default appearance is what you would expect from a ListBox. However, the default appearance of each task contains only the task name. To show the task name, description, and priority, the default appearance of the ListBox control's bound list items must be changed by using a DataTemplate. The following XAML defines such a DataTemplate, which is applied to each task by using the ItemTemplate attribute.

<Window
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.DataTemplateWindow"
  Title="With a Data Template">


...


<Window.Resources>
  <!-- Data Template (applied to each bound task item in the task collection) -->
  <DataTemplate x:Key="myTaskTemplate">
    <Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2" 
      CornerRadius="2" Padding="5" Margin="5">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Padding="0,0,5,0" Text="Task Name:"/>
        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=TaskName}"/>
        <TextBlock Grid.Row="1" Grid.Column="0" Padding="0,0,5,0" Text="Description:"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
        <TextBlock Grid.Row="2" Grid.Column="0" Padding="0,0,5,0" Text="Priority:"/>
        <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
      </Grid>
    </Border>  
  </DataTemplate>
</Window.Resources>


...


<!-- UI -->
<DockPanel>
  <!-- Title -->
  <Label DockPanel.Dock="Top" FontSize="18" Margin="5" Content="My Task List:"/>

  <!-- Data template is specified by the ItemTemplate attribute -->
  <ListBox 
    ItemsSource="{Binding}" 
    ItemTemplate="{StaticResource myTaskTemplate}" 
    HorizontalContentAlignment="Stretch" 
    IsSynchronizedWithCurrentItem="True" 
    Margin="5,0,5,5" />

</DockPanel>


...


</Window>

The following figure shows the effect of this code.

A list box that uses a data template

Note that the ListBox has retained its behavior and overall appearance; only the appearance of the content being displayed by the list box has changed.

For more information, see Data Templating Overview. For an introductory sample, see Introduction to Data Templating Sample.

Styles

Styles enable developers and designers to standardize on a particular appearance for their product. WPF provides a strong style model, the foundation of which is the Style element. The following example creates a style that sets the background color for every Button on a window to Orange.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.StyleWindow"
    Title="Styles">


...


<!-- Style that will be applied to all buttons -->
<Style TargetType="{x:Type Button}">
  <Setter Property="Background" Value="Orange" />
  <Setter Property="BorderBrush" Value="Crimson" />
  <Setter Property="FontSize" Value="20" />
  <Setter Property="FontWeight" Value="Bold" />
  <Setter Property="Margin" Value="5" />
</Style>


...


<!-- This button will have the style applied to it -->
<Button>Click Me!</Button>

<!-- This label will not have the style applied to it -->
<Label>Don't Click Me!</Label>

<!-- This button will have the style applied to it -->
<Button>Click Me!</Button>


...


</Window>

Because this style targets all Button controls, the style is automatically applied to all the buttons in the window, as shown in the following figure.

Two orange buttons

For more information, see Styling and Templating. For an introductory sample, see Introduction to Styling and Templating Sample.

Resources

Controls in an application should share the same appearance, which can include anything from fonts and background colors to control templates, data templates, and styles. You can use WPF's support for user interface (UI) resources to encapsulate these resources in a single location for reuse.

The following example defines a common background color that is shared by a Button and a Label.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.ResourcesWindow"
    Title="Resources Window">

  <!-- Define window-scoped background color resource -->
  <Window.Resources>
    <SolidColorBrush x:Key="defaultBackground" Color="Red" />
  </Window.Resources>


...


<!-- Button background is defined by window-scoped resource -->
<Button Background="{StaticResource defaultBackground}">One Button</Button>

<!-- Label background is defined by window-scoped resource -->
<Label Background="{StaticResource defaultBackground}">One Label</Label>


...


</Window>

This example implements a background color resource by using the Window.Resources property element. This resource is available to all children of the Window. There are a variety of resource scopes, including the following, listed in the order in which they are resolved:

  1. An individual control (using the inherited FrameworkElement.Resources property).

  2. A Window or a Page (also using the inherited FrameworkElement.Resources property).

  3. An Application (using the Application.Resources property).

The variety of scopes gives you flexibility with respect to the way in which you define and share your resources.

As an alternative to directly associating your resources with a particular scope, you can package one or more resources by using a separate ResourceDictionary that can be referenced in other parts of an application. For example, the following example defines a default background color in a resource dictionary.

<ResourceDictionary 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">

  <!-- Define background color resource -->
  <SolidColorBrush x:Key="defaultBackground" Color="Red" />

  <!-- Define other resources -->


...


</ResourceDictionary>

The following example references the resource dictionary defined in the previous example so that it is shared across an application.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App">

  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="BackgroundColorResources.xaml"/>
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>


...


</Application>

Resources and resource dictionaries are the foundation of WPF support for themes and skins.

For more information, see Resources Overview.

Themes and Skins

From a visual perspective, a theme defines the global appearance of Windows and the applications that run within it. Windows comes with several themes. For example, Microsoft Windows XP comes with both the Windows XP and Windows Classic themes, while Windows Vista comes with the Windows Vista and Windows Classic themes. The appearance that is defined by a theme defines the default appearance for a WPF application. WPF, however, does not integrate directly with Windows themes. Because the appearance of WPF is defined by templates, WPF includes one template for each of the well-known Windows themes, including Aero (Windows Vista), Classic (Microsoft Windows 2000), Luna (Microsoft Windows XP), and Royale (Microsoft Windows XP Media Center Edition 2005). These themes are packaged as resource dictionaries that are resolved if resources are not found in an application. Many applications rely on these themes to define their visual appearance; remaining consistent with Windows appearance helps users become familiar with more applications more easily.

On the other hand, the user experience for some applications does not necessarily come from the standard themes. For example, Microsoft Windows Media Player operates over audio and video data and benefits from a different style of user experience. Such UIs tend to provide customized, application-specific themes. These are known as skins, and applications that are skinned often provide hooks by which users can customize various aspects of the skin. Microsoft Windows Media Player has several prefabricated skins as well as a host of third-party skins.

Both themes and skins in WPF are most easily defined using resource dictionaries. The following example shows sample skin definitions.

<!-- Blue Skin -->
<ResourceDictionary
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample">
  <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Blue" />
  </Style>


...


</ResourceDictionary>
<!-- Yellow Skin -->
<ResourceDictionary
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample">
  <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Yellow" />
  </Style>


...


</ResourceDictionary>

For more information, see "Shared Resources and Themes" in Styling and Templating.

Custom Controls

Although WPF provides a host of customization support, you may encounter situations where existing WPF controls do not meet the needs of either your application or its users. This can occur when:

  • The UI that you require cannot be created by customizing the look and feel of existing WPF implementations.

  • The behavior that you require is not supported (or not easily supported) by existing WPF implementations.

At this point, however, you can take advantage of one of three WPF models to create a new control. Each model targets a specific scenario and requires your custom control to derive from a particular WPF base class. The three models are listed here:

  • User Control Model. A custom control derives from UserControl and is composed of one or more other controls.

  • Control Model. A custom control derives from Control and is used to build implementations that separate their behavior from their appearance using templates, much like the majority of WPF controls. Deriving from Control allows you more freedom for creating a custom UI than user controls, but it may require more effort.

  • Framework Element Model. A custom control derives from FrameworkElement when its appearance is defined by custom rendering logic (not templates).

The following example shows a custom numeric up/down control that derives from UserControl.

<UserControl
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.NumericUpDown">

  <Grid>

    <Grid.RowDefinitions>
      <RowDefinition/>
      <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <!-- Value text box -->
    <Border BorderThickness="1" BorderBrush="Gray" Margin="2" Grid.RowSpan="2" 
      VerticalAlignment="Center" HorizontalAlignment="Stretch">
      <TextBlock Name="valueText" Width="60" TextAlignment="Right" Padding="5"/>
    </Border>

    <!-- Up/Down buttons -->
    <RepeatButton Name="upButton" Click="upButton_Click" Grid.Column="1" 
      Grid.Row="0">Up</RepeatButton>
    <RepeatButton Name="downButton" Click="downButton_Click" Grid.Column="1" 
      Grid.Row="1">Down</RepeatButton>

  </Grid>

</UserControl>
imports System 'EventArgs
imports System.Windows 'DependencyObject, DependencyPropertyChangedEventArgs, 
                       ' FrameworkPropertyMetadata, PropertyChangedCallback, 
                       ' RoutedPropertyChangedEventArgs
imports System.Windows.Controls 'UserControl

Namespace SDKSample

    ' Interaction logic for NumericUpDown.xaml
    Partial Public Class NumericUpDown
        Inherits System.Windows.Controls.UserControl

        'NumericUpDown user control implementation


...



    End Class

End Namespace
using System; // EventArgs
using System.Windows; // DependencyObject, DependencyPropertyChangedEventArgs,
                      // FrameworkPropertyMetadata, PropertyChangedCallback, 
                      // RoutedPropertyChangedEventArgs
using System.Windows.Controls; // UserControl

namespace SDKSample
{
    public partial class NumericUpDown : UserControl
    {
        // NumericUpDown user control implementation


...


    }
}

The next example illustrates the XAML that is required to incorporate the user control into a Window.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.UserControlWindow"
    xmlns:local="clr-namespace:SDKSample" 
    Title="User Control Window">


...


<!-- Numeric Up/Down user control -->
<local:NumericUpDown />


...


</Window>

The following figure shows the NumericUpDown control hosted in a Window.

A custom UserControl

For more information on custom controls, see Control Authoring Overview.

WPF Best Practices

As with any development platform, WPF can be used in a variety of ways to achieve the desired result. As a way of ensuring that your WPF applications provide the required user experience and meet the demands of the audience in general, there are recommended best practices for accessibility, globalization and localization, and performance. See the following for more information:

Summary

WPF is a comprehensive presentation technology for building a wide variety of visually stunning client applications. This introduction has provided a look at the key features of WPF.

The next step is to build WPF applications!

As you build them, you can come back to this introduction for a refresher on the key features and to find references to more detailed coverage of the features covered in this introduction.

The following overviews and samples are mentioned in this introduction.

Overviews

Accessibility Best Practices

Application Management Overview

Commanding Overview

Controls

Data Binding Overview

Dependency Properties Overview

Documents in WPF

Input Overview

Layout System

Navigation Overview

Printing Overview

Resources Overview

Routed Events Overview

Styling and Templating

Typography in WPF

Security (WPF)

WPF Windows Overview

WPF Content Model

WPF Globalization and Localization Overview

Graphics and Multimedia

Samples

3-D Solids Sample

Animation Example Gallery

Brushes Sample

Data Binding Demo

Geometries Sample

Introduction to Data Templating Sample

Introduction to Styling and Templating Sample

Shape Elements Sample

Styling with ControlTemplates Sample

WPF Layout Gallery Sample

See Also

Concepts

Walkthrough: Getting Started with WPF

WPF Community Feedback