29
XAML XAML, properties, events 1 XAML Extensible Application Markup Separate the graphical portion from the underlying code XAML documents define the panels, buttons, and controls that make up the windows in a WPF application XAML graphical design tools Expression Blend graphic designer (non-coder) Microsoft Visual Studio developer / designer WPF XAML all the XAML's subsets: XPS XAML electronic document formatting Silverlight cross-platform browser plug-in for rich web content: 2D graphics, animation, audio and video. WF XAML Windows Workflow Foundation WPF source compiled BAML (binary application markup lang) embedded in DLL or EXE assembly (tokenized for size)

XAML Extensible Application Markup Separate the …renzo/cs585/WPF-XAML.pdf · XAML XAML, properties, events 1 XAML Extensible Application Markup Separate the graphical portion from

Embed Size (px)

Citation preview

XAML XAML, properties, events 1

XAML Extensible Application Markup

Separate the graphical portion from the underlying code

XAML documents define the panels, buttons, and controls that make up

the windows in a WPF application

XAML graphical design tools

Expression Blend graphic designer (non-coder)

Microsoft Visual Studio developer / designer

WPF XAML all the XAML's subsets:

XPS XAML electronic document formatting

Silverlight cross-platform browser plug-in for rich web content:

2D graphics, animation, audio and video.

WF XAML Windows Workflow Foundation

WPF source compiled BAML (binary application markup lang)

embedded in DLL or EXE assembly (tokenized for size)

XAML Namespaces XAML, properties, events 2

The XAML parser also needs to know the .NET namespace where this

class is located.

Standard Microsoft namespaces

core WPF

http://schemas.microsoft.com/winfx/2006/xaml/presentation

XAML utilities

http://schemas.microsoft.com/winfx/2006/xaml/presentation

Other system / API namespaces

xmlns:Prefix="clr-namespace:Namespace;

assembly=AssemblyName"

// AssemblyName does not have ".dll" extension

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

Code behind class for event handlers // application class x:Class="attractor.MainWindow"

Application specific namespaces (xmls:local=...),

Types defined in project's additional classes

XAML, properties, events 3

// MainWindow.xaml file

<Window x:Name="mainWindow" x:Class="attractor.MainWindow"

xmlns:local="clr-namespace:attractor"

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

presentation"

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

Title="Sierpinski Triangle" Height="450" Width="600"

ShowInTaskbar="False" BorderThickness="2"

SizeToContent="WidthAndHeight"

WindowStartupLocation="CenterOwner"

UseLayoutRounding="True" MinWidth="600"

inHeight="400" Topmost="True" Background="Gray">

</Window>

Partial classes, InitializeComponent() XAML, properties, events 4

C# Partial class allows XAML (design) and Class (code) to be separate

sources compiled into a single class.

// MainWindow.xaml.cs file

namespace attactor {

public partial class MainWindow : Window {

public MainWindow() {

InitializeComponent(); // must be first line

...

}

}

}

Build/compile sequence

MainWindow.xaml clr (common language runtime) type that is

merged with MainWindow.xaml.cs (code behind).

InitializeComponent() is generated by compiler.

InitializeComponent() extracts BAML from assembly for user interface.

Names XAML, properties, events 5

In XAML an element has "attributes" these are type converted to

properties in the code-behind by the XAML parser.

Naming elements in XAML allows code to get/set properties of element.

// MainWindow.xaml file

<Window x:Name="mainWindow" x:Class="attractor.MainWindow"

...>

<Button x:Name="runBtn" ToolTip="start the drawing"

UseLayoutRounding="True"

ScrollViewer.CanContentScroll="True"

Click="runClicked" Content="Run" Margin="5,10,5,5"

IsEnabled="False"/>

...

</Window>

Button named "runBtn" has attribute IsEnabled initially false.

In code the corresponding property could be set true....

runBtn.IsEnabled = true;

...

Complex properties XAML, properties, events 6

Some properties are full-fledged objects with their own set of properties.

e.g., Background property has Brush properties.

XAML has a property-element syntax for complex properties – nested

tags.

<Window ...

<ComboBox x:Name="redComboBox" SelectedIndex="1"

SelectionChanged="colorSet" Margin="0,10,0,0">

<ComboBox.Background>

<LinearGradientBrush EndPoint="0,1"

StartPoint="0,0">

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

...

</LinearGradientBrush>

</ComboBox.Background>

...

</Window>

XAML Markup extensions XAML, properties, events 7

Consider setting a property value to an object that already exists.

Or setting a property value dynamically by binding it to a property in

another control.

Markup extensions use "{"..."}" syntax

Refer to a Static property in another class

<Button ... Foreground="{x:Static

SystemColors.ActiveCaptionBrush}">

Code equivalent

cmdAnswer.Foreground = SystemColors.ActiveCaptionBrush;

Attached properties XAML, properties, events 8

Attached properties may apply to several controls but are defined in a

different class.

Attached properties have a two-part name in this form:

DefiningType.PropertyName.

Defining type is Grid and Property name is Row

<TextBox ... Grid.Row=”0”> ... </TextBox>

<Button ... Grid.Row=”1”> ... </Button>

<TextBox ... Grid.Row=”2”> ... </TextBox>

This code implies that the row number is stored in the Grid object.

However, the row number is actually stored in the object that it applies

to—in this case, the TextBox or Button objects.

Attached properties are an all-purpose extensibility system.

By defining the Row property as an attached property, it’s usable with

another control.

event handler XAML, properties, events 9

Button named "runBtn" has event handler "runClicked" that responds to a

Click mouse event w/in the button.

The code behind for runClicked is in the *.xaml.cs file.

private void runClicked(object sender, RoutedEventArgs e){

// cast the sender object as a Button, or a

// FrameworkElement, to set properties.

Button srcButton = sender as Button; // or e.Source

... // code for runBtn's behavior here

}

Object the source of the event

RoutedEventArgs args describing the event

Handled Present state of routed event as it travels the route.

OriginalSource Gets the original reporting source before

adjustments by a parent class.

RoutedEvent RoutedEvent type for this RoutedEventArgs

Source object that raised the event.

Routed events XAML, properties, events 10

WPF routed events can tunnel down or bubble up the element tree and

be processed by event handlers along the way.

Usually attach an event handler by adding an event attribute to your

XAML markup (or property to the class, with Designer).

<Image Source="happyface.jpg" Stretch="None“ Name="img“

MouseUp="img_MouseUp" />

Connect an event with code img.MouseUp += new MouseButtonEventHandler(img_MouseUp);

Naming convention is ElementName_EventName or a meaningful alias

for ElementName.

<Button Click="cmdOK_Click">OK</Button>

Only code can detach an event handler

img.MouseUp -= img_MouseUp;

Event routing XAML, properties, events 11

3 Routed events:

Direct events originate in one element and don’t pass to any other.

MouseEnter fires when Mouse moves over element

Bubbling events travel up the containment hierarchy

MouseDown raised first by the element that is clicked.

Next, it’s raised by that element’s parent, then by that element’s

parent, … , to top of the element tree.

Tunneling events travel down the containment hierarchy, can preview

(and stop) event before it reaches the appropriate control.

PreviewKeyDown can intercept a key press, first at the window level

and then in increasingly more-specific containers

until you reach the element that had focus when the key was pressed.

Tunneling & bubbling event paths XAML, properties, events 12

XAML bubbling event XAML, properties, events 13

<Window x:Class="RoutedEvents.BubbledLabelClick"

MouseUp="SomethingClicked">

<Grid Margin="3" MouseUp="SomethingClicked">

<Grid.RowDefinitions> … </Grid.RowDefinitions>

<Label …

MouseUp="SomethingClicked">

<StackPanel MouseUp="SomethingClicked">

<TextBlock Margin="3“ MouseUp="SomethingClicked">

</TextBlock>

<Image Source="happyface.jpg" Stretch="None"

MouseUp="SomethingClicked" />

<TextBlock Margin="3"

MouseUp="SomethingClicked"> … </TextBlock>

</StackPanel>

</Label>

</Grid>

</Window>

Code bubbling event XAML, properties, events 14

The SomethingClicked() method examines the properties of the

RoutedEventArgs object and adds a message to the list box:

protected int eventCounter = 0;

private void SomethingClicked(object sender,

RoutedEventArgs e)

{

eventCounter++;

string message = "#" +

eventCounter.ToString() + ":\r\n" +

" Sender: " + sender.ToString() + "\r\n" +

" Original Source: " + e.OriginalSource + "\r\n" +

" is Handled: " + e. Handled;

}

RoutedEventArgs.Handled property to true to stop the event bubbling

sequence the first time an event occurs.

example bubble up XAML, properties, events 15

Attached event XAML, properties, events 16

Consider a stack of buttons in a StackPanel and you want to handle all

the button clicks in one event handler.

One approach is to have the Click event of each button use the same

event handler.

The Click event is bubbling, handle all the events in the StackPanel; but

StackPanel doesn't have a Click event!

Use an attached event

<StackPanel Button.Click="DoSomething" Margin="5">

<Button Name="cmd1">Command 1</Button>

<Button Name="cmd2">Command 2</Button>

<Button Name="cmd3">Command 3</Button>

...

</StackPanel>

Which button ? XAML, properties, events 17

The Click event is defined in ButtonBase class and inherited by the

Button class.

Attach an event handler to ButtonBase.Click and that event handler can

be used by any ButtonBase-derived control {Button, RadioButton, and

CheckBox}.

To add the handler to the StackPanel, assume its name is buttonPanel.

Can't use += operator technique, need to use UIElement.AddHandler()

buttonPanel.AddHandler(Button.Click,

new RoutedEventHandler(DoSomething));

How does DoSomething() know which button was Clicked?

Look at the source (could also set a property tag in XAML)

private void DoSomething(object sender, RoutedEventArgs e){

if (e.Source == cmd1){ ... }

else if (e.Source == cmd2){ ... }

else if (e.Source == cmd3){ ... }

}

5 WPF event categories XAML, properties, events 18

Lifetime events: occur when the element is initialized, loaded, or

unloaded.

Mouse events: are the result of mouse actions.

Keyboard events: are the result of keyboard actions

(such as key presses).

Stylus events: These events are the result of using the pen-like stylus,

which takes the place of a mouse on a Tablet PC.

Multitouch events: These events result from touching down with one

or more fingers on a multitouch screen; supported only in

Windows 7 and Windows 8.

Mouse, keyboard, stylus, and multitouch are known as input events.

Input Events XAML, properties, events 19

Keyboard input XAML, properties, events 20

Name Routing Description

PreviewKeyDown Tunneling when a key is pressed.

KeyDown Bubbling when a key is pressed.

PreviewTextInput Tunneling when a keystroke is complete and

element is receiving text input.

Doesn’t fire: Ctrl, Shift,

Backspace, arrow , function

TextInput Bubbling when a keystroke is complete and

element is receiving text input.

Doesn't fired for keystrokes that

don’t result in text.

PreviewKeyUp Tunneling when a key is released.

KeyUp Bubbling when a key is released.

Mouse Input XAML, properties, events 21

Name Routing Description

MouseEnter Direct when mouse moves over element

MouseLeave Direct when mouse moves off element

PreviewMouseMove Tunneling when mouse moves

Mouse Move Bubbling when mouse moves

PreviewMouseLeftButtonDown Tunneling

PreviewMouseRightButtonDown when a mouse button is pressed

MouseLeftButtonDown Bubbling

MouseRightButtonDown when a mouse button is pressed

PreviewMouseLeftButtonUp Tunneling

PreviewMouseRightButtonUp when a mouse button is released

MouseLeftButtonUp Bubbling

MouseRightButtonUp when a mouse button is released

Mouse EventArgs XAML, properties, events 22

MouseEventArgs object has properties for the state of the mouse

buttons, and a GetPosition() method that returns the coordinates of the

mouse in relation to an element of your choosing.

Coordinates x and y offsets from element's origin corner (upper left)

private void MouseMoved(object sender, MouseEventArgs e) {

Point pt = e.GetPosition(this);

// showing a MessageBox for every mouse move, Bad idea ...

// MessageBox.Show(String.Format(

// "You are at ({0},{1})", pt.X, pt.Y);

...

}

Canvas mouse events XAML, properties, events 23

For a Canvas to respond to mouse events (like right mouse button down)

the Background Brush property can't be null or unset. It should be a

color.

The Background property is best set with the Property Window for a

Canvas. Below's Background example is close to white.

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

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

Title="A Canvas right mouse button up example"

Height="350" Width="525">

<DockPanel x:Name="dockPanel" Margin="0"

ToolTip="Use the right mouse button">

<Canvas x:Name="canvas" Cursor="Cross"

MouseRightButtonUp="rightButtonUp"

Background="#FFF9F6F6"/>

</DockPanel>

</Window>

Mouse capture XAML, properties, events 24

For drag operations you need notification of mouse up events, as they

occur and when the mouse has moved off your initial (selected) element

For example to drag an element:

mouseDown set selected element and capture mouse

mouseMove selected element's position gets mouse position

mouseUp release mouse capture

UIElement CaptureMouse() and ReleaseMouseCapture() for an

element's capture of the mouse.

isMouseCaptured property set true

CaptureMouse(null) can also release mouse for all elements

IInputElement Mouse.Capture (

IInputElement element, // selected element

CaptureMode captureMode ) // element, none, subtree

for element and element's subtree mouse capture.

Multi-touch input XAML, properties, events 25

Drag and Drop, see MSDN, on-line reading

Stylus (pen) input events similar to mouse, see MSDN, on-line reading

Multi-touch input differs from pen input in the use of gestures

specific ways the user can move more than one finger to operations.

3 levels of Multi-touch

Raw touch access to every touch not using standard gestures

Manipulation common gestures of WPF elements

pan, zoom, rotate, and tap.

Built-in element support some elements have built in support

e.g., scrollable controls {ListBox, ListView, DataGrid, TextBox, and

ScrollViewer} have touch panning.

XAML, properties, events 27

Raw touch events XAML, properties, events 28

Name Type Description

PreviewTouchDown Tunneling when the user touches down

TouchDown Bubbling when the user touches down

PreviewTouchMove Tunneling when the user moves

the touched-down finger

TouchMove Bubbling when the user moves

the touched-down finger

PreviewTouchUp Tunneling when the user lifts the

finger, ending the touch

TouchUp Bubbling when the user lifts the

finger, ending the touch

TouchEnter None when a contact point moves

into element

TouchLeave None when a contact point moves out

TouchEventArgs XAML, properties, events 29

private void canvas_TouchMove(object sender, TouchEventArgs e) {

// Get the ellipse that corresponds to the current contact

// point.

UIElement element = movingEllipses[e.TouchDevice.Id];

// Move it to the new contact point.

TouchPoint touchPoint = e.GetTouchPoint(canvas);

Canvas.SetTop(ellipse, touchPoint.Bounds.Top);

Canvas.SetLeft(ellipse, touchPoint.Bounds.Left);

}

TouchEventArgs has two important members.

GetTouchPoint() method provides the screen coordinates of touch

event (and less used data, like the size of the contact point).

TouchDevice property returns a TouchDevice object

Every contact point is treated as a separate device

UIElement has CaptureTouch() and ReleaseTouchCapture() methods,

similar to CaptureMouse() and ReleaseMouseCapture().