收集墨迹

更新:2007 年 11 月

Windows Presentation Foundation 平台将收集数字墨迹作为其核心功能。本主题讨论在 Windows Presentation Foundation (WPF) 中收集墨迹的方法。

先决条件

若要使用下面的示例,首先必须安装 Microsoft Visual Studio 2005 和 Windows SDK。还应了解如何编写 WPF 应用程序。有关 WPF 入门的更多信息,请参见 Windows Presentation Foundation 入门

使用 InkCanvas 元素

InkCanvas 元素提供了在 WPF 中收集墨迹的最简单方式。InkCanvas 元素类似于 Tablet PC SDK 1.7 及早期版本中的 InkOverlay 对象。

使用 InkCanvas 元素可接收和显示墨迹输入。通常使用手写笔(与数字化仪交互产生墨迹笔画)输入墨迹。此外,还可以使用鼠标代替手写笔。创建的笔画表示为 Stroke 对象,它们可以通过编程方式和用户输入方式进行操作。InkCanvas 允许用户选择、修改或删除现有的 Stroke

通过使用 XAML,可以像将 InkCanvas 元素添加到树中一样轻松地设置墨迹收集。下面的示例将 InkCanvas 添加到在 Microsoft Visual Studio 2005 中创建的默认 WPF 项目。

<Grid>
  <InkCanvas/>
</Grid>

InkCanvas 元素也可以包含子元素,这样便可以将墨迹批注功能添加到几乎所有类型的 XAML 元素。例如,若要将墨迹功能添加到文本元素,只需使其成为 InkCanvas 的子元素即可。

<InkCanvas>
  <TextBlock>Show text here.</TextBlock>
</InkCanvas>

可轻松添加对使用墨迹标记图像的支持。

<InkCanvas>
  <Image Source="myPicture.jpg"/>
</InkCanvas>

InkCollection 模式

InkCanvas 通过其 EditingMode 属性对各种输入模式提供支持。

操作墨迹

InkCanvas 对多种墨迹编辑操作提供支持。例如,InkCanvas 支持笔清除功能,不需要其他代码来将该功能添加到该元素。

选择

设置选择模式与将 InkCanvasEditingMode 属性设置为 Select 一样容易。下面的代码根据 CheckBox 的值来设置编辑模式。

' Set the selection mode based on a checkbox
If CBool(cbSelectionMode.IsChecked) Then
    theInkCanvas.EditingMode = InkCanvasEditingMode.Select
Else
    theInkCanvas.EditingMode = InkCanvasEditingMode.Ink
End If
// Set the selection mode based on a checkbox
if ((bool)cbSelectionMode.IsChecked)
{
    theInkCanvas.EditingMode = InkCanvasEditingMode.Select;
}
else
{
    theInkCanvas.EditingMode = InkCanvasEditingMode.Ink;
}

DrawingAttributes

使用 DrawingAttributes 属性可更改墨迹笔画的外观。例如,DrawingAttributesColor 成员可设置呈现的 Stroke 的颜色。下面的示例将所选笔画的颜色更改为红色。

' Get the selected strokes from the InkCanvas
Dim selection As StrokeCollection = theInkCanvas.GetSelectedStrokes()

' Check to see if any strokes are actually selected
If selection.Count > 0 Then
    ' Change the color of each stroke in the collection to red
    Dim stroke As System.Windows.Ink.Stroke
    For Each stroke In  selection
        stroke.DrawingAttributes.Color = System.Windows.Media.Colors.Red
    Next stroke
End If
// Get the selected strokes from the InkCanvas
StrokeCollection selection = theInkCanvas.GetSelectedStrokes();

// Check to see if any strokes are actually selected
if (selection.Count > 0)
{
    // Change the color of each stroke in the collection to red
    foreach (System.Windows.Ink.Stroke stroke in selection)
    {
        stroke.DrawingAttributes.Color = System.Windows.Media.Colors.Red;
    }
}

DefaultDrawingAttributes

DefaultDrawingAttributes 属性可提供对在 InkCanvas 中创建的笔画的高度、宽度和颜色等属性的访问。一旦更改 DefaultDrawingAttributes,则以后输入 InkCanvas 中的所有笔画都将使用新的属性值呈现。

除了在代码隐藏文件中修改 DefaultDrawingAttributes 外,还可以使用 XAML 语法指定 DefaultDrawingAttributes 属性。下面的 XAML 代码演示如何设置 Color 属性。若要使用此代码,请在 Visual Studio 2005 中创建名为“HelloInkCanvas”的新 WPF 项目。使用下面的代码替换 Window1.xaml 文件中的代码。

<Window x:Class="Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Ink="clr-namespace:System.Windows.Ink;assembly=PresentationCore"
    Title="Hello, InkCanvas!" Height="300" Width="300"
    >
  <Grid>
    <InkCanvas Name="inkCanvas1" Background="Ivory">
      <InkCanvas.DefaultDrawingAttributes>
        <Ink:DrawingAttributes xmlns:ink="system-windows-ink" Color="Red" Width="5" />
      </InkCanvas.DefaultDrawingAttributes>

    </InkCanvas>

    <!-- This stack panel of buttons is a sibling to InkCanvas (not a child) but overlapping it, 
         higher in z-order, so that ink is collected and rendered behind -->
    <StackPanel Name="buttonBar" VerticalAlignment="Top" Height="26" Orientation="Horizontal" Margin="5">
      <Button Click="Ink">Ink</Button>
      <Button Click="Highlight">Highlight</Button>
      <Button Click="EraseStroke">EraseStroke</Button>
      <Button Click="Select">Select</Button>
    </StackPanel>
  </Grid>
</Window>
<Window x:Class="HelloInkCanvas.Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Ink="clr-namespace:System.Windows.Ink;assembly=PresentationCore"
    Title="Hello, InkCanvas!" Height="300" Width="300"
    >
  <Grid>
    <InkCanvas Name="inkCanvas1" Background="Ivory">
      <InkCanvas.DefaultDrawingAttributes>
        <Ink:DrawingAttributes xmlns:ink="system-windows-ink" Color="Red" Width="5" />
      </InkCanvas.DefaultDrawingAttributes>
    </InkCanvas>

    <!-- This stack panel of buttons is a sibling to InkCanvas (not a child) but overlapping it, 
         higher in z-order, so that ink is collected and rendered behind -->
    <StackPanel Name="buttonBar" VerticalAlignment="Top" Height="26" Orientation="Horizontal" Margin="5">
      <Button Click="Ink">Ink</Button>
      <Button Click="Highlight">Highlight</Button>
      <Button Click="EraseStroke">EraseStroke</Button>
      <Button Click="Select">Select</Button>
    </StackPanel>
  </Grid>
</Window>

然后,将以下按钮事件处理程序添加到 Window1 类中的代码隐藏文件。

' Set the EditingMode to ink input.
Private Sub Ink(ByVal sender As Object, ByVal e As RoutedEventArgs) 

    inkCanvas1.EditingMode = InkCanvasEditingMode.Ink

    ' Set the DefaultDrawingAttributes for a red pen.
    inkCanvas1.DefaultDrawingAttributes.Color = Colors.Red
    inkCanvas1.DefaultDrawingAttributes.IsHighlighter = False
    inkCanvas1.DefaultDrawingAttributes.Height = 2

End Sub 'Ink

' Set the EditingMode to highlighter input.
Private Sub Highlight(ByVal sender As Object, ByVal e As RoutedEventArgs) 

    inkCanvas1.EditingMode = InkCanvasEditingMode.Ink

    ' Set the DefaultDrawingAttributes for a highlighter pen.
    inkCanvas1.DefaultDrawingAttributes.Color = Colors.Yellow
    inkCanvas1.DefaultDrawingAttributes.IsHighlighter = True
    inkCanvas1.DefaultDrawingAttributes.Height = 25

End Sub 'Highlight


' Set the EditingMode to erase by stroke.
Private Sub EraseStroke(ByVal sender As Object, ByVal e As RoutedEventArgs) 

    inkCanvas1.EditingMode = InkCanvasEditingMode.EraseByStroke

End Sub 'EraseStroke

' Set the EditingMode to selection.
Private Sub [Select](ByVal sender As Object, ByVal e As RoutedEventArgs) 

    inkCanvas1.EditingMode = InkCanvasEditingMode.Select

End Sub 'Select
// Set the EditingMode to ink input.
private void Ink(object sender, RoutedEventArgs e)
{
    inkCanvas1.EditingMode = InkCanvasEditingMode.Ink;

    // Set the DefaultDrawingAttributes for a red pen.
    inkCanvas1.DefaultDrawingAttributes.Color = Colors.Red;
    inkCanvas1.DefaultDrawingAttributes.IsHighlighter = false;
    inkCanvas1.DefaultDrawingAttributes.Height = 2;
}

// Set the EditingMode to highlighter input.
private void Highlight(object sender, RoutedEventArgs e)
{
    inkCanvas1.EditingMode = InkCanvasEditingMode.Ink;

    // Set the DefaultDrawingAttributes for a highlighter pen.
    inkCanvas1.DefaultDrawingAttributes.Color = Colors.Yellow;
    inkCanvas1.DefaultDrawingAttributes.IsHighlighter = true;
    inkCanvas1.DefaultDrawingAttributes.Height = 25;
}

// Set the EditingMode to erase by stroke.
private void EraseStroke(object sender, RoutedEventArgs e)
{
    inkCanvas1.EditingMode = InkCanvasEditingMode.EraseByStroke;
}

// Set the EditingMode to selection.
private void Select(object sender, RoutedEventArgs e)
{
    inkCanvas1.EditingMode = InkCanvasEditingMode.Select;
}

复制此代码后,在 Microsoft Visual Studio 2005 中按“F5”,在调试器中运行该程序。

请注意 StackPanel 是如何将按钮放在 InkCanvas 顶部的。如果尝试收集这些按钮顶部的墨迹,那么 InkCanvas 将收集并呈现按钮后面的墨迹。这是因为这些按钮是 InkCanvas 的同级,而不是子级。此外,这些按钮的 Z 顺序较高,所以墨迹呈现在其后面。

请参见

参考

DrawingAttributes

DefaultDrawingAttributes()

System.Windows.Ink