WPF InkCanvas 在 space 超出 Clip 边界的情况下绘制。覆盖命中测试

WPF InkCanvas draw even on space beyond bounds of Clip. Override Hit Test

我正在使用 InkCanvas.Clip 属性 将我的 InkCanvas 剪裁成我需要的形状(为此我正在使用 PathGeometry)。我只能在这个区域开始画画,但我希望能够在它之外开始画画。当然,超出此区域的部分将不会显示。 我怎样才能做到这一点?我考虑过覆盖 InkCanvas 的 HitTestCore,也许默认情况下 HitTest 在我允许的绘图区域之外失败

也许OpacityMask可以实现你想要的:

  1. 要在外部剪裁的笔画
  2. 开始在外面画画,然后进来。

<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>

附加:

为了避免@SaintMSent 提到的移动,我们应该启用 InkCanvas 的 AdornerDecorator 的 ClipToBounds 属性:

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

代码隐藏:

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