Ink Overview

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Ink refers to handwriting or drawing content that has been input with a stylus, a mouse, or by touch. There are various uses for ink in your Silverlight-based applications.

This topic contains the following sections.

  • Common Ink Scenarios
  • Supported Ink Input Devices
  • Getting Started with Ink in Silverlight
  • Related Topics

Common Ink Scenarios

Annotation

Ink annotation is a way to make Silverlight content more interactive and personal. Using the elements to implement ink annotation in Silverlight is both easy and flexible. Silverlight is one of the few Web technologies to support ink collection and the display of high-quality stylus input from Tablet PC devices.

Blogging

Blogs are personal. Adding ink to a blog gives it a unique, personal touch. You also extend what is possible in a blog when you add writing, drawing, and annotation over photos and videos.

Games

The use of ink in Silverlight opens up new scenarios for natural interaction in online game content. Silverlight makes the implementation of these scenarios straightforward. The flexibility of the input model enables great flexibility when you implement it in your gaming content.

Supported Ink Input Devices

Stylus Input

Computers with stylus (such as a Tablet PC or even a desktop computer that has an external digitizer) can take advantage of the full-fidelity stylus input in Silverlight. These devices allow ink input that you can integrate into your Silverlight-based applications to create high-quality handwriting, drawing, annotation, oil painting, and other content input with a stylus.

Touch Input

Silverlight supports touch-screen devices, such as those found in certain Tablet PC and Ultra-Mobile PC (UMPC) computers. Touch enables users to interact with Silverlight content in a natural way, when a keyboard or a stylus is cumbersome or unnecessary.

Mouse Input

You can use a mouse to draw ink in a Silverlight-based application. However, ink that is generated with the mouse has a lower resolution than stylus input that is gathered with a digitizer. You can use mouse-generated ink just like stylus-generated ink.

Getting Started with Ink in Silverlight

InkPresenter Element

The InkPresenter element provides a drawing surface to support ink features. InkPresenter derives from Canvas and can display one or more UIElement objects and a StrokeCollection.

The following code example shows how you can create an InkPresenter element in XAML.

<Canvas>
    <TextBlock Text="InkPresenter Control" FontWeight="Bold" Margin="50,30,0,0" />
    <Rectangle Height="500" Width="500" Margin="50,50,0,0" Stroke="Black" />
    <InkPresenter x:Name="MyIP" Height="500" Width="500"
              Margin="50,50,0,0"
              MouseLeftButtonDown="MyIP_MouseLeftButtonDown" 
              LostMouseCapture="MyIP_LostMouseCapture" 
              MouseMove="MyIP_MouseMove" 
              Background="Transparent" Opacity="1" />
</Canvas>

In the previous example, a Rectangle is added to the Canvas with the same margin as the InkPresenter element. This is because the InkPresenter does not have properties to provide visual boundaries. The Stroke property of the Rectangle is set to Black, which acts as the border for the InkPresenter. The z-order of the InkPresenter must be higher than that of the Rectangle Otherwise, the Rectangle will hide the InkPresenter.

To annotate photos with a stylus or a mouse, an Image and an InkPresenter are both added to a Canvas element. The following code example shows how you can annotate a photo.

<Canvas>
    <Image Source="flower.jpg" Stretch="Fill" Width="500" Height="500" />
    <InkPresenter x:Name="MyIP" Background="Transparent" Width="500" Height="500"
                  MouseLeftButtonDown="MyIP_MouseLeftButtonDown"
                  MouseMove="MyIP_MouseMove"
                  LostMouseCapture="MyIP_LostMouseCapture">

    </InkPresenter>

</Canvas>

Ink Data

Ink in Silverlight is a StrokeCollection object, which contains individual Stroke objects. Each Stroke corresponds to a stylus-down, stylus-move, and stylus-up sequence. A Stroke can be a dot, a straight line, or a curving line. Each Stroke contains a StylusPointCollection object, which contains individual StylusPoint objects. StylusPoint objects are collected when the stylus moves while it is in contact with the digitizer. The Stroke also has characteristics, such as height, width, color, and outline color, all of which are contained in the DrawingAttributes class.

Collecting Ink

You can create or capture strokes programmatically by responding to the events on the InkPresenter. The typical events for doing this are MouseLeftButtonDown, MouseMove and LostMouseCapture.

NoteNote:

Use the mouse events to detect actions by a stylus device. MouseLeftButtonDown, MouseMove, and LostMouseCapture events correspond to stylus-down, stylus-move, and stylus-up actions respectively.

The following code example shows how you can collect and display stroke data on the InkPresenter.

Public Sub New()
    MyBase.New()
    InitializeComponent()
    SetBoundary()
End Sub

'A new stroke object, MyStroke, is created and is added to the StrokeCollection object
'of the InkPresenter, MyIP
Private Sub MyIP_MouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseEventArgs)
    MyIP.CaptureMouse()
    Dim MyStylusPointCollection As StylusPointCollection = New StylusPointCollection
    MyStylusPointCollection.Add(e.StylusDevice.GetStylusPoints(MyIP))
    NewStroke = New Stroke(MyStylusPointCollection)
    MyIP.Strokes.Add(NewStroke)
End Sub

'StylusPoint objects are collected from the MouseEventArgs and added to MyStroke. 
Private Sub MyIP_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
    If (Not (NewStroke) Is Nothing) Then
        NewStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(MyIP))
    End If
End Sub

'MyStroke is completed
Private Sub MyIP_LostMouseCapture(ByVal sender As Object, ByVal e As MouseEventArgs)
    NewStroke = Nothing
End Sub

'Set the Clip property of the inkpresenter so that the strokes
'are contained within the boundary of the inkpresenter
Private Sub SetBoundary()
    Dim MyRectangleGeometry As RectangleGeometry = New RectangleGeometry
    MyRectangleGeometry.Rect = New Rect(0, 0, MyIP.ActualWidth, MyIP.ActualHeight)
    MyIP.Clip = MyRectangleGeometry
End Sub
public Page()
{
    InitializeComponent();
    SetBoundary();
}
Stroke NewStroke;

//A new stroke object named MyStroke is created. MyStroke is added to the StrokeCollection of the InkPresenter named MyIP
private void MyIP_MouseLeftButtonDown(object sender, MouseEventArgs e)
{
    MyIP.CaptureMouse();
    StylusPointCollection MyStylusPointCollection = new StylusPointCollection();
    MyStylusPointCollection.Add(e.StylusDevice.GetStylusPoints(MyIP));
    NewStroke = new Stroke(MyStylusPointCollection);
    MyIP.Strokes.Add(NewStroke);
}

//StylusPoint objects are collected from the MouseEventArgs and added to MyStroke. 
private void MyIP_MouseMove(object sender, MouseEventArgs e)
{
    if (NewStroke != null)
        NewStroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(MyIP));
}

//MyStroke is completed
private void MyIP_LostMouseCapture(object sender, MouseEventArgs e)
{
    NewStroke = null;

}

//Set the Clip property of the inkpresenter so that the strokes
//are contained within the boundary of the inkpresenter
private void SetBoundary()
{
    RectangleGeometry MyRectangleGeometry = new RectangleGeometry();
    MyRectangleGeometry.Rect = new Rect(0, 0, MyIP.ActualWidth, MyIP.ActualHeight);
    MyIP.Clip = MyRectangleGeometry;
}

In the previous example, when the InkPresenter element receives a MouseLeftButtonDown event, a new Stroke object is created and added to the StrokeCollection object of the InkPresenter element. When the stylus moves while in contact with the screen, the MouseMove event is called and StylusPoint objects are collected and added to that Stroke. When the LostMouseCapture event is raised, the Stroke created is completed.

Run this sample

See Also

Reference

Concepts