Using Win2D without built-in controls |
CanvasControl, CanvasVirtualControl and CanvasAnimatedControl are XAML controls- they extend UserControl and can exist alongside other controls in an app's XAML tree. They are good choice for many WinRT apps that use XAML and produce graphical content using Win2D. While these controls are versatile, they do impose policies pertaining to layout, resource re-creation, and device lost. Apps may want to implement their own XAML controls, or not use XAML at all.
Win2D is built to support this. This document describes how to use Win2D to draw graphics without use of CanvasControl, CanvasVirtualControl or CanvasAnimatedControl.
The Win2D XAML controls are built of top of a low level Win2D type. Each control contains an instance of a lower-level type:
Control | Low-level type |
---|---|
CanvasControl | CanvasImageSource |
CanvasVirtualControl | CanvasVirtualImageSource |
CanvasAnimatedControl | CanvasSwapChainPanel and CanvasSwapChain |
The controls consume only the public interfaces of these lower-level types. This implementation detail lends some confidence that apps can implement their own XAML controls which are equivalently as powerful as the built-in Win2D controls.
An application is free to bypass the provided Win2D XAML controls and use the lower-level types directly. This section provides some guidance on choosing the appropriate lower-level type.
If there is existing C++ code that works with IDXGISwapChain then C++ interop can be used to wrap this with a CanvasSwapChain. CanvasSwapChainPanel can be used to display a CanvasSwapChain in a XAML app.
If the app needs to add graphics to a XAML element which expects an ImageSource, it should use CanvasImageSource or CanvasVirtualImageSource.
Aside from that, it's worth considering:
CanvasSwapChain wraps a Direct3D swap chain. CanvasSwapChain is not a XAML type, but the fact that it has a swap chain means it has a built-in mechanism for being displayed. That said, CoreWindow apps may use CanvasSwapChain for displaying graphical content.
To create a CanvasSwapChain for use with a CoreWindow, in C#:
float currentDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
SwapChain = CanvasSwapChain.CreateForCoreWindow(device, window, currentDpi);
using (CanvasDrawingSession ds = swapChain.CreateDrawingSession(Colors.Black)) { ds.FillRectangle(100, 200, 3, 5); } swapChain.Present();
The size of the swap chain should match the size of the CoreWindow. If the size of the window changes, call ResizeBuffers(Size) on the swap chain with the new size. For more information, see the CoreWindow Win2D sample.
CanvasSwapChainPanel is a XAML type, and a relatively thin wrapper around CanvasSwapChain. It is suitable for XAML apps that require swap chain rendering, but do not want to use the policies that exist in CanvasAnimatedControl. To create a swap chain in XAML, use the namespace:
xmlns:canvas="using:Microsoft.Graphics.Canvas.UI.Xaml"
<canvas:CanvasSwapChainPanel x:Name="canvasSwapChainPanel"/>
CanvasDevice device = CanvasDevice.GetSharedDevice(); CanvasSwapChain swapChain = new CanvasSwapChain(device, width, height, 96); canvasSwapChainPanel.SwapChain = swapChain;
using (CanvasDrawingSession ds = canvasSwapChainPanel.SwapChain.CreateDrawingSession(Colors.Black)) { ds.FillRectangle(200, 300, 5, 6, Colors.Blue); } canvasSwapChainPanel.SwapChain.Present();
canvasSwapChainPanel.SizeChanged += canvasSwapChainPanel_SizeChanged; void canvasSwapChainPanel_SizeChanged(object sender, Windows.UI.Xaml.SizeChangedEventArgs e) { canvasSwapChainPanel.SwapChain.ResizeBuffers(e.NewSize); }
CanvasImageSource and CanvasVirtualImageSource provide a way of integrating Win2D graphical content with XAML. They are suitable for content which does not require swap chain rendering.
CanvasImageSource extends XAML's SurfaceImageSource. Apps can create an instance of CanvasImageSource, and reference it from a XAML type that consumes an ImageSource, such as an Image or ImageBrush. For example, in XAML markup:
<Image x:Name="image"/>
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasImageSource imageSource = new CanvasImageSource(device, width, height);
image.Source = imageSource;
using (CanvasDrawingSession ds = imageSource.CreateDrawingSession(Colors.Black)) { ds.FillRectangle(200, 300, 5, 6, Colors.Blue); }
For an example demonstrating how to use CanvasImageSource, see the ImageSourceUpdateRegion Win2D ExampleGallery page.
CanvasVirtualImageSource wraps XAML's VirtualSurfaceImageSource.
The wrapped VirtualSurfaceImageSource can be obtained by the Source property. Apart from this difference it can be used in much the same way as CanvasImageSource:
<Image x:Name="image"/>
var virtualImageSource = new CanvasVirtualImageSource(device, width, height); image.Source = virtualImageSource.Source;
CanvasRenderTarget represents a drawable bitmap, and does not have any built-in association with XAML. It is suitable for XAML or non-XAML apps which need to use an intermediate bitmap- for example, for saving image data to a file, reading back pixel data, or to be used as an intermediate for another operation.
CanvasRenderTarget doesn't have an automatic mechanism to cause it to be displayed. To display the content of a CanvasRenderTarget in your app, draw it in the drawing session created from a displayed control, image source, or swap chain.
For more information about using CanvasRenderTarget, see Offscreen drawing.