Charles Petzold XAML
Agenda Layout and positioning Shapes, brushes, and brush resources Text, fonts, and font resources Images and writeable bitmaps UI element properties Creating XAML objects programmatically Transforms and projections Animations and animation easing GPU caching
Controls for positioning UI elements More in the Silverlight for Windows Phone Toolkit Layout Controls ControlDescription CanvasPositions elements using pixel coordinates GridArranges objects in rows and columns StackPanelArranges objects in a row or a column
Allows absolute positioning of elements Canvas <Rectangle Canvas.Left="50" Canvas.Top="50" Width="100" Height="100" Fill="Red" /> <Canvas Canvas.Left="200" Canvas.Top="100" Width="200" Height="200" Background="Yellow"> <Rectangle Canvas.Left="50" Canvas.Top="50" Width="100" Height="100" Fill="Blue" />
Stacks elements horizontally or vertically StackPanel
Arranges elements in rows and columns Grid <Rectangle Width="100" Height="100" Fill="Red" Grid.Row="0" Grid.Column="0" /> <Rectangle Width="100" Height="100" Fill="Green" Grid.Row="0" Grid.Column="1" /> <Rectangle Width="100" Height="100" Fill="Blue" Grid.Row="1" Grid.Column="0" /> <Rectangle Width="100" Height="100" Fill="Yellow" Grid.Row="1" Grid.Column="1" />
Absolute sizing: Width="200" Automatic sizing: Width="Auto" –Column width == Width of widest object in column Proportional sizing: Sizing Rows and Columns 25% of total width 50% of total width 25% of total width
FrameworkElement's HorizontalAlignment and VerticalAlignment properties control alignment Alignment <Rectangle Width="100" Height="100" Fill="Red" HorizontalAlignment="Left" VerticalAlignment="Top" /> <Rectangle Width="100" Height="100" Fill="Green" Margin="10" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
FrameworkElement's Margin property creates padding around elements Margins
demo Layout
Silverlight supports six shape types Shapes RectangleEllipsePolygon LinePolyLinePath
Rectangles <Rectangle Width="300" Height="200" StrokeThickness="10" Stroke="Black" Fill="Yellow" />
Paths <Path Fill="Yellow" Stroke="Black" StrokeThickness="4" StrokeEndLineCap="Round" StrokeLineJoin="Round" Data="M 200,200 C 200, , ,140 C 330, , ,200" />
Objects used to color XAML UI elements Apply using property-element syntax Brushes BrushDescription SolidColorBrushRenders a solid color LinearGradientBrushRenders a linear gradient RadialGradientBrushRenders a radial gradient ImageBrushRenders an image
Allows properties to be assigned nontrivial values Property-Element Syntax <Rectangle Height="200" Width="300" Stroke="Black" StrokeThickness="10">
LinearGradientBrush <Rectangle Height="200" Width="300" Stroke="Black" StrokeThickness="10">
RadialGradientBrush <Rectangle Height="200" Width="300" Stroke="Black" StrokeThickness="10"> <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
Approximately 25 built-in brush resources –PhoneAccentBrush and PhoneSubtleBrush –PhoneBackgroundBrush and PhoneForegroundBrush –PhoneChromeBrush and PhoneDisabledBrush –PhoneBorderBrush and many others Colors change with theme and accent colors Complete list at us/library/ff769552(v=vs.92).aspx Also in ThemeResources.xaml Stock Brush Resources
Stock Brush Resources in Action Dark theme Blue accent Light theme Blue accent Dark theme Orange accent
Using Stock Brush Resources <Rectangle Width="300" Height="80" Stroke="{StaticResource PhoneBorderBrush}" Fill="{StaticResource PhoneAccentBrush}" /> {StaticResource} markup extension loads the specified resource
demo Stock Brushes
TextBlock <TextBlock FontSize="120" FontFamily="Georgia" FontStyle="Italic" FontWeight="Bold"> Silverlight
Default is Segoe WP Approx. 15 fonts provided in ROM on phones –Arial, Courier New, Georgia, Times New Roman, Segoe WP, Tahoma, Trebuchet MS, Verdana, and more –Complete list at us/library/ff806365%28v=VS.95%29.aspx Custom fonts supported, too Fonts
Build TTFs into application assembly as resources –Also works with ZIP files containing TTFs Reference individual fonts using syntax FontFamily="filename#fontname" Custom Fonts Silverlight
Built-in FontFamily resources –PhoneFontFamilyNormal, PhoneFontFamilyLight, PhoneFontFamilySemiLight, PhoneFontFamilySemiBold Built-in FontSize resources –PhoneFontSizeSmall, Normal, Medium, MediumLarge, Large, ExtraLarge, ExtraExtraLarge, Huge Built-in Style resources –PhoneTextNormalStyle, PhoneTextAccentStyle, PhoneTextContrastStyle, and many others –Combine FontFamily, FontSize, and Foreground Stock Font Resources
Stock Font Resources in Action PhoneTextNormalStyle PhoneTextTitle1Style PhoneTextExtraLargeStyle PhoneTextSubtleStyle PhoneTextAccentStyle
Using Stock Font Resources <TextBlock... Style="{StaticResource PhoneTextExtraLargeStyle}" /> <TextBlock... Style="{StaticResource PhoneTextAccentStyle}" /> {StaticResource} markup extension loads the specified resource
Images
Set build action to Content, not Resource, for images and other media –Both work –Resource is the default –Content is faster Images and Build Actions
Silverlight's pixel-addressable bitmap API –Pixels exposed through Pixels property –One-dimensional array (row-first order) Create bitmaps from scratch Create bitmaps from Image objects Render all or part of the XAML tree to a bitmap WriteableBitmap
Generating an Image WriteableBitmap bitmap = new WriteableBitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { bitmap.Pixels[(y * width) + x] = unchecked((int)0xFF000000); // ARGB (black) } bitmap.Invalidate(); // Copy WriteableBitmap bits to a XAML Image MyImage.Source = bitmap;
Modifying a XAML Image WriteableBitmap bitmap = new WriteableBitmap((BitmapImage)MyImage.Source); for (int x = 0; x < bitmap.PixelWidth; x++) { for (int y = 0; y < bitmap.PixelHeight; y++) { // TODO: Modify pixel at bitmap.Pixels[[(y * width) + x] } bitmap.Invalidate(); // Copy WriteableBitmap bits to back to the XAML Image MyImage.Source = bitmap;
Rendering XAML to a Bitmap // Create a WriteableBitmap WriteableBitmap bitmap = new WriteableBitmap(width, height); // Render Canvas named "TargetCanvas" to the bitmap bitmap.Render(TargetCanvas, null); bitmap.Invalidate(); // Copy WriteableBitmap bits to a XAML Image MyImage.Source = bitmap;
demo WriteableBitmap
Properties of UI Elements PropertyDescription Clip Clips an element using a specified geometry Cursor Specifies the appearance of the mouse cursor over an element IsHitTestVisible Determines whether an element fires touch events Opacity Specifies an element's opacity (0.0 – 1.0) OpacityMask Varies opacity using a gradient brush Style Applies a style to an element Visibility Controls an element's visibility Canvas.ZIndex Specifies an element's Z-index
Controls visibility of XAML objects –Visibility.Visible (default) – Visible –Visibility.Collapsed – Not visible Use Opacity, not Visibility, to hide objects temporarily (opposite desktop guidance) Visibility // XAML // C# Ball.Visibility = Visibility.Collapsed; // Make it disappear
Opacity <Ellipse Canvas.Left="50" Canvas.Top="50" Stroke="Black" Height="200" Width="300" StrokeThickness="10" Fill="Red" Opacity="0.5" /> <Ellipse Canvas.Left="200" Canvas.Top="50" Stroke="Black" Height="200" Width="300" StrokeThickness="10" Fill="#80FFFF00" />
OpacityMask...
Canvas.ZIndex <Ellipse Canvas.Left="50" Canvas.Top="50" Stroke="Black" Height="200" Width="300" StrokeThickness="10" Fill="Red" Canvas.ZIndex="1" /> <Ellipse Canvas.Left="200" Canvas.Top="50" Stroke="Black" Height="200" Width="300" StrokeThickness="10" Fill="Yellow" Canvas.ZIndex="0" />
Direct instantiation –Ellipse e = new Ellipse(); –One object at a time XamlReader.Load –Creates object(s) from XAML strings –One object or tree of objects Add object(s) to XAML DOM separately Creating XAML Objects at Run-Time
Direct Instantiation Ellipse ellipse = new Ellipse(); ellipse.SetValue(Canvas.LeftProperty, 50.0); ellipse.SetValue(Canvas.TopProperty, 50.0); ellipse.Width = 100.0; ellipse.Height = 100.0; ellipse.Fill = new SolidColorBrush(Colors.Red); Placeholder.Children.Add(ellipse);
XamlReader.Load string xaml = "<Ellipse " + "xmlns=\" " + "Canvas.Left=\"50\" Canvas.Top=\"50\" " + "Width=\"100\" Height="\100\" Fill=\"Red\" />"; FrameworkElement ellipse = (FrameworkElement) XamlReader.Load(xaml); Placeholder.Children.Add(ellipse);
demo Creating XAML Objects at Run-Time
Enable objects or groups of objects to be translated, rotated, scaled, and skewed Applied by assigning Transform object(s) to visual element's RenderTransform property –RenderTransform applies transform to objects after layout is performed (not before) –Silverlight doesn't support LayoutTransform Applies transform to objects before layout The basis for many advanced visual effects Transforms
Transform Types TranslateTransformRotateTransform SkewTransformScaleTransform
RotateTransform <Rectangle Fill="Yellow" Stroke="Black" Height="200" Width="300" StrokeThickness="10"> X Y (0,0) 30 o
<Rectangle Fill="Yellow" Stroke="Black" Height="200" Width="300" StrokeThickness="10"> Controlling Center of Rotation X Y 30 o
<Rectangle Fill="Yellow" Stroke="Black" Height="200" Width="300" StrokeThickness="10" RenderTransformOrigin="0.5,0.5"> XAML property that controls transform origin using normalized coordinates –0,0 = Upper left corner –1,1 = Lower right corner RenderTransformOrigin
Use element to apply multiple transforms to a XAML element Transforms applied in top-to-bottom order TransformGroup
One transform that does it all Applies transforms in following order: –Scale, Skew, Rotate, Translate CompositeTransform <CompositeTransform Rotation="135" ScaleX="1.5" ScaleY="1.2" TranslateX="100" SkewX="30" />
demo Transforms
PlaneProjection class applies perspective projections to XAML elements –Rotates elements about 3D coordinate axes –Applied through UIElement.Projection property Properties provide control over projection Projections
Rotating Around the Y-Axis
Controlling "Camera" Position <PlaneProjection RotationY="45" GlobalOffsetY="-300" /> Moves "camera" position down 300 pixels from center
demo Projections
Animations vary properties of elements over time –From-to animations vary properties linearly –Key-frame animations use discrete steps Animation objects define animations –DoubleAnimation[UsingKeyFrames] –ColorAnimation[UsingKeyFrames] –PointAnimation[UsingKeyFrames] StoryBoard objects hold animation objects Animations
From-To Animations <DoubleAnimation Storyboard.TargetName="Rect" Storyboard.TargetProperty="(Canvas.Left)" From="0" To="200" Duration="0:0:2" /> Rectangle's Canvas.Left property varies linearly from 0 to 200 over 2 seconds
Key-Frame Animations <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Rect" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2"> Canvas.Left goes from 0 to 50 in first second Canvas.Left goes from 50 to 200 in second second
Triggering an Animation // XAML <DoubleAnimation Storyboard.TargetName="Rect" Storyboard.TargetProperty="(Canvas.Left)" From="0" To="200" Duration="0:0:2" /> // C# RectStoryBoard.Begin(); // Call Begin on Storyboard object
Composing Animations <DoubleAnimation Storyboard.TargetName="Rect" Storyboard.TargetProperty="(Canvas.Left)" From="0" To="200" Duration="0:0:2" /> <DoubleAnimation Storyboard.TargetName="Rect" Storyboard.TargetProperty="(Canvas.Top)" From="0" To="200" Duration="0:0:2" BeginTime="0:0:2" /> Second animation begins after 2 seconds First animation begins immediately and runs for 2 seconds
Adds non-linear effects to animations –Bounce, oscillation, deceleration, and more Easing classes encapsulate effects –11 easing classes built in (BounceEase etc.) –Create custom easing classes by implementing IEasingFunction Simulate physics with simple from/to animations! Animation Easing
Easing Classes ClassDescription BackEase Retracts the motion of an animation slightly before it begins BounceEase Adds "bounce" to an animation CircleEase Accelerates and/or decelerates using a circular function CubicEase Accelerates and/or decelerates using the formula f(t) = t 3 ElasticEase Adds oscillation to an animation ExponentialEase Accelerates and/or decelerates using an exponential formula PowerEase Accelerates and/or decelerates using the formula f(t) = t p QuadraticEase Accelerates and/or decelerates using the formula f(t) = t 2 QuarticEase Accelerates and/or decelerates using the formula f(t) = t 4 QuinticEase Accelerates and/or decelerates using the formula f(t) = t 5 SineEase Accelerates and/or decelerates using a sine formula
Using BounceEase <DoubleAnimation Storyboard.TargetName="Ball" Storyboard.TargetProperty="(Canvas.Top)" From="200" To="0" Duration="0:0:1"> <BounceEase Bounces="10" Bounciness="2" EasingMode="EaseOut" />
demo Animation Easing
DispatcherTimer –Fires Tick events at programmable intervals –Use it to reposition objects in scene at regular intervals CompositionTarget.Rendering –Per-frame events fired by rendering engine Frequency controlled by MaxFrameRate property –Use it to perform precision custom animations (e.g., game loops) Manual Animations
DispatcherTimer private DispatcherTimer _timer;. _timer = new DispatcherTimer(); _timer.Tick += new EventHandler(OnTimerTick); _timer.Interval = new TimeSpan(0, 0, 0, 0, 50); // 50 ms _timer.Start();. private void OnTimerTick(Object sender, EventArgs e) { // TODO: Modify scene }
CompositionTarget.Rendering CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);. private void CompositionTarget_Rendering(Object sender, EventArgs e) { // TODO: Modify the scene. Changes will be rendered once // the event handler returns. }
demo Manual Animations
Speeds rendering by leveraging GPU –GPU present in every Windows phone –Dedicated composition thread renders to GPU Transforms and projections driven by "simple" animations are automatically GPU-cached –DoubleAnimation[UsingKeyFrames] CacheMode="BitmapCache" caches elements that aren't auto-cached –Objects with OpacityMask or non-rectangular clipping regions cannot be GPU-cached GPU Acceleration
GPU-Caching a Canvas. XAMLBitmap
Provides key rendering performance data – – Red counters flag potential perf problems Frame-Rate Counter
if (System.Diagnostics.Debugger.IsAttached) { // Display the current frame rate counters. Application.Current.Host.Settings.EnableFrameRateCounter = true;... // Enable non-production analysis visualization mode, // which shows areas of a page that are being GPU accelerated // with a colored overlay. Application.Current.Host.Settings.EnableCacheVisualization = true; } Enabling the Frame-Rate Counter
Visually depicts which objects are GPU-cached Cache Visualization Non-GPU-CachedGPU-CachedVisualization Off
if (System.Diagnostics.Debugger.IsAttached) { // Display the current frame rate counters. Application.Current.Host.Settings.EnableFrameRateCounter = true;... // Enable non-production analysis visualization mode, // which shows areas of a page that are being GPU accelerated // with a colored overlay. Application.Current.Host.Settings.EnableCacheVisualization = true; } Enabling Cache Visualization
demo GPU Acceleration
Charles Petzold Questions?