Interazioni tramite penna e Windows Ink nelle app di WindowsPen interactions and Windows Ink in Windows apps

Immagine Hero della penna della superficie.Hero image of the Surface Pen.
Penna per Surface (disponibile per l'acquisto in Microsoft Store).Surface Pen (available for purchase at the Microsoft Store).

PanoramicaOverview

Ottimizza l'app Windows per l'input penna per fornire funzionalità del dispositivo puntatore standard e la migliore esperienza di Windows Ink per gli utenti.Optimize your Windows app for pen input to provide both standard pointer device functionality and the best Windows Ink experience for your users.

Nota

Questo argomento presenta la piattaforma Windows Ink.This topic focuses on the Windows Ink platform. Per la gestione dell'input del puntatore generale (simile a mouse, tocco e touchpad), vedi Gestire l'input del puntatore.For general pointer input handling (similar to mouse, touch, and touchpad), see Handle pointer input.

Uso dell'input penna nell'app di WindowsUsing ink in your Windows app

Usare la penna e Windows Ink per creare app aziendali più coinvolgentiUse Windows Pen and Ink to build more engaging enterprise apps

L'uso combinato della piattaforma Windows Ink e di un dispositivo di tipo penna permette di creare appunti digitali scritti a mano, disegni e annotazioni in modo naturale.The Windows Ink platform, together with a pen device, provides a natural way to create digital handwritten notes, drawings, and annotations. La piattaforma supporta l'acquisizione di dati di input penna dall'input del digitalizzatore, la generazione e la gestione di dati di input penna, il rendering dei dati di input penna come tratti input penna nel dispositivo di output e la conversione dell'input penna in testo attraverso il riconoscimento della grafia.The platform supports capturing digitizer input as ink data, generating ink data, managing ink data, rendering ink data as ink strokes on the output device, and converting ink to text through handwriting recognition.

Oltre ad acquisire la posizione di base e i movimenti della penna durante la scrittura o il disegno, la tua app può anche raccogliere informazioni sui livelli di pressione applicati durante l'esecuzione di un tratto.In addition to capturing the basic position and movement of the pen as the user writes or draws, your app can also track and collect the varying amounts of pressure used throughout a stroke. Questi dati, sommati alle impostazioni relative a forma della punta della penna, dimensioni, rotazione, colore dell'input penna e scopo, ad esempio semplice input penna, cancellazione, evidenziazione e selezione, ti consentono di offrire esperienze utente il più possibile simili al disegno su carta con una penna, una matita o un pennello.This information, along with settings for pen tip shape, size, and rotation, ink color, and purpose (plain ink, erasing, highlighting, and selecting), enables you to provide user experiences that closely resemble writing or drawing on paper with a pen, pencil, or brush.

Nota

La tua app può supportare anche l'input da altri dispositivi basati su puntatore, tra cui digitalizzatori a tocco e dispositivi mouse.Your app can also support ink input from other pointer-based devices, including touch digitizers and mouse devices. 

La piattaforma di input penna è molto flessibile.The ink platform is very flexible. È progettata per supportare vari livelli di funzionalità, in base alle tue esigenze.It is designed to support various levels of functionality, depending on your requirements.

Per le linee guida relative all'esperienza utente con Windows Ink, vedi l'articolo relativo ai controlli per l'input penna.For Windows Ink UX guidelines, see Inking controls.

Componenti della piattaforma Windows InkComponents of the Windows Ink platform

ComponenteComponent DescrizioneDescription
InkCanvasInkCanvas Un controllo di interfaccia utente della piattaforma in formato XAML che, per impostazione predefinita, riceve e visualizza tutto l'input proveniente da una penna come tratto input penna oppure tratto di cancellazione.A XAML UI platform control that, by default, receives and displays all input from a pen as either an ink stroke or an erase stroke.
Per altre informazioni su come usare InkCanvas, vedi Riconoscere i tratti input penna di Windows come testo e Archiviare e recuperare dati dei tratti di Windows Ink.For more information about how to use the InkCanvas, see Recognize Windows Ink strokes as text and Store and retrieve Windows Ink stroke data.
InkPresenterInkPresenter Oggetto code-behind, di cui è stata creata un'istanza insieme a un controllo InkCanvas (esposto tramite la proprietà InkCanvas. InkPresenter ).A code-behind object, instantiated along with an InkCanvas control (exposed through the InkCanvas.InkPresenter property). Questo oggetto fornisce tutte le funzionalità di input penna predefinite esposte da InkCanvas, oltre a un set completo di API per l'ulteriore personalizzazione.This object provides all default inking functionality exposed by the InkCanvas, along with a comprehensive set of APIs for additional customization and personalization.
Per altre informazioni su come usare InkPresenter, vedi Riconoscere i tratti input penna di Windows come testo e Archiviare e recuperare dati dei tratti di Windows Ink.For more information about how to use the InkPresenter, see Recognize Windows Ink strokes as text and Store and retrieve Windows Ink stroke data.
InkToolbarInkToolbar Controllo della piattaforma dell'interfaccia utente XAML contenente una raccolta di pulsanti personalizzabile ed estendibile che attiva le funzionalità correlate all'input penna in un InkCanvasassociato.A XAML UI platform control containing a customizable and extensible collection of buttons that activate ink-related features in an associated InkCanvas.
Per altre informazioni su come usare InkToolbar, vedere aggiungere un InkToolbar a un'app di Windows in app Inking.For more information about how to use the InkToolbar, see Add an InkToolbar to a Windows app inking app.
IInkD2DRendererIInkD2DRenderer Consente il rendering dei tratti di input penna nel contesto di periferica Direct2D designato di un'app di Windows universale, anziché il controllo InkCanvas predefinito.Enables the rendering of ink strokes onto the designated Direct2D device context of a Universal Windows app, instead of the default InkCanvas control. Questo permette la personalizzazione completa dell'esperienza di input penna.This enables full customization of the inking experience.
Per altre informazioni, vedi l'esempio di input penna complesso.For more information, see the Complex ink sample.

Input penna di base con InkCanvasBasic inking with InkCanvas

Per aggiungere la funzionalità di base di Inking, è sufficiente inserire un controllo della piattaforma InkCanvas UWP nella pagina appropriata nell'app.To add basic inking functionality, just place an InkCanvas UWP platform control on the appropriate page in your app.

Per impostazione predefinita, InkCanvas supporta input input penna solo da un oggetto Pen.By default, the InkCanvas supports ink input only from a pen. L'input viene reso come tratto input penna usando le impostazioni predefinite di colore e spessore (una penna a sfera nera con uno spessore di 2 pixel) oppure elaborato come un tratto di cancellazione (quando l'input proviene da una punta per cancellare o dalla punta della penna modificata con un pulsante di cancellazione).The input is either rendered as an ink stroke using default settings for color and thickness (a black ballpoint pen with a thickness of 2 pixels), or treated as a stroke eraser (when input is from an eraser tip or the pen tip modified with an erase button).

Nota

Se non è presente una punta per cancellare o un pulsante di cancellazione, InkCanvas può essere configurato per l'elaborazione dell'input della punta della penna come un tratto di cancellazione.If an eraser tip or button is not present, the InkCanvas can be configured to process input from the pen tip as an erase stroke.

In questo esempio, un InkCanvas sovrappone un'immagine di sfondo.In this example, an InkCanvas overlays a background image.

Nota

Un InkCanvas ha proprietà di altezza e larghezza predefinite pari a zero, a meno che non sia l'elemento figlio di un elemento che ridimensiona automaticamente gli elementi figlio, ad esempio i controlli StackPanel o Grid .An InkCanvas has default Height and Width properties of zero, unless it is the child of an element that automatically sizes its child elements, such as StackPanel or Grid controls.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
        <TextBlock x:Name="Header"
                   Text="Basic ink sample"
                   Style="{ThemeResource HeaderTextBlockStyle}"
                   Margin="10,0,0,0" />            
    </StackPanel>
    <Grid Grid.Row="1">
        <Image Source="Assets\StoreLogo.png" />
        <InkCanvas x:Name="inkCanvas" />
    </Grid>
</Grid>

Questa serie di immagini illustra il rendering dell'input penna da parte del controllo InkCanvas.This series of images shows how pen input is rendered by this InkCanvas control.

Screenshot degli InkCanvas vuoti con un'immagine di sfondo. Screenshot degli InkCanvas con tratti di input penna. Screenshot degli InkCanvas con un tratto cancellato.
InkCanvas vuoto con un'immagine di sfondo.The blank InkCanvas with a background image. InkCanvas con tratti di input penna.The InkCanvas with ink strokes. InkCanvas con un tratto cancellato. Tieni presente che la cancellazione opera su un intero tratto, non su una parte di esso.The InkCanvas with one stroke erased (note how erase operates on an entire stroke, not a portion).

La funzionalità Inking supportata dal controllo InkCanvas viene fornita da un oggetto code-behind denominato InkPresenter.The inking functionality supported by the InkCanvas control is provided by a code-behind object called the InkPresenter.

Per l'input di base, non è necessario preoccuparsi di InkPresenter.For basic inking, you don't have to concern yourself with the InkPresenter. Tuttavia, per personalizzare e configurare il comportamento di input penna nell'InkCanvas, devi accedere all'oggetto InkPresenter corrispondente.However, to customize and configure inking behavior on the InkCanvas, you must access its corresponding InkPresenter object.

Personalizzazione di base con InkPresenterBasic customization with InkPresenter

Con ogni controllo InkCanvas viene creata un'istanza di un oggetto InkPresenter.An InkPresenter object is instantiated with each InkCanvas control.

Nota

Non è possibile creare direttamente un'istanza di InkPresenter.The InkPresenter cannot be instantiated directly. Viene invece eseguito l'accesso tramite la proprietà InkPresenter di InkCanvas.Instead, it is accessed through the InkPresenter property of the InkCanvas. 

Oltre a fornire tutti i comportamenti predefiniti del controllo InkCanvas corrispondente, l'oggetto InkPresenter fornisce un set completo di API per la personalizzazione del tratto e una gestione più dettagliata dell'input penna (standard e modificato).Along with providing all default inking behaviors of its corresponding InkCanvas control, the InkPresenter provides a comprehensive set of APIs for additional stroke customization and finer-grained management of the pen input (standard and modified). Sono incluse le proprietà del tratto, i tipi di dispositivi di input supportati e il fatto che l'input venga elaborato dall'oggetto o passato all'app per l'elaborazione.This includes stroke properties, supported input device types, and whether input is processed by the object or passed to the app for processing.

Nota

L'input input penna standard (da penna o suggerimento/pulsante della gomma) non viene modificato con un'offerta hardware secondaria, ad esempio un pulsante della penna, un pulsante destro del mouse o un meccanismo simile.Standard ink input (from either pen tip or eraser tip/button) is not modified with a secondary hardware affordance, such as a pen barrel button, right mouse button, or similar mechanism.

Per impostazione predefinita, l'input penna è supportato solo per l'input penna.By default, ink is supported for pen input only. Qui viene configurato l'oggetto InkPresenter per interpretare i dati di input sia dalla penna che dal mouse come tratti di input penna.Here, we configure the InkPresenter to interpret input data from both pen and mouse as ink strokes. Impostiamo anche alcuni attributi iniziali per il tratto input penna usati per il rendering dei tratti nel controllo InkCanvas.We also set some initial ink stroke attributes used for rendering strokes to the InkCanvas.

Per abilitare il mouse e il tocco Inking, impostare la proprietà InputDeviceTypes dell'oggetto InkPresenter sulla combinazione di valori CoreInputDeviceTypes desiderati.To enable mouse and touch inking, set the InputDeviceTypes property of the InkPresenter to the combination of CoreInputDeviceTypes values that you want.

public MainPage()
{
    this.InitializeComponent();

    // Set supported inking device types.
    inkCanvas.InkPresenter.InputDeviceTypes =
        Windows.UI.Core.CoreInputDeviceTypes.Mouse |
        Windows.UI.Core.CoreInputDeviceTypes.Pen;

    // Set initial ink stroke attributes.
    InkDrawingAttributes drawingAttributes = new InkDrawingAttributes();
    drawingAttributes.Color = Windows.UI.Colors.Black;
    drawingAttributes.IgnorePressure = false;
    drawingAttributes.FitToCurve = true;
    inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
}

Gli attributi del tratto input penna si possono impostare in modo dinamico, per adattarli alle preferenze dell'utente o ai requisiti dell'app.Ink stroke attributes can be set dynamically to accommodate user preferences or app requirements.

Qui permettiamo all'utente di scegliere in un elenco di colori dell'input penna.Here, we let a user choose from a list of ink colors.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
        <TextBlock x:Name="Header"
                   Text="Basic ink customization sample"
                   VerticalAlignment="Center"
                   Style="{ThemeResource HeaderTextBlockStyle}"
                   Margin="10,0,0,0" />
        <TextBlock Text="Color:"
                   Style="{StaticResource SubheaderTextBlockStyle}"
                   VerticalAlignment="Center"
                   Margin="50,0,10,0"/>
        <ComboBox x:Name="PenColor"
                  VerticalAlignment="Center"
                  SelectedIndex="0"
                  SelectionChanged="OnPenColorChanged">
            <ComboBoxItem Content="Black"/>
            <ComboBoxItem Content="Red"/>
        </ComboBox>
    </StackPanel>
    <Grid Grid.Row="1">
        <Image Source="Assets\StoreLogo.png" />
        <InkCanvas x:Name="inkCanvas" />
    </Grid>
</Grid>

Gestiamo quindi le modifiche al colore selezionato e aggiorniamo gli attributi del tratto input penna di conseguenza.We then handle changes to the selected color and update the ink stroke attributes accordingly.

// Update ink stroke color for new strokes.
private void OnPenColorChanged(object sender, SelectionChangedEventArgs e)
{
    if (inkCanvas != null)
    {
        InkDrawingAttributes drawingAttributes =
            inkCanvas.InkPresenter.CopyDefaultDrawingAttributes();

        string value = ((ComboBoxItem)PenColor.SelectedItem).Content.ToString();

        switch (value)
        {
            case "Black":
                drawingAttributes.Color = Windows.UI.Colors.Black;
                break;
            case "Red":
                drawingAttributes.Color = Windows.UI.Colors.Red;
                break;
            default:
                drawingAttributes.Color = Windows.UI.Colors.Black;
                break;
        };

        inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
    }
}

Queste immagini mostrano il modo in cui l'input penna viene elaborato e personalizzato dall'InkPresenter.These images shows how pen input is processed and customized by the InkPresenter.

Screenshot che Mostra gli InkCanvas con tratti di inchiostro nero predefiniti. Screenshot degli InkCanvas con i tratti di input penna rossi selezionati dall'utente.
InkCanvas con tratti di input penna nero predefiniti.The InkCanvas with default black ink strokes. InkCanvas con tratti di input penna rossi selezionati dall'utente.The InkCanvas with user selected red ink strokes.  

Per fornire altre funzionalità oltre l'input penna e la cancellazione, ad esempio la selezione del tratto, la tua app deve identificare lo specifico input per InkPresenter da passare non elaborato per la gestione da parte dell'app.To provide functionality beyond inking and erasing, such as stroke selection, your app must identify specific input for the InkPresenter to pass through unprocessed for handling by your app.

Passaggio dell'input per l'elaborazione avanzataPass-through input for advanced processing

Per impostazione predefinita, InkPresenter elabora tutti gli input come un tratto di input penna o un tratto di cancellazione, incluso l'input modificato da un'offerta hardware secondaria, ad esempio un pulsante della penna, un pulsante destro del mouse o simile.By default, InkPresenter processes all input as either an ink stroke or an erase stroke, including input modified by a secondary hardware affordance such as a pen barrel button, a right mouse button, or similar. Tuttavia, gli utenti in genere prevedono funzionalità aggiuntive o un comportamento modificato con questi affordances secondari.However, users typically expect some additional functionality or modified behavior with these secondary affordances.

In alcuni casi, potrebbe anche essere necessario esporre funzionalità aggiuntive per le penne senza affordances secondarie (funzionalità non generalmente associate al suggerimento penna), altri tipi di dispositivi di input o un tipo di comportamento modificato in base a una selezione utente nell'interfaccia utente dell'app.In some cases, you might also need to expose additional functionality for pens without secondary affordances (functionality not usually associated with the pen tip), other input device types, or some type of modified behavior based on a user selection in your app's UI.

Per supportare questa operazione, è possibile configurare InkPresenter per lasciare un input specifico non elaborato.To support this, InkPresenter can be configured to leave specific input unprocessed. L'input non elaborato verrà quindi passato all'app per l'elaborazione.This unprocessed input is then passed through to your app for processing.

Esempio: usare un input non elaborato per implementare la selezione del trattoExample - Use unprocessed input to implement stroke selection

La piattaforma Windows Ink non fornisce il supporto incorporato per le azioni che richiedono input modificato, ad esempio la selezione del tratto.The Windows Ink platform does not provide built-in support for actions that require modified input, such as stroke selection. Per supportare funzionalità come questa, è necessario fornire una soluzione personalizzata nelle app.To support features like this, you must provide a custom solution in your apps.

L'esempio di codice seguente (tutto il codice è nei file MainPage. XAML e MainPage.xaml.cs) illustra come abilitare la selezione del tratto quando l'input viene modificato con un pulsante della penna (o con il pulsante destro del mouse).The following code example (all code is in the MainPage.xaml and MainPage.xaml.cs files) steps through how to enable stroke selection when input is modified with a pen barrel button (or right mouse button).

  1. Prima di tutto, configuriamo l'interfaccia utente in MainPage.xaml.First, we set up the UI in MainPage.xaml.

    Qui viene aggiunta un'area di disegno (sotto gli InkCanvas) per disegnare il tratto di selezione.Here, we add a canvas (below the InkCanvas) to draw the selection stroke. Usando un livello separato per disegnare il tratto di selezione, il controllo InkCanvas e il suo contenuto restano invariati.Using a separate layer to draw the selection stroke leaves the InkCanvas and its content untouched.

    Screenshot degli InkCanvas vuoti con un'area di disegno di selezione sottostante.

      <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
          <TextBlock x:Name="Header"
            Text="Advanced ink customization sample"
            VerticalAlignment="Center"
            Style="{ThemeResource HeaderTextBlockStyle}"
            Margin="10,0,0,0" />
        </StackPanel>
        <Grid Grid.Row="1">
          <!-- Canvas for displaying selection UI. -->
          <Canvas x:Name="selectionCanvas"/>
          <!-- Inking area -->
          <InkCanvas x:Name="inkCanvas"/>
        </Grid>
      </Grid>
    
  2. In MainPage.xaml.cs dichiariamo un paio di variabili globali per mantenere riferimenti ad aspetti dell'interfaccia utente di selezione.In MainPage.xaml.cs, we declare a couple of global variables for keeping references to aspects of the selection UI. In particolare, il tratto del Lazo di selezione e il rettangolo delimitatore che evidenzia i tratti selezionati.Specifically, the selection lasso stroke and the bounding rectangle that highlights the selected strokes.

      // Stroke selection tool.
      private Polyline lasso;
      // Stroke selection area.
      private Rect boundingRect;
    
  3. Si configura quindi l'oggetto InkPresenter per interpretare i dati di input sia dalla penna che dal mouse come tratti di input penna e impostare alcuni attributi iniziali del tratto di input penna utilizzati per il rendering dei tratti in InkCanvas.Next, we configure the InkPresenter to interpret input data from both pen and mouse as ink strokes, and set some initial ink stroke attributes used for rendering strokes to the InkCanvas.

    In particolare, si usa la proprietà InputProcessingConfiguration di InkPresenter per indicare che qualsiasi input modificato deve essere elaborato dall'app.Most importantly, we use the InputProcessingConfiguration property of the InkPresenter to indicate that any modified input should be processed by the app. L'input modificato si specifica assegnando a InputProcessingConfiguration.RightDragAction il valore InkInputRightDragAction.LeaveUnprocessed.Modified input is specified by assigning InputProcessingConfiguration.RightDragAction a value of InkInputRightDragAction.LeaveUnprocessed. Quando questo valore è impostato, InkPresenter passa alla classe InkUnprocessedInput , un set di eventi puntatore da gestire.When this value is set, the InkPresenter passes through to the InkUnprocessedInput class, a set of pointer events for you to handle.

    Si assegnano i listener per gli eventi PointerPressed, PointerMovede PointerReleased non elaborati passati tramite InkPresenter.We assign listeners for the unprocessed PointerPressed, PointerMoved, and PointerReleased events passed through by the InkPresenter. Tutte le funzionalità di selezione sono implementate nei gestori per questi eventi.All selection functionality is implemented in the handlers for these events.

    Infine, vengono assegnati i listener per gli eventi StrokeStarted e StrokesErased di InkPresenter.Finally, we assign listeners for the StrokeStarted and StrokesErased events of the InkPresenter. Usiamo i gestori per questi eventi per pulire l'interfaccia utente di selezione se viene iniziato un nuovo tratto o se un tratto esistente viene cancellato.We use the handlers for these events to clean up the selection UI if a new stroke is started or an existing stroke is erased.

    Screenshot dell'app di esempio Advance Ink Customization che Mostra gli InkCanvas con tratti di input penna predefiniti.

      public MainPage()
      {
        this.InitializeComponent();
    
        // Set supported inking device types.
        inkCanvas.InkPresenter.InputDeviceTypes =
          Windows.UI.Core.CoreInputDeviceTypes.Mouse |
          Windows.UI.Core.CoreInputDeviceTypes.Pen;
    
        // Set initial ink stroke attributes.
        InkDrawingAttributes drawingAttributes = new InkDrawingAttributes();
        drawingAttributes.Color = Windows.UI.Colors.Black;
        drawingAttributes.IgnorePressure = false;
        drawingAttributes.FitToCurve = true;
        inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
    
        // By default, the InkPresenter processes input modified by
        // a secondary affordance (pen barrel button, right mouse
        // button, or similar) as ink.
        // To pass through modified input to the app for custom processing
        // on the app UI thread instead of the background ink thread, set
        // InputProcessingConfiguration.RightDragAction to LeaveUnprocessed.
        inkCanvas.InkPresenter.InputProcessingConfiguration.RightDragAction =
            InkInputRightDragAction.LeaveUnprocessed;
    
        // Listen for unprocessed pointer events from modified input.
        // The input is used to provide selection functionality.
        inkCanvas.InkPresenter.UnprocessedInput.PointerPressed +=
            UnprocessedInput_PointerPressed;
        inkCanvas.InkPresenter.UnprocessedInput.PointerMoved +=
            UnprocessedInput_PointerMoved;
        inkCanvas.InkPresenter.UnprocessedInput.PointerReleased +=
            UnprocessedInput_PointerReleased;
    
        // Listen for new ink or erase strokes to clean up selection UI.
        inkCanvas.InkPresenter.StrokeInput.StrokeStarted +=
            StrokeInput_StrokeStarted;
        inkCanvas.InkPresenter.StrokesErased +=
            InkPresenter_StrokesErased;
      }
    
  4. Si definiscono quindi i gestori per gli eventi PointerPressed, PointerMovede PointerReleased non elaborati passati tramite InkPresenter.We then define handlers for the unprocessed PointerPressed, PointerMoved, and PointerReleased events passed through by the InkPresenter.

    Tutte le funzionalità di selezione sono implementate in questi gestori, inclusi il tratto Lazo e il rettangolo delimitatore.All selection functionality is implemented in these handlers, including the lasso stroke and the bounding rectangle.

    Screenshot del lazo di selezione.

      // Handle unprocessed pointer events from modified input.
      // The input is used to provide selection functionality.
      // Selection UI is drawn on a canvas under the InkCanvas.
      private void UnprocessedInput_PointerPressed(
        InkUnprocessedInput sender, PointerEventArgs args)
      {
        // Initialize a selection lasso.
        lasso = new Polyline()
        {
            Stroke = new SolidColorBrush(Windows.UI.Colors.Blue),
            StrokeThickness = 1,
            StrokeDashArray = new DoubleCollection() { 5, 2 },
            };
    
            lasso.Points.Add(args.CurrentPoint.RawPosition);
    
            selectionCanvas.Children.Add(lasso);
        }
    
        private void UnprocessedInput_PointerMoved(
          InkUnprocessedInput sender, PointerEventArgs args)
        {
          // Add a point to the lasso Polyline object.
          lasso.Points.Add(args.CurrentPoint.RawPosition);
        }
    
        private void UnprocessedInput_PointerReleased(
          InkUnprocessedInput sender, PointerEventArgs args)
        {
          // Add the final point to the Polyline object and
          // select strokes within the lasso area.
          // Draw a bounding box on the selection canvas
          // around the selected ink strokes.
          lasso.Points.Add(args.CurrentPoint.RawPosition);
    
          boundingRect =
            inkCanvas.InkPresenter.StrokeContainer.SelectWithPolyLine(
              lasso.Points);
    
          DrawBoundingRect();
        }
    
  5. Per concludere il gestore dell'evento PointerReleased, cancelliamo tutto il contenuto del livello di selezione (il tratto Lazo) e quindi disegniamo un unico rettangolo delimitatore attorno ai tratti input penna racchiusi nell'area del Lazo.To conclude the PointerReleased event handler, we clear the selection layer of all content (the lasso stroke) and then draw a single bounding rectangle around the ink strokes encompassed by the lasso area.

    Screenshot del rettangolo di delimitazione della selezione.

      // Draw a bounding rectangle, on the selection canvas, encompassing
      // all ink strokes within the lasso area.
      private void DrawBoundingRect()
      {
        // Clear all existing content from the selection canvas.
        selectionCanvas.Children.Clear();
    
        // Draw a bounding rectangle only if there are ink strokes
        // within the lasso area.
        if (!((boundingRect.Width == 0) ||
          (boundingRect.Height == 0) ||
          boundingRect.IsEmpty))
          {
            var rectangle = new Rectangle()
            {
              Stroke = new SolidColorBrush(Windows.UI.Colors.Blue),
                StrokeThickness = 1,
                StrokeDashArray = new DoubleCollection() { 5, 2 },
                Width = boundingRect.Width,
                Height = boundingRect.Height
            };
    
            Canvas.SetLeft(rectangle, boundingRect.X);
            Canvas.SetTop(rectangle, boundingRect.Y);
    
            selectionCanvas.Children.Add(rectangle);
          }
        }
    
  6. Infine, vengono definiti i gestori per gli eventi InkPresenter StrokeStarted e StrokesErased .Finally, we define handlers for the StrokeStarted and StrokesErased InkPresenter events.

    Entrambi gli eventi chiamano la stessa funzione di pulizia per cancellare la selezione corrente quando viene rilevato un nuovo tratto.These both just call the same cleanup function to clear the current selection whenever a new stroke is detected.

      // Handle new ink or erase strokes to clean up selection UI.
      private void StrokeInput_StrokeStarted(
        InkStrokeInput sender, Windows.UI.Core.PointerEventArgs args)
      {
        ClearSelection();
      }
    
      private void InkPresenter_StrokesErased(
        InkPresenter sender, InkStrokesErasedEventArgs args)
      {
        ClearSelection();
      }
    
  7. Ecco la funzione per rimuovere tutta l'interfaccia utente di selezione dal canvas di selezione quando viene iniziato un nuovo tratto o viene cancellato un tratto esistente.Here's the function to remove all selection UI from the selection canvas when a new stroke is started or an existing stroke is erased.

      // Clean up selection UI.
      private void ClearSelection()
      {
        var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
        foreach (var stroke in strokes)
        {
          stroke.Selected = false;
        }
        ClearDrawnBoundingRect();
       }
    
      private void ClearDrawnBoundingRect()
      {
        if (selectionCanvas.Children.Any())
        {
          selectionCanvas.Children.Clear();
          boundingRect = Rect.Empty;
        }
      }
    

Rendering personalizzato dell'input pennaCustom ink rendering

Per impostazione predefinita, l'input penna viene elaborato in un thread in background a bassa latenza e sottoposto a rendering in corso o "bagnato" mentre viene disegnato.By default, ink input is processed on a low-latency background thread and rendered in-progress, or "wet", as it is drawn. Al termine del tratto (penna o dito sollevato o pulsante del mouse rilasciato), il tratto viene elaborato sul thread dell'interfaccia utente e sottoposto a rendering "Dry" nel livello InkCanvas (sopra il contenuto dell'applicazione e sostituendo l'inchiostro bagnato).When the stroke is completed (pen or finger lifted, or mouse button released), the stroke is processed on the UI thread and rendered "dry" to the InkCanvas layer (above the application content and replacing the wet ink).

È possibile eseguire l'override di questo comportamento predefinito e controllare completamente l'esperienza Inking per "essiccazione personalizzata" dei tratti di input penna bagnato.You can override this default behavior and completely control the inking experience by "custom drying" the wet ink strokes. Sebbene il comportamento predefinito sia in genere sufficiente per la maggior parte delle applicazioni, in alcuni casi potrebbe essere necessario l'essiccazione personalizzata, tra cui:While the default behavior is typically sufficient for most applications, there are a few cases where custom drying might be required, these include:

  • Gestione più efficiente di raccolte di tratti di input penna di grandi dimensioni o complesseMore efficient management of large, or complex, collections of ink strokes
  • Supporto più efficiente per la panoramica e lo zoom su Canvas ink di grandi dimensioniMore efficient panning and zooming support on large ink canvases
  • Interfoliazione dell'input penna e di altri oggetti, ad esempio forme o testo, mantenendo l'ordine zInterleaving ink and other objects, such as shapes or text, while maintaining z-order
  • Essiccazione e conversione dell'input penna in modo sincrono in una forma DirectX (ad esempio, una linea retta o una forma rasterizzata e integrata nel contenuto dell'applicazione anziché come livello InkCanvas separato).Drying and converting ink synchronously into a DirectX shape (for example, a straight line or shape rasterized and integrated into application content instead of as a separate InkCanvas layer).

L'essiccazione personalizzata richiede un oggetto IInkD2DRenderer per gestire l'input dell'input penna ed eseguirne il rendering nel contesto di periferica Direct2D dell'app di Windows universale, anziché il controllo InkCanvas predefinito.Custom drying requires an IInkD2DRenderer object to manage the ink input and render it to the Direct2D device context of your Universal Windows app, instead of the default InkCanvas control.

Chiamando ActivateCustomDrying (prima che sia caricato il controllo InkCanvas), un'app crea un oggetto InkSynchronizer per personalizzare la modalità di esecuzione del rendering definitivo di un tratto input penna in un oggetto SurfaceImageSource o VirtualSurfaceImageSource.By calling ActivateCustomDrying (before the InkCanvas is loaded), an app creates an InkSynchronizer object to customize how an ink stroke is rendered dry to a SurfaceImageSource or VirtualSurfaceImageSource.

Sia SurfaceImageSource che VirtualSurfaceImageSource forniscono una superficie condivisa di DirectX che consente all'app di creare e comporre nel contenuto dell'applicazione, sebbene VSI fornisca una superficie virtuale più grande dello schermo per la panoramica e lo zoom a prestazioni elevate.Both SurfaceImageSource and VirtualSurfaceImageSource provide a DirectX shared surface for your app to draw into and compose into your application's content, although VSIS provides a virtual surface that’s larger than the screen for performant panning and zooming. Poiché gli aggiornamenti visivi per queste superfici sono sincronizzati con il thread dell'interfaccia utente XAML, quando viene eseguito il rendering dell'input penna in entrambi i casi, l'inchiostro bagnato può essere rimosso contemporaneamente da InkCanvas.Because visual updates to these surfaces are synchronized with the XAML UI thread, when ink is rendered to either, the wet ink can be removed from the InkCanvas simultaneously.

È anche possibile personalizzare l'input penna in un SwapChainPanel, ma la sincronizzazione con il thread dell'interfaccia utente non è garantita e potrebbe esserci un ritardo tra il rendering dell'input penna in SwapChainPanel e quando l'input penna viene rimosso da InkCanvas.You can also custom dry ink to a SwapChainPanel, but synchronization with the UI thread is not guaranteed and there might be a delay between when the ink is rendered to your SwapChainPanel and when ink is removed from the InkCanvas.

Per un esempio completo di questa funzionalità, vedi l'esempio di input penna complesso.For a full example of this functionality, see the Complex ink sample.

Nota

Personalizzazione del rendering definitivo e InkToolbarCustom drying and the InkToolbar
Se l'app esegue l'override del comportamento di rendering dell'input penna predefinito di InkPresenter con un'implementazione di essiccazione personalizzata, i tratti di input penna di cui è stato eseguito il rendering non sono più disponibili per InkToolbar e i comandi di cancellazione predefiniti di InkToolbar non funzionano come previsto.If your app overrides the default ink rendering behavior of the InkPresenter with a custom drying implementation, the rendered ink strokes are no longer available to the InkToolbar and the built-in erase commands of the InkToolbar do not work as expected. Per offrire funzionalità di cancellazione, è necessario gestire tutti gli eventi puntatore, eseguire l'hit testing su ogni tratto ed eseguire l'override del comando predefinito "Cancella tutto l'input penna".To provide erase functionality, you must handle all pointer events, perform hit-testing on each stroke, and override the built-in "Erase all ink" command.

ArgomentoTopic DescrizioneDescription
Riconoscere i tratti input pennaRecognize ink strokes Puoi convertire i tratti input penna in testo usando il riconoscimento della grafia oppure in forme usando il riconoscimento personalizzato.Convert ink strokes to text using handwriting recognition, or to shapes using custom recognition.
Archiviare e recuperare tratti input pennaStore and retrieve ink strokes Puoi archiviare i dati del tratto input penna in un file GIF (Graphics Interchange Format) usando metadati ISF (Ink Serialized Format) incorporati.Store ink stroke data in a Graphics Interchange Format (GIF) file using embedded Ink Serialized Format (ISF) metadata.
Aggiungere un InkToolbar a un'app di Windows InkingAdd an InkToolbar to a Windows inking app Aggiungere un valore predefinito di InkToolbar a un'app di Windows app Inking, aggiungere un pulsante di penna personalizzato al InkToolbar e associare il pulsante della penna personalizzata a una definizione di penna personalizzata.Add a default InkToolbar to a Windows app inking app, add a custom pen button to the InkToolbar, and bind the custom pen button to a custom pen definition.

APIAPIs

EsempiSamples

Esempi di archivioArchive Samples