Search code examples
c#wpfinkcanvas

Custom InkCanvas (MSDN Code Sample not working properly)


I want to use custom brushes with the InkCanvas.

Their is a code snippet from MSDN. (http://msdn.microsoft.com/en-us/library/ms747347.aspx)

If i use that code and move my mouse VERY fast i get space between the brushes(ellipses): Screenshot

And my question is of course how to fix this but I'm also curious why this is happening (I want to learn from it) I thought maybe i did something wrong but even if i cut/paste the example it's happening.

One little thing i noticed when reading the code was this comment in the CustomStroke class

// Draw linear gradient ellipses between
// all the StylusPoints in the Stroke

Seems to me like it should draw ellipses between the points not only at the points.

I'm using C#.NET.

Again in short:

  • Why is this happening
  • Help me fix it :)

Solution

  • Why this is happening

    The custom InkCanvas in the example draws an ellipse at every collected StrokePoint but makes no attempt to draw lines between them. The standard InkCanvas control is implemented by drawing lines between the points it is given. This is why the custom InkCanvas implementation from the example leaves gaps and the built-in one doesn't.

    How to "fix" it

    The custom code could easily be extended to not leave gaps: In addition to drawing ellipses at each point, it could draw lines between each pair of points.

    Code to draw connecting lines might be added before the code to draw the ellipses, like this:

    // Draw connecting lines
    var geo = new StreamGeometry();
    using(geoContext = geo.Open())
    {
      geoContext.StartFigure(stylusPoints[0], false, false);
      geoContext.PolyLineTo(stylusPoints.Skip(1).Cast<Point>(), true, false);
    }
    drawingContext.DrawGeometry(null, connectingLinePen, geo);
    
    // Draw ellipses
    for(int i = 1; i < stylusPoints.Count; i++)
    {
      ... etc ...
    

    This code works by constructing a polyline StreamGeometry and then drawing it to the context. Using a StreamGeometry in this context is generally more efficient than creating a PathGeometry with a Polyline or doing a bunch of DrawLine calls directly on the drawingCanvas.

    Note: Using a better digitizer won't solve the underlying problem, which is that the custom InkCanvas is actually designed to only show data at the sampled points and not in between.