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.
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.
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.
Gestures XAML, properties, events 26
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().