首页 > 解决方案 > 如何使 UWP TextBlock 可通过手写进行编辑?

问题描述

我目前正在展示一个TextBlock用户可以使用游戏手柄、鼠标和键盘以各种方式操作的带有文本的文本。

我希望用户能够在上面写文字TextBlock,然后文字将替换TextBlock.

该应用程序的工作原理如下:

<TextBlock x:Name="TheTextBlock" Text="Sample Text" />

而后面的代码是这样的:

private void Page_KeyDown(object sender, KeyEventArgs args)
{
    if (args.Key = VirtualKey.LeftButton)
        TheTextBlock.Text = "Left Button Pressed";
}

因此,当写一些东西时,即 anInkCanvas或 a<TextBox IsHandwritingViewEnabled="False" />文本应该出现在 the 中TextBlock,并且墨水应该消失。

你怎么能做到这一点?当笔压在画布上时会清除文本的顶部InkCanvasTextBlock一个看不见的手写文本框?

标签: c#xamluwphandwriting-recognitionhandwriting

解决方案


你怎么能做到这一点?TextBlock 顶部的 InkCanvas 会在将笔按在画布上时清除文本?一个看不见的手写文本框?

根据您的描述,您似乎想制作手写板来识别文本,然后将其显示在TextBlock. 请参考本文档。我已经制作了您可以参考的样本。

Xaml

<Grid>
    <TextBlock x:Name="TheTextBlock" Text="Sample Text"/>
    <InkCanvas x:Name="TheInkCanvas" />
</Grid>

代码背后

InkAnalyzer inkAnalyzer;
DispatcherTimer recoTimer;
public MainPage()
{
    this.InitializeComponent();
    TheInkCanvas.InkPresenter.InputDeviceTypes =
       Windows.UI.Core.CoreInputDeviceTypes.Mouse |
       Windows.UI.Core.CoreInputDeviceTypes.Pen;

    TheInkCanvas.InkPresenter.StrokesCollected += inkCanvas_StrokesCollected;
    // StrokeStarted is fired when ink input is first detected.
    TheInkCanvas.InkPresenter.StrokeInput.StrokeStarted +=
        inkCanvas_StrokeStarted;

    inkAnalyzer = new InkAnalyzer();

    // Timer to manage dynamic recognition.
    recoTimer = new DispatcherTimer();
    recoTimer.Interval = TimeSpan.FromSeconds(1);
    recoTimer.Tick += recoTimer_TickAsync;
}

private async void recoTimer_TickAsync(object sender, object e)
{
    recoTimer.Stop();
    if (!inkAnalyzer.IsAnalyzing)
    {
        InkAnalysisResult result = await inkAnalyzer.AnalyzeAsync();

        // Have ink strokes on the canvas changed?
        if (result.Status == InkAnalysisStatus.Updated)
        {
            // Find all strokes that are recognized as handwriting and 
            // create a corresponding ink analysis InkWord node.
            var inkwordNodes =
                inkAnalyzer.AnalysisRoot.FindNodes(
                    InkAnalysisNodeKind.InkWord);

            // Iterate through each InkWord node.
            // Display the primary recognized text (for this example, 
            // we ignore alternatives), and then delete the 
            // ink analysis data and recognized strokes.
            foreach (InkAnalysisInkWord node in inkwordNodes)
            {
                string recognizedText = node.RecognizedText;
                // Display the recognition candidates.
                TheTextBlock.Text = recognizedText;

                foreach (var strokeId in node.GetStrokeIds())
                {
                    var stroke =
                        TheInkCanvas.InkPresenter.StrokeContainer.GetStrokeById(strokeId);
                    stroke.Selected = true;
                }
                inkAnalyzer.RemoveDataForStrokes(node.GetStrokeIds());
            }
            TheInkCanvas.InkPresenter.StrokeContainer.DeleteSelected();
        }
    }
    else
    {
        // Ink analyzer is busy. Wait a while and try again.
        recoTimer.Start();
    }
}

private void inkCanvas_StrokeStarted(InkStrokeInput sender, PointerEventArgs args)
{
    recoTimer.Stop();
}

private void inkCanvas_StrokesCollected(InkPresenter sender, InkStrokesCollectedEventArgs args)
{
    recoTimer.Stop();
    foreach (var stroke in args.Strokes)
    {
        inkAnalyzer.AddDataForStroke(stroke);
        inkAnalyzer.SetStrokeDataKind(stroke.Id, InkAnalysisStrokeKind.Writing);
    }
    recoTimer.Start();
}

推荐阅读