-1

I am using InkCanvas.Clip property to clip my InkCanvas to the shape I need (I am using PathGeometry for that). I can only start drawing in this area, but I want to be able to start drawing outside of it. Of course, stoke parts beyond this area would not be displayed. How can I do that? I thought about overriding HitTestCore of InkCanvas, perhaps by default HitTest fails outside of my allowed drawing area

IntegerOverlord
  • 1,477
  • 1
  • 14
  • 33
  • Where to display the stroke outside the clipped InkCanvas? – Iron Aug 06 '18 at 14:44
  • @Iron nowhere. Right now if you start drawing inside and go outside, strokes are registered, but they are not displayed outside (if you remove the Clip, you will be able to see them outside). I want to be able to start drawing outside and come inside. Strokes should be displayed only inside – IntegerOverlord Aug 06 '18 at 15:01
  • As the `InkCanvas` was clipped, it can't receive the `MouseDown` event, which fires the drawing. So, you are unable to start drawing outside and come inside. – Iron Aug 06 '18 at 15:11
  • @Iron I thought that maybe Hit Test is negative outside and I can override it. Is it possible? – IntegerOverlord Aug 06 '18 at 15:38
  • Yes, the `HitTest` is invalid outside. Unfortunately, you can't override it, as clipped `UIElement` will be penetrated in WPF. – Iron Aug 06 '18 at 15:47

1 Answers1

1

Maybe OpacityMask can achieve what you want:

  1. Stroke to be clipped outside
  2. To start drawing outside and come inside.

<Grid Background="LightSalmon">
    <InkCanvas Background="LightBlue">
        <InkCanvas.OpacityMask>
            <DrawingBrush>
                <DrawingBrush.Drawing>
                    <GeometryDrawing>
                        <GeometryDrawing.Brush>
                            <SolidColorBrush Color="Black"/>
                        </GeometryDrawing.Brush>
                        <GeometryDrawing.Geometry>
                            <PathGeometry>
                                <PathGeometry.Figures>
                                    <PathFigure StartPoint="0,0">
                                        <PathFigure.Segments>
                                            <PolyLineSegment Points="100,0 100,100 0,100 0,0"/>
                                            <PolyLineSegment Points="100,0 100,100 0,100 0,0"/>
                                            <PolyLineSegment Points="30,30 70,30 70,70 30,70 30,30"/>
                                        </PathFigure.Segments>
                                    </PathFigure>
                                </PathGeometry.Figures>
                            </PathGeometry>
                        </GeometryDrawing.Geometry>
                    </GeometryDrawing>
                </DrawingBrush.Drawing>
            </DrawingBrush>
        </InkCanvas.OpacityMask>
    </InkCanvas>
</Grid>

Appended:

To avoid the shifting as @SaintMSent mentioned, we should enable the ClipToBounds property of the InkCanvas's AdornerDecorator:

<InkCanvas x:Name="MyInkCanvas" Background="LightBlue" Loaded="MyInkCanvas_OnLoaded">
    ......
</InkCanvas>

Code-behind:

private void MyInkCanvas_OnLoaded(object sender, RoutedEventArgs e)
{
    var adornerDecorator = VisualTreeHelper.GetChild(MyInkCanvas, 0) as AdornerDecorator;
    if (adornerDecorator != null)
    {
        adornerDecorator.ClipToBounds = true;
    }
}
Iron
  • 926
  • 1
  • 5
  • 16