Création d'un contrôle d'entrée d'encreCreating an Ink Input Control

Vous pouvez créer un contrôle personnalisé qui dynamiquement et restitue l’encre de manière statique.You can create a custom control that dynamically and statically renders ink. Autrement dit, afficher l’encre lorsqu’un utilisateur trace un trait, à l’origine de l’encre semble « couler » du stylet et d’afficher l’encre après lui est ajouté au contrôle, soit via le stylet, collé à partir du Presse-papiers ou chargé à partir d’un fichier.That is, render ink as a user draws a stroke, causing the ink to appear to "flow" from the tablet pen, and display ink after it is added to the control, either via the tablet pen, pasted from the Clipboard, or loaded from a file. Pour restituer l’encre de manière dynamique, votre contrôle doit utiliser un DynamicRenderer.To dynamically render ink, your control must use a DynamicRenderer. Pour restituer l’encre de façon statique, vous devez substituer les méthodes d’événement de stylet (OnStylusDown, OnStylusMove, et OnStylusUp) pour collecter StylusPoint données, créer des traits et les ajouter à un InkPresenter (qui restitue l’encre sur le contrôle).To statically render ink, you must override the stylus event methods (OnStylusDown, OnStylusMove, and OnStylusUp) to collect StylusPoint data, create strokes, and add them to an InkPresenter (which renders the ink on the control).

Cette rubrique contient les sous-sections suivantes :This topic contains the following subsections:

Procédure : Collecter des données de Point de stylet et créer des traits d’encreHow to: Collect Stylus Point Data and Create Ink Strokes

Pour créer un contrôle qui collecte et gère l’encre traits les opérations suivantes :To create a control that collects and manages ink strokes do the following:

  1. Dérivez une classe de Control ou une des classes dérivées de Control, tel que Label.Derive a class from Control or one of the classes derived from Control, such as Label.

    using System;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Input.StylusPlugIns;
    using System.Windows.Controls;
    using System.Windows;
    
    class InkControl : Label
    {
    
    }
    
  2. Ajouter un InkPresenter à la classe et définissez la Content à la nouvelle propriété InkPresenter.Add an InkPresenter to the class and set the Content property to the new InkPresenter.

    InkPresenter ip;
    
    public InkControl()
    {
        // Add an InkPresenter for drawing.
        ip = new InkPresenter();
        this.Content = ip;
    }
    
  3. Attacher le RootVisual de la DynamicRenderer à la InkPresenter en appelant le AttachVisuals (méthode) et ajoutez le DynamicRenderer à la StylusPlugIns collection.Attach the RootVisual of the DynamicRenderer to the InkPresenter by calling the AttachVisuals method, and add the DynamicRenderer to the StylusPlugIns collection. Cela permet la InkPresenter pour afficher l’encre comme les données de point de stylet sont collectées par votre contrôle.This allows the InkPresenter to display the ink as the stylus point data is collected by your control.

    public InkControl()
    {
    
        // Add a dynamic renderer that 
        // draws ink as it "flows" from the stylus.
        dr = new DynamicRenderer();
        ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes);
        this.StylusPlugIns.Add(dr);
    
    }
    
  4. Remplacez la méthode OnStylusDown .Override the OnStylusDown method. Dans cette méthode, capturez le stylet avec un appel à Capture.In this method, capture the stylus with a call to Capture. En capturant le stylet, votre contrôle sera pour continuer à recevoir StylusMove et StylusUp événements même si le stylet quitte les limites du contrôle.By capturing the stylus, your control will to continue to receive StylusMove and StylusUp events even if the stylus leaves the control's boundaries. Cela n’est pas strictement obligatoire, mais il est presque toujours souhaité pour une expérience utilisateur optimale.This is not strictly mandatory, but almost always desired for a good user experience. Créer un nouveau StylusPointCollection pour rassembler StylusPoint données.Create a new StylusPointCollection to gather StylusPoint data. Enfin, ajoutez l’ensemble initial de StylusPoint données à le StylusPointCollection.Finally, add the initial set of StylusPoint data to the StylusPointCollection.

    protected override void OnStylusDown(StylusDownEventArgs e)
    {
        // Capture the stylus so all stylus input is routed to this control.
        Stylus.Capture(this);
    
        // Allocate memory for the StylusPointsCollection and
        // add the StylusPoints that have come in so far.
        stylusPoints = new StylusPointCollection();
        StylusPointCollection eventPoints = 
            e.GetStylusPoints(this, stylusPoints.Description);
    
        stylusPoints.Add(eventPoints);
    
    }
    
  5. Remplacer le OnStylusMove méthode et ajoutez le StylusPoint données à la StylusPointCollection objet que vous avez créé précédemment.Override the OnStylusMove method and add the StylusPoint data to the StylusPointCollection object that you created earlier.

    protected override void OnStylusMove(StylusEventArgs e)
    {
        if (stylusPoints == null)
        {
            return;
        }
    
        // Add the StylusPoints that have come in since the 
        // last call to OnStylusMove.
        StylusPointCollection newStylusPoints = 
            e.GetStylusPoints(this, stylusPoints.Description);
        stylusPoints.Add(newStylusPoints);
    }
    
  6. Remplacer le OnStylusUp (méthode) et créez un nouveau Stroke avec la StylusPointCollection données.Override the OnStylusUp method and create a new Stroke with the StylusPointCollection data. Ajoutez la nouvelle Stroke que vous avez créé à le Strokes collection de la InkPresenter et la capture du stylet.Add the new Stroke you created to the Strokes collection of the InkPresenter and release stylus capture.

    protected override void OnStylusUp(StylusEventArgs e)
    {
        if (stylusPoints == null)
        {
            return;
        }
    
        // Add the StylusPoints that have come in since the 
        // last call to OnStylusMove.
        StylusPointCollection newStylusPoints = 
            e.GetStylusPoints(this, stylusPoints.Description);
        stylusPoints.Add(newStylusPoints);
    
        // Create a new stroke from all the StylusPoints since OnStylusDown.
        Stroke stroke = new Stroke(stylusPoints);
    
        // Add the new stroke to the Strokes collection of the InkPresenter.
        ip.Strokes.Add(stroke);
    
        // Clear the StylusPointsCollection.
        stylusPoints = null;
    
        // Release stylus capture.
        Stylus.Capture(null);
    }
    

Procédure : Activer votre contrôle d’accepter l’entrée à partir de la sourisHow to: Enable Your Control to Accept Input from the Mouse

Si vous ajoutez le contrôle précédent à votre application, exécutez, puis utilisez la souris comme périphérique d’entrée, vous remarquerez que les traits ne sont pas conservées.If you add the preceding control to your application, run it, and use the mouse as an input device, you will notice that the strokes are not persisted. Pour conserver les traits lorsque la souris est utilisée en tant que le périphérique d’entrée les opérations suivantes :To persist the strokes when the mouse is used as the input device do the following:

  1. Remplacer le OnMouseLeftButtonDown et créez un nouveau StylusPointCollection obtenir la position de la souris lorsque l’événement s’est produite et créer un StylusPoint les données du point et ajoutez le StylusPoint à la StylusPointCollection.Override the OnMouseLeftButtonDown and create a new StylusPointCollection Get the position of the mouse when the event occurred and create a StylusPoint using the point data and add the StylusPoint to the StylusPointCollection.

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
    
        base.OnMouseLeftButtonDown(e);
    
        // If a stylus generated this event, return.
        if (e.StylusDevice != null)
        {
            return;
        }
    
        // Start collecting the points.
        stylusPoints = new StylusPointCollection();
        Point pt = e.GetPosition(this);
        stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
    
    }
    
  2. Remplacez la méthode OnMouseMove .Override the OnMouseMove method. Obtient la position de la souris lorsque l’événement s’est produite et créer un StylusPoint en utilisant les données de point.Get the position of the mouse when the event occurred and create a StylusPoint using the point data. Ajouter le StylusPoint à la StylusPointCollection objet que vous avez créé précédemment.Add the StylusPoint to the StylusPointCollection object that you created earlier.

    protected override void OnMouseMove(MouseEventArgs e)
    {
    
        base.OnMouseMove(e);
    
        // If a stylus generated this event, return.
        if (e.StylusDevice != null)
        {
            return;
        }
    
        // Don't collect points unless the left mouse button
        // is down.
        if (e.LeftButton == MouseButtonState.Released || 
            stylusPoints == null)
        {
            return;
        }
    
        Point pt = e.GetPosition(this);
        stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
    }
    
  3. Remplacez la méthode OnMouseLeftButtonUp .Override the OnMouseLeftButtonUp method. Créer un nouveau Stroke avec la StylusPointCollection données et ajoutez la nouvelle Stroke que vous avez créé à le Strokes collection de la InkPresenter.Create a new Stroke with the StylusPointCollection data, and add the new Stroke you created to the Strokes collection of the InkPresenter.

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
    
        base.OnMouseLeftButtonUp(e);
    
        // If a stylus generated this event, return.
        if (e.StylusDevice != null)
        {
            return;
        }
    
        if (stylusPoints == null)
        {
            return;
        }
    
        Point pt = e.GetPosition(this);
        stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
    
        // Create a stroke and add it to the InkPresenter.
        Stroke stroke = new Stroke(stylusPoints);
        stroke.DrawingAttributes = dr.DrawingAttributes;
        ip.Strokes.Add(stroke);
    
        stylusPoints = null;
    
    }
    

AssemblagePutting it together

L’exemple suivant est un contrôle personnalisé qui collecte d’encre lorsque l’utilisateur utilise la souris ou le stylet.The following example is a custom control that collects ink when the user uses either the mouse or the pen.

using System;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Input.StylusPlugIns;
using System.Windows.Controls;
using System.Windows;
// A control for managing ink input
class InkControl : Label
{
    InkPresenter ip;
    DynamicRenderer dr;

    // The StylusPointsCollection that gathers points 
    // before Stroke from is created.
    StylusPointCollection stylusPoints = null;
    
    public InkControl()
    {
        // Add an InkPresenter for drawing.
        ip = new InkPresenter();
        this.Content = ip;

        // Add a dynamic renderer that 
        // draws ink as it "flows" from the stylus.
        dr = new DynamicRenderer();
        ip.AttachVisuals(dr.RootVisual, dr.DrawingAttributes);
        this.StylusPlugIns.Add(dr);

    }

    static InkControl()
    {
        // Allow ink to be drawn only within the bounds of the control.
        Type owner = typeof(InkControl);
        ClipToBoundsProperty.OverrideMetadata(owner,
            new FrameworkPropertyMetadata(true));
    }

    protected override void OnStylusDown(StylusDownEventArgs e)
    {
        // Capture the stylus so all stylus input is routed to this control.
        Stylus.Capture(this);

        // Allocate memory for the StylusPointsCollection and
        // add the StylusPoints that have come in so far.
        stylusPoints = new StylusPointCollection();
        StylusPointCollection eventPoints = 
            e.GetStylusPoints(this, stylusPoints.Description);

        stylusPoints.Add(eventPoints);

    }

    protected override void OnStylusMove(StylusEventArgs e)
    {
        if (stylusPoints == null)
        {
            return;
        }

        // Add the StylusPoints that have come in since the 
        // last call to OnStylusMove.
        StylusPointCollection newStylusPoints = 
            e.GetStylusPoints(this, stylusPoints.Description);
        stylusPoints.Add(newStylusPoints);
    }

    protected override void OnStylusUp(StylusEventArgs e)
    {
        if (stylusPoints == null)
        {
            return;
        }

        // Add the StylusPoints that have come in since the 
        // last call to OnStylusMove.
        StylusPointCollection newStylusPoints = 
            e.GetStylusPoints(this, stylusPoints.Description);
        stylusPoints.Add(newStylusPoints);

        // Create a new stroke from all the StylusPoints since OnStylusDown.
        Stroke stroke = new Stroke(stylusPoints);

        // Add the new stroke to the Strokes collection of the InkPresenter.
        ip.Strokes.Add(stroke);

        // Clear the StylusPointsCollection.
        stylusPoints = null;

        // Release stylus capture.
        Stylus.Capture(null);
    }

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {

        base.OnMouseLeftButtonDown(e);

        // If a stylus generated this event, return.
        if (e.StylusDevice != null)
        {
            return;
        }

        // Start collecting the points.
        stylusPoints = new StylusPointCollection();
        Point pt = e.GetPosition(this);
        stylusPoints.Add(new StylusPoint(pt.X, pt.Y));

    }

    protected override void OnMouseMove(MouseEventArgs e)
    {

        base.OnMouseMove(e);

        // If a stylus generated this event, return.
        if (e.StylusDevice != null)
        {
            return;
        }

        // Don't collect points unless the left mouse button
        // is down.
        if (e.LeftButton == MouseButtonState.Released || 
            stylusPoints == null)
        {
            return;
        }

        Point pt = e.GetPosition(this);
        stylusPoints.Add(new StylusPoint(pt.X, pt.Y));
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {

        base.OnMouseLeftButtonUp(e);

        // If a stylus generated this event, return.
        if (e.StylusDevice != null)
        {
            return;
        }

        if (stylusPoints == null)
        {
            return;
        }

        Point pt = e.GetPosition(this);
        stylusPoints.Add(new StylusPoint(pt.X, pt.Y));

        // Create a stroke and add it to the InkPresenter.
        Stroke stroke = new Stroke(stylusPoints);
        stroke.DrawingAttributes = dr.DrawingAttributes;
        ip.Strokes.Add(stroke);

        stylusPoints = null;

    }
}

À l’aide de Plug-ins supplémentaires et DynamicRenderersUsing Additional Plug-ins and DynamicRenderers

Tout comme l’InkCanvas, votre contrôle personnalisé peut avoir personnalisé StylusPlugIn et d’autres DynamicRenderer objets.Like the InkCanvas, your custom control can have custom StylusPlugIn and additional DynamicRenderer objects. Ajouter à la StylusPlugIns collection.Add these to the StylusPlugIns collection. L’ordre de la StylusPlugIn des objets dans le StylusPlugInCollection affecte l’apparence de l’encre lorsqu’il est restitué.The order of the StylusPlugIn objects in the StylusPlugInCollection affects the appearance of the ink when it is rendered. Supposons que vous ayez un DynamicRenderer appelé dynamicRenderer et personnalisé StylusPlugIn appelée translatePlugin qui décale l’encre du stylet.Suppose you have a DynamicRenderer called dynamicRenderer and a custom StylusPlugIn called translatePlugin that offsets the ink from the tablet pen. Si translatePlugin est le premier StylusPlugIn dans le StylusPlugInCollection, et dynamicRenderer est le deuxième, l’encre qui « coule » sera décalée quand l’utilisateur déplace le stylet.If translatePlugin is the first StylusPlugIn in the StylusPlugInCollection, and dynamicRenderer is the second, the ink that "flows" will be offset as the user moves the pen. Si dynamicRenderer est tout d’abord, et translatePlugin est en second lieu, l’encre ne sera pas décalée jusqu'à ce que l’utilisateur soulève le stylet.If dynamicRenderer is first, and translatePlugin is second, the ink will not be offset until the user lifts the pen.

ConclusionConclusion

Vous pouvez créer un contrôle qui collecte et restitue l’encre en substituant les méthodes d’événement de stylet.You can create a control that collects and renders ink by overriding the stylus event methods. En créant votre propre contrôle, en dérivant vos propres StylusPlugIn classes et en les insérant le dans StylusPlugInCollection, vous pouvez implémenter virtuellement tout comportement imaginable avec l’encre numérique.By creating your own control, deriving your own StylusPlugIn classes, and inserting them the into StylusPlugInCollection, you can implement virtually any behavior imaginable with digital ink. Vous avez accès à la StylusPoint données tel qu’il sont générées, ce qui vous donne la possibilité de personnaliser Stylus d’entrée et de restituer sur l’écran en fonction de votre application.You have access to the StylusPoint data as it is generated, giving you the opportunity to customize Stylus input and render it on the screen as appropriate for your application. Étant donné que vous avez un accès de bas niveau pour le StylusPoint données, vous pouvez implémenter la collecte d’encre et restituer avec des performances optimales pour votre application.Because you have such low-level access to the StylusPoint data, you can implement ink collection and render it with optimal performance for your application.

Voir aussiSee also