--- title: "Custom Rendering Ink" ms.date: "03/30/2017" dev_langs: - "csharp" - "vb" helpviewer_keywords: - "custom-rendering ink" - "ink [WPF], custom-rendering" - "classes [WPF], InkCanvas" ms.assetid: 65c978a7-0ee0-454f-ac7f-b1bd2efecac5 --- # Custom Rendering Ink The 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 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 Windows Presentation Foundation (WPF) allows you to custom render ink by implementing a custom and object. This topic contains the following subsections: - [Architecture](#Architecture) - [Implementing a Dynamic Renderer](#ImplementingADynamicRenderer) - [Implementing Custom Strokes](#ImplementingCustomStrokes) - [Implementing a Custom InkCanvas](#ImplementingACustomInkCanvas) - [Conclusion](#Conclusion) ## 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 renders the ink when the user moves the tablet pen on the digitizer, and the 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 . This class is a specialized that renders the stroke as it is drawn. The 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](the-ink-threading-model.md). To customize dynamically rendering a stroke, override the method. 2. **Stroke**: Implement a class that derives from . This class is responsible for static rendering of the data after it has been converted into a object. Override the method to ensure that static rendering of the stroke is consistent with dynamic rendering. 3. **InkCanvas:** Implement a class that derives from . Assign the customized to the property. Override the method and add a custom stroke to the property. This ensures that the appearance of the ink is consistent. ## Implementing a Dynamic Renderer Although the class is a standard part of WPF, to perform more specialized rendering, you must create a customized dynamic renderer that derives from the and override the method. The following example demonstrates a customized that draws ink with a linear gradient brush effect. [!code-csharp[AdvancedInkTopicsSamples#19](~/samples/snippets/csharp/VS_Snippets_Wpf/AdvancedInkTopicsSamples/CSharp/DynamicRenderer.cs#19)] [!code-vb[AdvancedInkTopicsSamples#19](~/samples/snippets/visualbasic/VS_Snippets_Wpf/AdvancedInkTopicsSamples/VisualBasic/DynamicRenderer.vb#19)] [!code-csharp[AdvancedInkTopicsSamples#1](~/samples/snippets/csharp/VS_Snippets_Wpf/AdvancedInkTopicsSamples/CSharp/DynamicRenderer.cs#1)] [!code-vb[AdvancedInkTopicsSamples#1](~/samples/snippets/visualbasic/VS_Snippets_Wpf/AdvancedInkTopicsSamples/VisualBasic/DynamicRenderer.vb#1)] ## Implementing Custom Strokes Implement a class that derives from . This class is responsible for rendering data after it has been converted into a object. Override the class to do the actual drawing. Your Stroke class can also store custom data by using the method. This data is stored with the stroke data when persisted. The class can also perform hit testing. You can also implement your own hit testing algorithm by overriding the method in the current class. The following C# code demonstrates a custom class that renders data as a 3D stroke. [!code-csharp[AdvancedInkTopicsSamples#19](~/samples/snippets/csharp/VS_Snippets_Wpf/AdvancedInkTopicsSamples/CSharp/DynamicRenderer.cs#19)] [!code-vb[AdvancedInkTopicsSamples#19](~/samples/snippets/visualbasic/VS_Snippets_Wpf/AdvancedInkTopicsSamples/VisualBasic/DynamicRenderer.vb#19)] [!code-csharp[AdvancedInkTopicsSamples#2](~/samples/snippets/csharp/VS_Snippets_Wpf/AdvancedInkTopicsSamples/CSharp/DynamicRenderer.cs#2)] [!code-vb[AdvancedInkTopicsSamples#2](~/samples/snippets/visualbasic/VS_Snippets_Wpf/AdvancedInkTopicsSamples/VisualBasic/DynamicRenderer.vb#2)] ## Implementing a Custom InkCanvas The easiest way to use your customized and stroke is to implement a class that derives from and uses these classes. The has a property that specifies how the stroke is rendered when the user is drawing it. To custom render strokes on an do the following: - Create a class that derives from the . - Assign your customized to the property. - Override the method. In this method, remove the original stroke that was added to the InkCanvas. Then create a custom stroke, add it to the property, and call the base class with a new that contains the custom stroke. The following C# code demonstrates a custom class that uses a customized and collects custom strokes. [!code-csharp[AdvancedInkTopicsSamples#9](~/samples/snippets/csharp/VS_Snippets_Wpf/AdvancedInkTopicsSamples/CSharp/Window1.xaml.cs#9)] An can have more than one . You can add multiple objects to the by adding them to the property. ## Conclusion You can customize the appearance of ink by deriving your own , , and 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](advanced-ink-handling.md)