mirror of
https://github.com/Stone-Red-Code/docs-desktop.git
synced 2026-09-04 09:06:04 +02:00
* net-current-v30plus-md.md * net-current-v40plus-md.md * tla2sharptla-ui-md.md * tla2sharptla-uiautomation-md.md * tla2sharptla-winclient-md.md * tla2sharptla-xaml-md.md * tlasharptla-ui-md.md * tlasharptla-uiautomation-md.md * tlasharptla-winclient-md.md * tlasharptla-xaml-md.md * fix warnings
91 lines
8.3 KiB
Markdown
91 lines
8.3 KiB
Markdown
---
|
|
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 <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 Windows Presentation Foundation (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](#Architecture)
|
|
|
|
- [Implementing a Dynamic Renderer](#ImplementingADynamicRenderer)
|
|
|
|
- [Implementing Custom Strokes](#ImplementingCustomStrokes)
|
|
|
|
- [Implementing a Custom InkCanvas](#ImplementingACustomInkCanvas)
|
|
|
|
- [Conclusion](#Conclusion)
|
|
|
|
<a name="Architecture"></a>
|
|
## 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](the-ink-threading-model.md). 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.
|
|
|
|
<a name="ImplementingADynamicRenderer"></a>
|
|
## Implementing a Dynamic Renderer
|
|
Although the <xref:System.Windows.Input.StylusPlugIns.DynamicRenderer> class is a standard part of WPF, 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-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)]
|
|
|
|
<a name="ImplementingCustomStrokes"></a>
|
|
## 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 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)]
|
|
|
|
<a name="ImplementingACustomInkCanvas"></a>
|
|
## 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-csharp[AdvancedInkTopicsSamples#9](~/samples/snippets/csharp/VS_Snippets_Wpf/AdvancedInkTopicsSamples/CSharp/Window1.xaml.cs#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.
|
|
|
|
<a name="Conclusion"></a>
|
|
## 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](advanced-ink-handling.md)
|