wpf deep dive

120
WPF Deep Dive Aniruddha Chakrabarti Sr. Solution Architect “If I have six hours to chop down a tree, I will use four hours to sharpen the axe” – Abraham Lincoln

Upload: aniruddha-chakrabarti

Post on 27-Jun-2015

1.145 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: WPF Deep Dive

WPF Deep Dive

Aniruddha ChakrabartiSr. Solution Architect

“If I have six hours to chop down a tree, I will use four hours to sharpen the axe” – Abraham Lincoln

Page 2: WPF Deep Dive

Key benefits of WPF• Broad integration

– Provides access to normal 2D graphics, controls, 3D, video, speech and rich document viewing with consistent programming model as well as tight integration

• Hardware acceleration• Improved Visual Rendering

– Retained mode graphics– Vector graphics– Resolution independence (Device Independent Graphics)

• Declarative programming (aka XAML)• Rich composition, layout and customization• Easy deployment• Incorporates best of Web and Windows• Integrate developers and designers

Page 3: WPF Deep Dive

WPF Architecture

Page 4: WPF Deep Dive

WPF Architecture

Page 5: WPF Deep Dive

WPF: Assemblies and Namespaces• Primary Assemblies containing the

WPF API– PresentationFramework– PresentationCore– WindowsBase– milcore (unmanaged)

• mil: Media Integration Layer• Namespaces

– System.Windows– Other child namespaces starting with

System.Windows except System.Windows.Forms (Win Forms)• System.Windows.Controls• System.Windows.Data• System.Windows.Documents• System.Windows.Media (+ child

namespaces)• System.Windows.Shapes

Unmanaged/Native

Managed

Page 6: WPF Deep Dive

WPF Base Class Hierarchy

PresentationFramework

PresentationCore

WindowsBase

Page 7: WPF Deep Dive

WPF Base Class Details• System.Threading.DispatcherObject:

– Provides basic constructs for dealing with concurrency and threading. WPF is based on a messaging system implemented by the dispatcher - works much like familiar Win32 message pump

• System.Windows.DependencyObject:– Provides reach Property System (DP + attached property)

• System.Windows.Media.Visual:– Provides for building a tree of visual objects. Visual is designed to be extremely

lightweight and flexible, so most of the features have no public API exposure.– Visual is really the entry point to the WPF composition system. Visual is the point of

connection between these two subsystems, the managed API and the unmanaged milcore.

• System.Windows.UIElement:– defines core subsystems including Layout, Input, and Events

• System.Windows.FrameworkElement:– Provides Advanced Layout on top of the features provided by UIElement– Provides DataBinding & Styles

• System.Windows.Controls.Control:– Provides Templating Support

Page 8: WPF Deep Dive

Different type of WPF applications

• Standalone/Desktop Applications– Window class is used to create windows and dialog boxes

• Browser Hosted Applications / XAML Browser Applications (XBAP)– Create Page, Page Function

• Loose XAML pages (can be opened in IE)

Page 9: WPF Deep Dive

XAML (eXtensible Application Markup Language)

Page 10: WPF Deep Dive

XAML Overview• Simple general-purpose, XML based declarative programming

language for constructing & initializing .NET objects• .NET Framework 3.0 includes

– A compiler and run-time parser for XAML, – Plug-in that enables to view standalone WPF-based XAML files

(sometimes called loose XAML pages) inside IE.

• Can be used independent of WPF (e.g. WF)• XAML Spec defines rules that map .NET namespaces, types,

properties, and events into XML namespaces, elements, and attributes.– Declaring an XML element in XAML (known as an object element) is

equivalent to instantiating the corresponding .NET object (always via a default constructor).

– Setting an attribute on the object element is equivalent to setting a property of the same name (called a property attribute)

Page 11: WPF Deep Dive

XAML Example

<Window x:Class="WpfApplication1.Window1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="First XAML Example" Height="300" Width="300"><StackPanel>

<Button Height="70" FontFamily="Verdana" FontSize="18">Hello World</Button>

</StackPanel></Window>

namespace WpfApplication1{ public partial class Window1 :

Window { public Window1() { InitializeComponent(); } }}

Window1.xamlWindow1.xaml.cs

Button btn = new Button();btn.Height = 70;btn.FontFamily = new FontFamily("Verdana");btn.FontSize = 18;btn.Content = "Hello World";

panel.Children.Add(btn);

Page 12: WPF Deep Dive

Loose XAML files

<Button xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Height="50" Width="250" FontSize="16"> Hello from loose XAML page </Button>

Page 13: WPF Deep Dive

XAML Namespace

• XAML Namespace– Default Namespace: declared with xmlns attribute

• Xmlns: http://schemas.microsoft.com/winfx/2006/xaml/presentation - maps to .NET namespace System.Windows.Controls.

• Mapping defined in PresentationFramework.dll assembly [assembly:XmlnsDefinition (“http://schemas.microsoft.com/winfx/2006/xaml/presentation”, “System.Windows.Controls”)]

– Root object element in a XAML file must specify at least one XML namespace: used to qualify itself & any child elements.

– Additional XML namespaces (on the root or on children) can be declared , but each one must be given a distinct prefix to be used on any identifiers from that namespace.• e.g. WPF XAML files typically use a second namespace with the prefix x (denoted by

using xmlns:x instead of just xmlns): xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml (XAML Language namespace) – System.Windows.Markup

<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:w="clr-namespace:WpfApplication1"

Page 14: WPF Deep Dive

XML Properties and Attributes<Button>Hello World <Button.FontSize>16</Button.FontSize></Button>

Property Element Syntax

<Button FontSize="16">Hello World </Button>

Attribute Syntax

<Button Width="120">Hello World</Button> <Button Width="1.2in">Hello World</Button> <Button Width="1.2 IN">Hello World</Button> <Button Width="2.8cm">Hello World</Button> <Button Width="70pt">Hello World</Button> <Button Width="15e-1in">Hello World</Button> <Button Width="NaN">Hello World</Button>

Page 15: WPF Deep Dive

XamlReader Class• XamlReader class exposes some

functionality of XAML Parser– Defined in namespace

System.Windows.Markup– Load & Parse method allows to parse

XAML and convert it into initialized object

Page 16: WPF Deep Dive

Application and Window class

Page 17: WPF Deep Dive

Application class

• Application object is responsible for– Managing the lifetime of the application– Tracking the visible windows– Dispensing resources– Managing the global state of the application

• Provides Run() method to start an app• Most WPF apps create a subclass of Application

– Run() method starts the dispatcher which sends the messages & events.

• WPF requires the UI thread to be STA because many components that WPF uses (e.g. Clipboard) require STA– The [STAThread] marker on the entry-point function is

required like Win Forms and User32

Page 18: WPF Deep Dive

First WPF Appusing System;using System.Windows;namespace ConsoleApplication1{ class Program { [STAThread] static void Main(string[] args) { Window mainWin = new Window(); mainWin.Title = "First WPF App"; Application app = new

Application(); app.Run(mainWin); } }}

Page 19: WPF Deep Dive

Using VS2008 WPF Template

Page 20: WPF Deep Dive

Important Members of Application• Property

– Current (static) – refers to current App– MainWindow – points to application’s Main window– Windows – collection of windows of app– StartupUri – Uri of resource to be started if Run is called

without parameter– ShutdownMode

• Method– Run – starts the app– Shutdown – ends the app

• Events– Startup & Exit– Activated & Deactivated– DispatcherUnhandledException

Page 21: WPF Deep Dive

Window• WPF Window provides abstraction for Win32 Window

– OS does not distinguish between windows with WPF content and normal Win32 content.

• Similar to Form in Win Forms• Represented by System.Windows.Window class• Order of Window events

1. Constructor is called.2. Window.Initialized event is raised.3. Window.Activated event is raised.13

4. Window.Loaded event is raised.5. Window.ContentRendered event is raised.6. User interacts with the window.7. Window.Closing event is raised.8. Window.Unloaded event is raised.9. Window.Closed event is raised.

Page 22: WPF Deep Dive

Navigation Window• Provides navigation in Windows app (like

navigation from one page to another in web Apps)

• Built with three basic concepts – – Navigation Hosts: hosts the content like Browser– Navigable Content: Page– Journal: responsible for tracking the navigation

actions<Label>This is page 1</Label><TextBlock>

<Hyperlink NavigateUri="Page2.xaml">Go to Page2 </Hyperlink></TextBlock>

Page 23: WPF Deep Dive

Controls

Page 24: WPF Deep Dive

Controls• Provides standard set of controls like Button, TextBox, CheckBox,

ComboBox, RadioButton etc.• Provides Content property instead of familiar Win32 Text property. Content

can be any object, not only string.– Content actually supports both string and UIElement– For other datatypes, it uses the string value returned by ToString().

• Most WPF controls ship with several default appearances– Aero (default Windows Vista theme)– Luna (default Windows XP theme)– Royale (Media Center & Tablet PC theme)– Classic (Win 9x theme)

• Provides different type of controls– Content Controls

• Buttons• Simple Containers• Containers with a Header

– Items Controls – Range Controls– Text and Ink Controls

Page 25: WPF Deep Dive

Buttons• Provides Content property -

derived from ContentControl base class

• Content property is of type object (not text), so any content is allowed, not only text.

• Provides rich composition

Page 26: WPF Deep Dive

Simple Containers• Label – Can be assigned an Access Key, which can be used to set

the cursor to the next TextBox.• ToolTip – provides rich tooltip like Office 2007• Frame – Can contain HTML content

Page 27: WPF Deep Dive

Containers with Header• GroupBox – Groups other controls. Has Header property.• Expander – New control in WPF. Does not exist in Win32/

WinForms.– Contains a button that enables you to expand and collapse the

inner content. – By default, the Expander starts out collapsed.

Page 28: WPF Deep Dive

Items Control• ComboBox• ListBox• ListView• TabControl

Page 29: WPF Deep Dive

Customizing ComboBox

IsEditable=”False” (default)

IsEditable=”True”

TextSearch.Text property set

Page 30: WPF Deep Dive

Range Control• ProgressBar• Slider

Page 31: WPF Deep Dive

Text and Ink Control• TextBox• RichTextBox– Can Contain Rich

formatted text & images

• PasswordBox• InkCanvas

Page 32: WPF Deep Dive

Other• Menu, MenuItem• ContextMenu• ToolBar• StatusBar

• WPF does not provide these control• Grid• Calendar

Page 33: WPF Deep Dive

Sizing, Positioning and Transform

Page 34: WPF Deep Dive

Sizing• Layout and size depends on the negotiation between

Parent and Child control• Input

– Height & Width property (from FrameworkElement)– Avoid Explicit Sizing

• use MinHeight, MinWidth, MaxHeight & MaxWidth

• Output– ActualHeight, ActualWidth (read only)– DesiredSize, RenderSize (UIElement)

• Default unit of measurement in WPF is Device Independent Pixel / Logical Pixel– NOT in Pixel (as in WinForms) as it’s resolution dependant. – 1 Logical Pixel = 1/96th of an inch (regardless of the DPI setting)

Page 35: WPF Deep Dive

Unit Example<StackPanel> <Button Width="120">Button 1</Button> // Device Independent Pixel

<Button Width="96">Button 2</Button> // Device Independent Pixel

<Button Width="1.2in">Button 3</Button> // Inches

<Button Width="1.2 IN">Button 4</Button> // Inches

<Button Width="5cm">Button 5</Button> // Centimeter

<Button Width="5 Cm">Button 6</Button> // Centimeter

<Button Width="NaN">Button 7</Button> // Not a Number

<Button Width="70pt">Button 8</Button> // Point

<Button Width="15e-1in">Button 9</Button> // Scientific</StackPanel>

• Is XAML Parser using double.Parse method behind?– No as it can parse NaN & Infinity but NOT in, cm, pt strings

• It’s using DoubleConverter class from System.ComponentModel

Page 36: WPF Deep Dive

Margin (Thickness) Example<StackPanel Margin="10" Background="LightBlue"> <Button Margin="10">Hello World</Button> <Button Margin="10 20">Hello World</Button></StackPanel>

• XAML Parser uses ThicknessConverter class from System.Windows namespace.

<StackPanel Margin="10" Background="LightBlue"> <Button Margin="10">Hello World</Button> <Button Margin="10 20 30 40">Hello World</Button></StackPanel>

Page 37: WPF Deep Dive

Converter Example• System.ComponentModel namespace provides a base class called

TypeConverter. • All Converter classes ultimately derives from TypeConverter.

.NET FrameworkTypeConverter Supported in: 3.5, 3.0 SP1, 3.0, 2.0 SP1, 2.0, 1.1, 1.0

Page 38: WPF Deep Dive

Margin, Padding and Visisbility• Margin - Controls how much extra space gets placed around the

outside edges of the element• Padding - Controls how much extra space gets placed around the

inside edges of the element• Visibility – NOT boolean, rather a three-state

System.Windows.Visibility enumeration– Visible: The element gets rendered and participates in layout.– Collapsed: The element is invisible and does not participate in layout.– Hidden: The element is invisible yet still participates in layout.

<StackPanel Background="LightBlue" Margin="40,30,20,10"> <Button Margin="50" Padding="20">Hello World</Button></StackPanel>

Page 39: WPF Deep Dive

Position• Alignment– HorizontalAlignment : Left, Center, Right, Stretch (default)– VerticalAlignment: Top, Center, Bottom, Stretch (default)

<StackPanel> <Button HorizontalAlignment="Left">Left Button</Button> <Button HorizontalAlignment="Center">Center Button</Button> <Button HorizontalAlignment="Right">Right Button</Button> <Button HorizontalAlignment="Stretch">Stretch Button</Button></StackPanel>

Page 40: WPF Deep Dive

Position (cont’d)• Content Alignment: Determines how a control’s

content fills the space within the control– HorizontalContentAlignment : Left, Center, Right, Stretch– VerticalContentAlignment: Top, Center, Bottom, Stretch

<StackPanel> <Button HorizontalAlignment="Left">Left Button</Button> <Button HorizontalAlignment="Center">Center Button</Button> <Button HorizontalAlignment="Right">Right Button</Button> <Button HorizontalAlignment="Stretch" MinHeight="60" HorizontalContentAlignment="Right"VerticalContentAlignment="Bottom">Stretch Button</Button></StackPanel>

Page 41: WPF Deep Dive

How all properties come together

• HorizonalAlignment and VerticalAlignment• Margin and Padding• Height and Width• Transform

Page 42: WPF Deep Dive

Layout with Panels

Page 43: WPF Deep Dive

Panels• All panels derive from abstract Panel class.• Panel allows adding multiple child controls (UIElement) via Children

property.• Different type of panels -

– StackPanel– WrapPanel– DockPanel– Grid and UniformGrid– Canvas

Page 44: WPF Deep Dive

Stack Panel• Stacks its children (controls) sequentially• Stacks either horizontally or vertically depending on

Orientation property

<StackPanel> <Button>Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button></StackPanel>

<StackPanel Orientation="Horizontal"> <Button>Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button></StackPanel>

Page 45: WPF Deep Dive

Wrap Panel• Wraps its children (controls) to additional rows or

columns when there’s not enough space• ItemHeight, ItemWidth – uniform height & width can

be set for all children (controls)<WrapPanel Orientation="Horizontal"> <Button MinWidth="150">Button 1</Button> <Button MinWidth="120">Button 2</Button> <Button MinWidth="100">Button 3</Button> <Button MinWidth="80">Button 4</Button> <Button MinWidth="170">Button 5</Button> <Button MinWidth="40">Button 6</Button></WrapPanel>

Page 46: WPF Deep Dive

Dock Panel• Wraps its children (controls) to additional rows or

columns when there’s not enough space<DockPanel> <Button DockPanel.Dock="Top">Button 1</Button> <Button DockPanel.Dock="Left">Button 2</Button> <Button DockPanel.Dock="Bottom">Button 3</Button> <Button DockPanel.Dock="Right">Button 4</Button> <Button>Center Button</Button></DockPanel>

Page 47: WPF Deep Dive

Grid• Provides tabular layout (rows & columns) of controls• Most versatile Panel & most used• Default Layout used by Visual Studio & Expression• Similar to working with Table in HTML

<Grid ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition Height="40" /> <RowDefinition Height="40" /> <RowDefinition Height="40" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <Label Margin="7">First Name:</Label> <TextBox Grid.Column="1" Margin="7"></TextBox> <Label Margin="7" Grid.Row="1">Middle Name:</Label> <TextBox Grid.Row="1" Grid.Column="1" Margin="7"></TextBox> <Label Margin="7" Grid.Row="2">Last Name:</Label> <TextBox Grid.Row="2" Grid.Column="1" Margin="7"></TextBox></Grid>

Page 48: WPF Deep Dive

UniformGrid• Special type of Grid• Provides same height & width to all children

(controls)

<UniformGrid> <Button>Button 1</Button> <Button>Button 2</Button> <Button>Button 3</Button> <Button>Button 4</Button> <Button>Button 5</Button> <Button>Button 6</Button></UniformGrid>

Page 49: WPF Deep Dive

Canvas• Most basic Panel• Provides absolute positioning using Left, Top, Bottom

& Right with explicit coordinates• Should not be used if possible<Canvas Background="LightBlue" > <Label Canvas.Left="10">First Name:</Label> <TextBox Canvas.Left="100" MinWidth="150"></TextBox> <Label Canvas.Left="20" Canvas.Top="50">Middle Name:</Label> <TextBox Canvas.Left="120" Canvas.Top="50" MinWidth="150"></TextBox> <Label Canvas.Left="10" Canvas.Top="140">Last Name:</Label> <TextBox Canvas.Left="80" Canvas.Top="140" MinWidth="180"></TextBox></Canvas>

Page 50: WPF Deep Dive

Controlling Scrolling: ScrollViewer• ScrollViewer: provides Scrolling capability with scroll

bar<ScrollViewer> <StackPanel> <Button MinHeight="50">Button 1</Button> <Button MinHeight="60">Button 2</Button> <Button MinHeight="90">Button 3</Button> <Button MinHeight="50">Button 4</Button> <Button MinHeight="120">Button 5</Button> <Button MinHeight="50">Button 6</Button> </StackPanel></ScrollViewer>

Page 51: WPF Deep Dive

ViewBox• ViewBox: Scales Content to fit the window<Viewbox> <StackPanel> <Label>Patient Detail:</Label> <StackPanel Orientation="Horizontal"> <Label Foreground="Gray">Name:</Label> <Label>John W Smith</Label> </StackPanel> <StackPanel Orientation="Horizontal"> <Label Foreground="Gray">Sex:</Label> <Label>Male</Label> </StackPanel> <StackPanel Orientation="Horizontal"> <Label Foreground="Gray">Age:</Label> <Label>30 yrs</Label> </StackPanel> <Label Foreground="Gray">Address:</Label> <Label>2A Market Avenue, Minneapolis, MN, USA</Label> </StackPanel> </Viewbox>

Page 52: WPF Deep Dive

Resources and Styles

Page 53: WPF Deep Dive

Resource• Different from traditional .NET Resources which are binary

resources (strings, images, icons etc)• WPF Resources are Logical Resources.• A Resource can be anything that should be reused• Resources are stored in an object of type

ResourceDisctionary.– Each resource in resource dictionary must have unique key

• Three fundamental classes (FrameworkElement, FrameworkContentElement and Application) define a property named Resource of type ResourceDisctionary.

• Any element derived from FrameworkElement (such as panels, controls) can have a Resource collection.

Page 54: WPF Deep Dive

Resource Example<Window.Resources> <SolidColorBrush x:Key="ButtonBackground">LightBlue</SolidColorBrush> <s:Double x:Key="ButtonFontSize">17.5</s:Double></Window.Resources><StackPanel> <Button Background="{StaticResource ButtonBackground}" FontSize="{StaticResource ButtonFontSize}">Button 1</Button> <Button Background="{StaticResource ButtonBackground}">Button 2</Button> <Button FontSize="{StaticResource ButtonFontSize}">Button 3</Button>

<Button>Button 4 <Button.FontSize> <StaticResource ResourceKey="ButtonFontSize" /> </Button.FontSize> <Button.Background> <StaticResource ResourceKey="ButtonBackground" /> </Button.Background>

</Button></StackPanel>

Property Element syntax

Attribute syntax

Resource Key

Page 55: WPF Deep Dive

Resource (Cont’d)• Resources can be used in two ways– Through Markup Extension (via {})

• Static Resource Markup Extension• Dynamic Resource Markup Extension

– Through Property Element Syntax

• Helps in consistency & reusability• Can be stored at different level (like individual

control, panels, window or application level)• The markup extension class implements the ability to

walk the logical tree to find the item. 1. Element hierarchy2. Application.Resources3. Type theme4. System theme

Page 56: WPF Deep Dive

Application Resources<Application.Resources> <s:Double x:Key="bigFontSize">20</s:Double> <SolidColorBrush x:Key="buttonBg">LightBlue</SolidColorBrush></Application.Resources>

App.xaml

<StackPanel> <Button FontSize="{StaticResource bigFontSize}" Background="{StaticResource buttonBg}">Hello World </Button></StackPanel>

Window1.xaml

<Window.Resources> <SolidColorBrush x:Key="buttonBg"> LightGreen</SolidColorBrush></Window.Resources><StackPanel> <Button FontSize="{StaticResource bigFontSize}"

Background="{StaticResource buttonBg}">Hello World </Button></StackPanel>

Window2.xaml

Page 57: WPF Deep Dive

Markup Extension Example<Button Content="{Hello}"></Button> Error: WPF expects markup Extension

<Button Content="{}{Hello}"></Button> OK – Displays {Hello}, Escape Character

<StackPanel> <Label Foreground="Green">Machine Name:</Label> <Label Content="{x:Static s:Environment.MachineName}"></Label> <Label Foreground="Green">OS version:</Label> <Label Content="{x:Static s:Environment.OSVersion}"></Label> <Label Foreground="Green">Version:</Label> <Label Content="{x:Static s:Environment.Version}"></Label> <Label Foreground="Green">User Name:</Label> <Label Content="{x:Static s:Environment.UserName}"></Label> <Label Foreground="Green">User Domain Name:</Label> <Label Content="{x:Static s:Environment.UserDomainName}"></Label> <Label Foreground="Green">System Directory:</Label> <Label Content="{x:Static s:Environment.SystemDirectory}"></Label> <Label Foreground="Green">Current Directory:</Label> <Label Content="{x:Static s:Environment.CurrentDirectory}"></Label></StackPanel>

Page 58: WPF Deep Dive

Static vs. Dynamic Resource• WPF provides two ways to access a logical resource:– Statically with StaticResource, meaning the resource is

applied only once (the first time it’s needed)– Dynamically with DynamicResource, meaning the resource

is reapplied every time it changes

Page 59: WPF Deep Dive

System Resource• WPF provides out of the box System Resources:

– System settings encapsulated by static fields on three classes in the System.Windows namespace: SystemColors, SystemFonts, and SystemParameters

<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="System Resources Demo" Height="300" Width="300" Background="{x:Static SystemColors.ActiveCaptionBrush}"> <StackPanel> <Label FontFamily="{x:Static SystemFonts.MessageFontFamily}">User:</Label> <TextBox>Aniruddha</TextBox> </StackPanel></Window>

Page 60: WPF Deep Dive

Style• Simple mechanism for separating property

values from user interface elements. • Conceptually similar to using CSS in HTML.• Consists of Property Setters.• Named Styles are the simplest.

<Window.Resources> <Style x:Key="SpecialButton"> <Setter Property="Button.Background" Value="LightSlateGray"></Setter> <Setter Property="Button.FontSize" Value="20.5"></Setter> <Setter Property="Button.Foreground" Value="DarkBlue"></Setter> <Setter Property="Button.FontFamily" Value="Verdana"></Setter> </Style></Window.Resources><StackPanel> <Button Style="{StaticResource SpecialButton}">Special Button</Button></StackPanel>

Page 61: WPF Deep Dive

Style Inheritance• Styles can be inherited: BasedOn property in Style

<Window.Resources> <Style x:Key="SpecialButton"> <Setter Property="Button.Background" Value="LightSlateGray"></Setter> <Setter Property="Button.FontSize" Value="20.5"></Setter> <Setter Property="Button.Foreground" Value="DarkBlue"></Setter> <Setter Property="Button.FontFamily" Value="Verdana"></Setter> </Style> <Style x:Key="VerySpecialButton" BasedOn="{StaticResource SpecialButton}"> <Setter Property="Button.FontSize" Value="26.5"></Setter> <Setter Property="Button.FontStyle" Value="Italic"></Setter> <Setter Property="Button.Foreground" Value="White"></Setter> </Style></Window.Resources><StackPanel> <Button Style="{StaticResource SpecialButton}">Special Button</Button> <Button Name="btn2" Style="{StaticResource VerySpecialButton}">Very Special Button</Button></StackPanel>

Page 62: WPF Deep Dive

Restricting use of Style• Usage of Styles can be restricted through TargetType property.• TargetType can be set to a specific type of controls like Button,

Checkbox etc so that the Style is applied to those controls only.

<Window.Resources> <Style x:Key="SpecialButton" TargetType="{x:Type Button}"> <Setter Property="Control.Background" Value="LightSlateGray"></Setter> <Setter Property="Control.FontSize" Value="18.5"></Setter> <Setter Property="Control.Foreground" Value="DarkBlue"></Setter> <Setter Property="Control.FontFamily" Value="Verdana"></Setter> </Style> </Window.Resources> <StackPanel> <Button Style="{StaticResource SpecialButton}">Special Button</Button> <CheckBox Style="{StaticResource SpecialButton}">Special Checkbox</CheckBox></StackPanel>

Page 63: WPF Deep Dive

Trigger• Style applies its values unconditionally, but a trigger

performs its work based on one or more conditions• Three types of Triggers

– Property triggers: Invoked when the value of a dependency property changes

– Data triggers: Invoked when the value of a plain .NET property changes

– Event triggers: Invoked when a routed event is raised

• FrameworkElement, Style, DataTemplate & ControlTemplate all have a Triggers collection, but whereas Style and the template classes accept all three types, FrameworkElement only accepts event triggers.– This is simply because WPF development team didn’t have

enough time to implement the support for version 3.0

Page 64: WPF Deep Dive

Trigger Class Diagram

Page 65: WPF Deep Dive

Property Trigger• Executes a collection of Setters when a specified property has a specified value. • When the property no longer has this value, the property trigger “undoes” the Setters.

<Window.Resources> <Style x:Key="magicButton" TargetType="Button"> <Setter Property="FontSize" Value="18"></Setter> <Setter Property="Foreground" Value="Green"></Setter> <Setter Property="Background" Value="LightBlue"></Setter> <Setter Property="FontStyle" Value="Italic"></Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="26"></Setter> <Setter Property="Foreground" Value="Red"></Setter> <Setter Property="Background" Value="Yellow"></Setter> <Setter Property="FontWeight" Value="Bold"></Setter> </Trigger> </Style.Triggers> </Style></Window.Resources><StackPanel> <Button Style="{StaticResource magicButton}">Button 1</Button> <Button Style="{StaticResource magicButton}">Button 2</Button></StackPanel>

Page 66: WPF Deep Dive

Data Trigger• Data triggers are just like property triggers, except that they can be triggered by any .NET

property rather than just dependency properties.

<StackPanel Margin="10"> <StackPanel.Resources> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="disabled"> <Setter Property="IsEnabled" Value="False"/> </DataTrigger> </Style.Triggers> <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Text}"/> </Style> </StackPanel.Resources> <TextBox Margin="3"/> <TextBox Margin="3"/> <TextBox Margin="3"/> <TextBox Margin="3"/></StackPanel>

Page 67: WPF Deep Dive

MultiTrigger• To express a logical AND relationship a variation of Trigger called MultiTrigger or a variation

of DataTrigger called MultiDataTrigger is used• MultiTrigger and MultiDataTrigger have a collection of Conditions that contain information

that goes directly inside a Trigger or DataTrigger.

Page 68: WPF Deep Dive

2D GraphicsPen, Color, Brush BitmapEffect & Transform

Page 69: WPF Deep Dive

Graphics Overview• Provides a new rendering and composition model –– Enables to use advanced display techniques – Takes advantage of the capabilities of modern graphics cards– Retained-mode Graphics– High Quality Rendering– Painter’s Algorithm

• Retained-mode Graphics – no repainting• All Shapes (Rectangle, Ellipse) are Vector based.– Vector images do not get distorted when they are enlarged.– Vector graphics formats work by specifying the primitive

shapes that make up the picture, and describing their positions using coordinates (or "vectors").

Page 70: WPF Deep Dive

Retained-mode Graphics• GDI/GDI+ app must respond to "invalidation" events to repaint parts of the image

damaged by previously overlapping images. • This is because GDI's graphics model is primarily a "pixel painter"—once a primitive

like ellipse is rendered, GDI "forgets" the primitive. • The application must retain the state (geometry, formatting attributes, etc.) of all

these graphic objects in order to repaint.• GDI programmers never have to worry about maintaining the images of user-

interface controls because controls are retained-mode graphics—they are objects stored in the underlying graphics system

• The burden of maintaining the image of the control is borne by the graphics platform itself, not by the app.

• Retained-mode graphics is not new to GDI/Win32. In WPF ALL graphic objects are retained. In addition to the UI controls and media primitives, 2-D Shape primitives (rectangles, ellipses, paths, etc.) and 3-D modeling primitives are retained objects.

Paint (WM_PAINT) Not handled

Page 71: WPF Deep Dive

High Quality Rendering• Higher-quality typography: via built-in support for subpixel ClearType and

OpenType (including advanced features like contextual ligatures) used for all text, including text in UI controls

• Resolution independence: Device Independent Pixel • Anti-aliasing, eliminating the "jagged" edges of the rendering of diagonal or

curved lines • Higher performance in drawing and refreshing, due to WPF's better use of the

underlying graphics hardware

WPF

WinForm/GDI/GDI+

Page 72: WPF Deep Dive

Painter’s Algorithm• In User32 and GDI, the system works on an immediate mode clipping system. When

a component needs to be rendered, the system establishes a clipping bounds outside of which the component isn’t allowed to touch the pixels, and then the component is asked to paint pixels in that box.

• This system works very well in memory constrained systems because when something changes you only have to touch the affected component – no two components ever contribute to the color of a single pixel.

• WPF uses "painter's algorithm" painting model - Instead of clipping each component, each component is asked to render from the back to the front of the display. This allows each component to paint over the previous component's display.

• Advantage of this model is complex, partially transparent shapes. With today’s modern graphics hardware, this model is relatively fast (which wasn’t the case when User32/ GDI were created).

Page 73: WPF Deep Dive

Color• Supports both sRGB and

scRGB formatColor bgColor1 = Color.FromRgb(255, 0, 0);btn1.Background = new SolidColorBrush(bgColor1);

Color bgColor2 = Color.FromArgb(50, 255, 0, 0);btn2.Background = new SolidColorBrush(bgColor2);

Color bgColor3 = Color.FromScRgb(75.5f, 200.5f, 100.5f, 50.5f);btn3.Background = new SolidColorBrush(bgColor3);

btn4.Background = new SolidColorBrush(Colors.Green);

Page 74: WPF Deep Dive

Brushes Overview• WPF provides two types of brushes – Three Color Brush

• SolidColorBrush , LinearGradientBrush, RadialGradientBrush

– Three Tile Brush• Visual Brush, Drawing Brush, Image Brush

Page 75: WPF Deep Dive

Brushes: Color Brushes• WPF provides three Color Brush – SolidColorBrush– LinearGradientBrush– RadialGradientBrush

<Window.Background> <SolidColorBrush Color="LightSteelBlue" /></Window.Background>

<LinearGradientBrush> <GradientStop Color="White" Offset="0" /> <GradientStop Color="Black" Offset="2" /></LinearGradientBrush>

<RadialGradientBrush> <GradientStop Color="White" Offset="0" /> <GradientStop Color="DarkBlue" Offset="1" /></RadialGradientBrush>

Page 76: WPF Deep Dive

Brushes: Tile Brushes• WPF provides three Tile Brush

– Visual Brush– Drawing Brush– Image Brush

<Window.Background><ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Winter Leaves.jpg"></ImageBrush></Window.Background>

<Window.Background><ImageBrush TileMode="FlipXY" Viewport="0,0,0.5,0.5"

ImageSource="C:\Users\Public\Pictures\Sample Pictures\Winter Leaves.jpg"></ImageBrush>

</Window.Background>

<Window.Background> <VisualBrush TileMode="FlipXY" Viewport="0,0,0.5,0.5"> <VisualBrush.Visual> <TextBox>Aniruddha</TextBox> </VisualBrush.Visual> </VisualBrush></Window.Background>

Page 77: WPF Deep Dive

Pen• A Pen is a brush with a thickness• Important Pen properties– StartLineCap and EndLineCap– Line Join– DashStyle

<Line X1="20" Y1="40" X2="250" Y2="40" Stroke="Red" StrokeThickness="10" StrokeDashArray="1" StrokeDashCap="Flat"

StrokeStartLineCap="Triangle" StrokeEndLineCap="Round"></Line>

Page 78: WPF Deep Dive

Shapes• WPF provides six Shape related classes

(derived from System.Windows.Shapes.Shape)– Rectangle– Ellipse– Line– PolyLine– Polygon– Path

<StackPanel> <Rectangle Fill="Blue" Height="50" Width="175" Stroke="Black" StrokeThickness="5"></Rectangle> <Ellipse Fill="Orange" Height="50" Width="175" Stroke="Red" StrokeThickness="3"></Ellipse> <Line Stroke="Green" StrokeThickness="3" X1="20" Y1="20" X2="250" Y2="20"></Line> <Polyline Points="0,0 30,30 40,50 90,50 120,30 170,20" Stroke="Blue" StrokeThickness="2"></Polyline></StackPanel>

Page 79: WPF Deep Dive

Bitmap Effect• WPF provides the following

bitmap effects– Bevel– Emboss– Drop Shadow– Blur– Outer Glow

<Button Margin="10"><Button.BitmapEffect>

<DropShadowBitmapEffect/></Button.BitmapEffect>

Drop Shadow</Button>

Page 80: WPF Deep Dive

Transform• Provides 2D Transform classes (deriving from

System.Windows.Media.Transform)– RotateTransform– ScaleTransform– SkewTransform– TranslateTransform– MatrixTransform

• All FrameworkElements have two properties of type Transform:– LayoutTransform, which is applied before the element is

laid out– RenderTransform (inherited from UIElement), which is

applied after the layout

Page 81: WPF Deep Dive

RotateTransform• Rotates an element according to values of three properties.

– Angle: Angle of rotation, specified in degrees (default value = 0)– CenterX: Horizontal center of rotation (default value = 0)– CenterY: Vertical center of rotation (default value = 0)

<StackPanel> <Button>Button 1</Button> <Button MinWidth="120" MinHeight="30"> <Button.LayoutTransform> <RotateTransform Angle="45"></RotateTransform> </Button.LayoutTransform> Button 2 </Button> <Button>Button 3</Button></StackPanel>

Page 82: WPF Deep Dive

ScaleTransform• Enlarges or shrinks an element horizontally, vertically, or in both

directions.– ScaleX: Multiplier for the element’s width (default value = 1)– ScaleY: Multiplier for the element’s height (default value = 1)– CenterX: Origin for horizontal scaling (default value = 0)– CenterY: Origin for vertical scaling (default value = 0)

<StackPanel><Button>Button 1</Button>

<Button>Button 2<Button.LayoutTransform>

<ScaleTransform ScaleX="2.5" ScaleY="1.5"></ScaleTransform> </Button.LayoutTransform>

</Button> <Button>Button 3</Button></StackPanel>

Page 83: WPF Deep Dive

SkewTransform• Slants an element according to values of four properties.

– AngleX: Amount of horizontal skew (default value = 0)– AngleY: Amount of vertical skew (default value = 0)– CenterX: Origin for horizontal skew (default value = 0)– CenterY: Origin for vertical skew (default value = 0)

<StackPanel><Button>Button 1</Button>

<Button>Button 2<Button.LayoutTransform>

<SkewTransform AngleX="45" AngleY="5"></SkewTransform> </Button.LayoutTransform>

</Button> <Button>Button 3</Button></StackPanel>

Page 84: WPF Deep Dive

Combining Transform: TransformGroup• Multiple Transforms can be grouped using

TransformGroup<StackPanel> <Button>Button 1</Button> <Button MinWidth="120" MinHeight="30"> <Button.LayoutTransform> <TransformGroup> <SkewTransform AngleX="45" AngleY="5"></SkewTransform> <ScaleTransform ScaleX="2" ScaleY="1.5"></ScaleTransform> <RotateTransform Angle="5"></RotateTransform> </TransformGroup> </Button.LayoutTransform> Button 2 </Button> <Button>Button 3</Button></StackPanel>

Page 85: WPF Deep Dive

LayoutTransform vs. RenderTransform• LayoutTransform : Applied before the element is laid out• RenderTransform (inherited from UIElement): Applied

after the layout

<StackPanel> <Button>Button 1</Button> <Button MinWidth="120"> <Button.LayoutTransform> <RotateTransform Angle="45" /> </Button.LayoutTransform> Button 2 </Button> <Button>Button 3</Button></StackPanel>

<StackPanel> <Button>Button 1</Button> <Button MinWidth="120"> <Button.RenderTransform> <RotateTransform Angle="45" /> </Button.RenderTransform> Button 2 </Button> <Button>Button 3</Button></StackPanel>

Page 86: WPF Deep Dive

Trees in WPF• Logical Tree or Element Tree• Visual Tree <DockPanel> <ListBox DockPanel.Dock="Top"> <ListBoxItem>Dog</ListBoxItem> <ListBoxItem>Cat</ListBoxItem> <ListBoxItem>Fish</ListBoxItem> </ListBox> <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button></DockPanel>

Logical Tree

Page 87: WPF Deep Dive

Tree Helper Class• WPF exposes the functionality to traverse both the logical and

visual trees – System.Windows.LogicalTreeHelper – System.Windows.Media.VisualTreeHelper

Page 88: WPF Deep Dive

Tree Helper Example

Page 89: WPF Deep Dive

Data Binding & Template

Page 90: WPF Deep Dive

Data Binding Overview

• Data binding is the bridge between binding target and binding source.• Each Binding (represented by Binding class) has these four components:

– a binding Target object, – a Target property, – a Binding Source, – a Path to the value in the binding source to use.– e.g if you want to bind the content of a TextBox to the Name property of an

Employee object, your target object is the TextBox, the target property is the Text property, the value to use is Name, and the source object is the Employee object.

• The target property must be a Dependency Property. Most UIElement properties are dependency properties and most dependency properties, except read-only ones, support data binding by default.

Page 91: WPF Deep Dive

Data Binding: Control to Control• Process that establishes connection between application UI and business logic.

– If binding has correct settings & data provides proper notifications, then, when the data changes its value, elements bound to data reflect changes automatically.

<Label>Enter your name:</Label><TextBox x:Name="nameTextBox"></TextBox><Label Margin="0,20,0,0">Name Entered by you:</Label><Label x:Name="label" Content="{Binding ElementName=nameTextBox, Path=Text}"></Label>

Binding binding = new Binding();// Set the Source objectbinding.Source = nameTextBox;// Set the Source propertybinding.Path = new PropertyPath("Text");// Attach to Target propertylabel.SetBinding(Label.ContentProperty, binding);

Page 92: WPF Deep Dive

Binding Markup Extension• Binding is a Markup Extension similar to StaticResource &

DynamicResource– Markup Extensions are indicated by curly braces - { and }– No “ or ‘ within the curly braces– ElementName and Path are separated by ,

<Label>Enter your name:</Label><TextBox x:Name="nameTextBox"></TextBox><Label Margin="0,20,0,0">Name Entered by you:</Label><Label Content="{Binding ElementName=nameTextBox,Path=Text}"></Label><Label Content="{Binding Text,ElementName=nameTextBox}"></Label>

<Label>Enter your name:</Label><TextBox x:Name="nameTextBox"></TextBox><Label Margin="0,20,0,0">Name Entered by you:</Label><Label x:Name="label">

<Label.Content> <Binding ElementName="nameTextBox" Path="Text"></Binding>

</Label.Content></Label>

Alternate Property Element Syntax

Page 93: WPF Deep Dive

Binding Direction (Binding Mode)

• Mode Property of Binding accepts the following values -– OneWay: Changes to source property automatically update the

target property, but changes to target property are not propagated back to source property.

– TwoWay: Changes to either source property or target property to automatically update the other. This is default.

– OneWayToSource: Reverse of OneWay binding. updates source property when target property changes.

– OneTime: Source property to initialize the target property, but subsequent changes do not propagate.

Page 94: WPF Deep Dive

What triggers source update

• Bindings that are TwoWay or OneWayToSource listen for changes in the target property and propagate them back to the source. This is known as updating the source. – LostFocus: Default for TextBox.Text. Occurs when the TextBox control loses

focus.– PropertyChanged: As you type into the TextBox.– Explicit: When the application calls UpdateSource.

<Label>Enter your name:</Label><TextBox x:Name="nameTextBox"></TextBox><Label Margin="0,20,0,0">Name Entered by you:</Label><TextBox x:Name="label" Text="{Binding ElementName=nameTextBox, Path=Text,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>

Page 95: WPF Deep Dive

Relative Source• Refers to an element by its relationship to the target element. • The property is of type RelativeSource, which also happens to be a

markup extension.– To make the source element equal the target element:

{Binding RelativeSource={RelativeSource Self}}

– To make the source element equal the closest parent of a given type:{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type desiredType}}}

<Label>Enter a name of a color:</Label><TextBox Background="{Binding RelativeSource={RelativeSource Self}, Path=Text}"> </TextBox>

Page 96: WPF Deep Dive

Binding to .NET primitive data

public class PatientManager { public string PatientName { get; set; } public PatientManager() {

PatientName = "John Smith"; } }

<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:p="clr-namespace:WpfApplication1" Title="Data Binding - .NET primitive data" Height="300" Width="300"> <Window.Resources> <p:PatientManager x:Key="PatientSource"></p:PatientManager> </Window.Resources> <StackPanel> <Label>Patient Name:</Label> <TextBox Text="{Binding Source={StaticResource PatientSource}, Path=PatientName}"></TextBox> </StackPanel></Window>

Page 97: WPF Deep Dive

Data Context

<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:p="clr-namespace:WpfApplication1" Title="Data Binding - DataContext" Height="300" Width="300"> <Window.Resources> <p:PatientManager x:Key="PatientSource"></p:PatientManager> </Window.Resources> <StackPanel> <StackPanel.DataContext> <Binding Source="{StaticResource PatientSource}"></Binding> </StackPanel.DataContext> <Label>Patient Name:</Label> <TextBox Text="{Binding Path=PatientName}" /> <Label>Date of Birth:</Label> <TextBox Text="{Binding Path=DateOfBirth}" /> <Label>Address:</Label> <TextBox Text="{Binding Path=Address}" /> <Label>City:</Label> <TextBox Text="{Binding Path=City}" /> </StackPanel></Window>

public class PatientManager { public string PatientName { get; set; } public DateTime DateOfBirth { get; set; } public string Address { get; set; } public string City { get; set; } public PatientManager() { PatientName = "John Smith"; DateOfBirth = DateTime.Now; Address = "C.V.Raman Nagar"; City = "Bangalore"; } }

Page 98: WPF Deep Dive

Binding to .NET collection data

<Window.Resources> <p:Patient x:Key="PatientData"></p:Patient></Window.Resources><StackPanel DataContext="{StaticResource PatientData}"> <Label>Patient Name:</Label> <TextBox Text="{Binding Path=Name}" /> <Label>DOB:</Label> <TextBox Text="{Binding Path=Dob}" /> <Label>Patient's Addresses:</Label> <ListBox ItemsSource="{Binding Path=Addresses}" /></StackPanel>

Page 99: WPF Deep Dive

Notification: Interface and Collection• INotifyPropertyChanged: Used to notify clients, typically binding clients, that a property value has

changed. Provided in .NET 2.0• INotifyCollectionChanged: Notifies listeners of dynamic changes, such as when items get added

and removed or the whole list is refreshed. Provided in .NET 3.0• ObservableCollection<T>: WPF provided built-in implementation of a collection that exposes the

INotifyCollectionChanged. Provided in .NET 3.0

Page 100: WPF Deep Dive

INotifyPropertyChanged: Example

Page 101: WPF Deep Dive

INotifyCollectionChanged & ObservableCollection

• To set up dynamic bindings so that updates in collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface.

• INotifyCollectionChanged interface exposes an event that should be raised whenever the underlying collection changes.

• ObservableCollection<T> class provides built-in implementation of collection that exposes the INotifyCollectionChanged interface.

Page 102: WPF Deep Dive

ObservableCollection (Cont’d)

Page 103: WPF Deep Dive

Template Overview• Allows to completely

customize the look & feel.• Template allows to

completely replace an element’s visual tree while keeping all of its functionality intact.– Default visuals for every

Control in WPF are defined in templates (and customized for each Windows theme).

– The source code for every control is completely separated from its default visual tree representations.

Page 104: WPF Deep Dive

Template Example <Window.Resources> <Style x:Key="magicButton" TargetType="Button"> <Setter Property="FontSize" Value="16"></Setter> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="FontSize" Value="26"></Setter> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel> <Button Style="{StaticResource magicButton}">Hello World <Button.Template> <ControlTemplate> <Grid> <Ellipse Fill="LightBlue" Height="30" Width="150" Stroke="Red" StrokeThickness="2"></Ellipse> <ContentControl HorizontalAlignment="Center" VerticalAlignment="Center">Hello</ContentControl> </Grid> </ControlTemplate> </Button.Template> </Button> </StackPanel>

Page 105: WPF Deep Dive

Template Binding<StackPanel> <Button BorderThickness="3" Height="40" Width="150" Background="LightPink" BorderBrush="Brown" FontSize="16">Hello World <Button.Template> <ControlTemplate> <Grid> <Ellipse Fill="{TemplateBinding ContentControl.Background}" Height="{TemplateBinding ContentControl.Height}" Width="{TemplateBinding ContentControl.Width}" Stroke="{TemplateBinding ContentControl.BorderBrush}" StrokeThickness="{TemplateBinding ContentControl.BorderThickness}"></Ellipse> <ContentControl HorizontalAlignment="{TemplateBinding ContentControl.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding ContentControl.VerticalContentAlignment}" FontSize="{TemplateBinding ContentControl.FontSize}" Content="{TemplateBinding ContentControl.Content}"></ContentControl> </Grid> </ControlTemplate> </Button.Template> </Button></StackPanel>

Page 106: WPF Deep Dive

Input and Command

Page 107: WPF Deep Dive

Input Overview• Provides powerful API for obtaining input from variety of devices,

including the mouse, keyboard, and stylus.• Primary input API exposure is found on base element classes:

UIElement, ContentElement, FrameworkElement, and FrameworkContentElement– Provide functionality for input events related to key presses, mouse

buttons, mouse wheel, mouse movement, focus management, and mouse capture.

• Additionally Keyboard class & Mouse classes provide additional API for working with keyboard & mouse input.– Examples of input API on the Keyboard class are

the Modifiers property, which returns the ModifierKeys currently pressed– IsKeyDown method, which determines whether a specified key is pressed. – Examples of input API on the Mouse class are MiddleButton, which

obtains the state of the middle mouse button, and DirectlyOver, which gets the element the mouse pointer is currently over.

Page 108: WPF Deep Dive

Loose Coupling• Supports Events at different abstraction level

– Physical Event: Supports direct Mouse events like MouseUp, MouseDown– Semantic Event: Supports higher level events like Click.

• Can fire when user presses space bar (with the button in focus)• Can fire when user presses Enter (when the button is default)• Can happen when user uses mouse or stylus

• Writing code against the Click event has two advantages: – Independent of specific input gesture (mouse versus keyboard), – NOT tied with button. Code written against the Click event depends only on a

component that can be clicked. Decoupling of code to the action produced allows for more flexibility in the implementation of handlers.

• Events suffer from a form of coupling that requires the method implementation to be of a specific signature. e.g. the delegate for Button.Click is defined as follows:public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);

Page 109: WPF Deep Dive

Built in Commands• WPF defines a bunch of commands so you don’t have to implement

ICommand objects for Cut, Copy, and Paste and worry about where to store them.

• WPF’s built-in commands are exposed as static properties of five different classes.– ApplicationCommands: Close, Copy, Cut, Delete, Find, Help, New, Open,

Paste, Print, PrintPreview, Properties, Redo, Replace, Save, SaveAs, SelectAll, Stop, Undo

– ComponentCommands: MoveDown, MoveLeft, MoveRight, MoveUp, ScrollByLine, ScrollPageDown, ScrollPageLeft, ScrollPageRight, ScrollPageUp, SelectToEnd, SelectToHome, SelectToPageDown, SelectToPageUp

– MediaCommands: ChannelDown, ChannelUp, DecreaseVolume, FastForward, IncreaseVolume, MuteVolume, NextTrack, Pause, Play, PreviousTrack, Record, Rewind, Select, Stop

– NavigationCommands: BrowseBack, BrowseForward, BrowseHome, BrowseStop, Favorites, FirstPage, GoToPage, LastPage, NextPage, PreviousPage, Refresh, Search, Zoom, and more

– EditingCommands: AlignCenter, AlignJustify, AlignLeft, AlignRight, CorrectSpellingError, DecreaseFontSize, DecreaseIndentation, EnterLineBreak, EnterParagraphBreak, IgnoreSpellingError, IncreaseFontSize, IncreaseIndentation, MoveDownByLine, MoveDownByPage, MoveDownByParagraph, MoveLeftByCharacter, MoveLeftByWord, MoveRightByCharacter, MoveRightByWord

Page 110: WPF Deep Dive

Built In Command Example

Page 111: WPF Deep Dive

Custom Command• Implement ICommand interface– Execute: The method that executes the

command specific logic– CanExecute: A method returning true if the

command is enabled or false if it is disabled– CanExecuteChanged: An event that is raised whenever the

value of CanExecute changes

Page 112: WPF Deep Dive

Custom Command Example

Page 113: WPF Deep Dive

Custom Command Example (Cont’d)

Page 114: WPF Deep Dive

Routed Event• Events that are designed to work well with a tree of elements. • When a routed event is raised, it can travel up or down the visual

and logical tree, getting raised on each element in a simple and consistent fashion, without the need for any custom code.

• Helps Apps remain oblivious to details of the visual tree & is crucial to success of element composition.

• Routing strategies: the way in which event raising travels through element tree -

1. Tunneling: The event is first raised on the root, then on each element down the tree until the source element is reached (or until a handler halts the tunneling by marking the event as handled).

2. Bubbling: The event is first raised on the source element, then on each element up the tree until the root is reached (or until a handler halts the bubbling by marking the event as handled).

3. Direct: The event is only raised on source element. This is same behavior as plain .NET event, except that such events can still participate in mechanisms specific to routed events.

Page 115: WPF Deep Dive

RoutedEventAgrs

• Source: The element in the logical tree that originally raised the event.

• OriginalSource: The element in the visual tree that originally raised the event.

• Handled: A Boolean that can be set to true to mark the event as handled. This is precisely what halts any tunneling or bubbling.

• RoutedEvent: The actual routed event object (such as Button.ClickEvent), which can be helpful for identifying the raised event when the same handler is used for multiple routed events.

private void Button_Click(object sender, RoutedEventArgs e)private void button1_Click(object sender, EventArgs e)

Page 116: WPF Deep Dive

Dependency Property

Dependency Property (DP) & Attached Property

Page 117: WPF Deep Dive

Dependency Property Overview• WPF Introduces a new Property called DP• Used throughout the platform to enable styling, automatic data

binding, animation and more.• A dependency property depends on multiple providers for

determining its value at any point in time. – Providers could be an animation continuously changing its value, a parent

element whose property value trickles down to its children, and so on.

• Biggest feature of DP is built-in ability to provide change notification.

• DP allows property value inheritance.– Doesn’t refer to traditional object oriented class based inheritance, but

rather the flowing of property values down the element tree.

this.FontSize = 20;

Page 118: WPF Deep Dive

Dependency Property Example// Declare a public object of type DependencyPropertypublic static readonly DependencyProperty SpaceProperty;

// .NET Property Wrapper (Optional)public int Space{ get { return (int)GetValue(SpaceProperty); } set { SetValue(SpaceProperty, value); }}

// Declare metadata such as default value of the DPFrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();metadata.DefaultValue = 1;metadata.AffectsMeasure = true;metadata.Inherits = true;metadata.PropertyChangedCallback += OnSpacePropertyChanged;

// Register the Dependency PropertySpaceProperty = DependencyProperty.Register("Space", typeof(int), typeof(SpaceButton), metadata, ValidateSpaceButton);

static void OnSpacePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { }

Page 119: WPF Deep Dive

Change Notification

Page 120: WPF Deep Dive

WPF Books