Permalink
Fetching contributors…
Cannot retrieve contributors at this time
104 lines (74 sloc) 8.92 KB
title ms.custom ms.date ms.prod ms.reviewer ms.suite ms.technology ms.tgt_pltfrm ms.topic helpviewer_keywords ms.assetid caps.latest.revision author ms.author manager
Custom Rendering Ink
03/30/2017
.net-framework
dotnet-wpf
article
custom-rendering ink
classes, Stroke
classes, DynamicRenderer
ink, custom-rendering
InkCanvas class
Stroke class
DynamicRenderer class
classes, InkCanvas
65c978a7-0ee0-454f-ac7f-b1bd2efecac5
10
dotnet-bot
dotnetcontent
wpickett

Custom Rendering Ink

The xref:System.Windows.Ink.Stroke.DrawingAttributes%2A property of a stroke allows you to specify the appearance of a stroke, such as its size, color, and shape, but there may be times that you want to customize the appearance beyond what xref:System.Windows.Ink.Stroke.DrawingAttributes%2A allow. You may want to customize the appearance of ink by rendering in the appearance of an air brush, oil paint, and many other effects. The [!INCLUDETLA#tla_wpf] allows you to custom render ink by implementing a custom xref:System.Windows.Input.StylusPlugIns.DynamicRenderer and xref:System.Windows.Ink.Stroke object.

This topic contains the following subsections:

Architecture

Ink rendering occurs two times; when a user writes ink to an inking surface, and again after the stroke is added to the ink-enabled surface. The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer renders the ink when the user moves the tablet pen on the digitizer, and the xref:System.Windows.Ink.Stroke renders itself once it is added to an element.

There are three classes to implement when dynamically rendering ink.

  1. DynamicRenderer: Implement a class that derives from xref:System.Windows.Input.StylusPlugIns.DynamicRenderer. This class is a specialized xref:System.Windows.Input.StylusPlugIns.StylusPlugIn that renders the stroke as it is drawn. The xref:System.Windows.Input.StylusPlugIns.DynamicRenderer does the rendering on a separate thread, so the inking surface appears to collect ink even when the application user interface (UI) thread is blocked. For more information about the threading model, see The Ink Threading Model. To customize dynamically rendering a stroke, override the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer.OnDraw%2A method.

  2. Stroke: Implement a class that derives from xref:System.Windows.Ink.Stroke. This class is responsible for static rendering of the xref:System.Windows.Input.StylusPoint data after it has been converted into a xref:System.Windows.Ink.Stroke object. Override the xref:System.Windows.Ink.Stroke.DrawCore%2A method to ensure that static rendering of the stroke is consistent with dynamic rendering.

  3. InkCanvas: Implement a class that derives from xref:System.Windows.Controls.InkCanvas. Assign the customized xref:System.Windows.Input.StylusPlugIns.DynamicRenderer to the xref:System.Windows.Controls.InkCanvas.DynamicRenderer%2A property. Override the xref:System.Windows.Controls.InkCanvas.OnStrokeCollected%2A method and add a custom stroke to the xref:System.Windows.Controls.InkCanvas.Strokes%2A property. This ensures that the appearance of the ink is consistent.

Implementing a Dynamic Renderer

Although the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer class is a standard part of [!INCLUDETLA2#tla_winclient], to perform more specialized rendering, you must create a customized dynamic renderer that derives from the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer and override the xref:System.Windows.Input.StylusPlugIns.DynamicRenderer.OnDraw%2A method.

The following example demonstrates a customized xref:System.Windows.Input.StylusPlugIns.DynamicRenderer that draws ink with a linear gradient brush effect.

[!code-csharpAdvancedInkTopicsSamples#19] [!code-vbAdvancedInkTopicsSamples#19]
[!code-csharpAdvancedInkTopicsSamples#1] [!code-vbAdvancedInkTopicsSamples#1]

Implementing Custom Strokes

Implement a class that derives from xref:System.Windows.Ink.Stroke. This class is responsible for rendering xref:System.Windows.Input.StylusPoint data after it has been converted into a xref:System.Windows.Ink.Stroke object. Override the xref:System.Windows.Ink.Stroke.DrawCore%2A class to do the actual drawing.

Your Stroke class can also store custom data by using the xref:System.Windows.Ink.Stroke.AddPropertyData%2A method. This data is stored with the stroke data when persisted.

The xref:System.Windows.Ink.Stroke class can also perform hit testing. You can also implement your own hit testing algorithm by overriding the xref:System.Windows.Ink.Stroke.HitTest%2A method in the current class.

The following C# code demonstrates a custom xref:System.Windows.Ink.Stroke class that renders xref:System.Windows.Input.StylusPoint data as a 3-D stroke.

[!code-csharpAdvancedInkTopicsSamples#19] [!code-vbAdvancedInkTopicsSamples#19]
[!code-csharpAdvancedInkTopicsSamples#2] [!code-vbAdvancedInkTopicsSamples#2]

Implementing a Custom InkCanvas

The easiest way to use your customized xref:System.Windows.Input.StylusPlugIns.DynamicRenderer and stroke is to implement a class that derives from xref:System.Windows.Controls.InkCanvas and uses these classes. The xref:System.Windows.Controls.InkCanvas has a xref:System.Windows.Controls.InkCanvas.DynamicRenderer%2A property that specifies how the stroke is rendered when the user is drawing it.

To custom render strokes on an xref:System.Windows.Controls.InkCanvas do the following:

  • Create a class that derives from the xref:System.Windows.Controls.InkCanvas.

  • Assign your customized xref:System.Windows.Input.StylusPlugIns.DynamicRenderer to the xref:System.Windows.Controls.InkCanvas.DynamicRenderer%2A?displayProperty=nameWithType property.

  • Override the xref:System.Windows.Controls.InkCanvas.OnStrokeCollected%2A method. In this method, remove the original stroke that was added to the InkCanvas. Then create a custom stroke, add it to the xref:System.Windows.Controls.InkCanvas.Strokes%2A property, and call the base class with a new xref:System.Windows.Controls.InkCanvasStrokeCollectedEventArgs that contains the custom stroke.

The following C# code demonstrates a custom xref:System.Windows.Controls.InkCanvas class that uses a customized xref:System.Windows.Input.StylusPlugIns.DynamicRenderer and collects custom strokes.

[!code-csharpAdvancedInkTopicsSamples#9]

An xref:System.Windows.Controls.InkCanvas can have more than one xref:System.Windows.Input.StylusPlugIns.DynamicRenderer. You can add multiple xref:System.Windows.Input.StylusPlugIns.DynamicRenderer objects to the xref:System.Windows.Controls.InkCanvas by adding them to the xref:System.Windows.UIElement.StylusPlugIns%2A property.

Conclusion

You can customize the appearance of ink by deriving your own xref:System.Windows.Input.StylusPlugIns.DynamicRenderer, xref:System.Windows.Ink.Stroke, and xref:System.Windows.Controls.InkCanvas classes. Together, these classes ensure that the appearance of the stroke is consistent when the user draws the stroke and after it is collected.

See Also

Advanced Ink Handling