简体   繁体   English

UWP Canvas 绘图越界

[英]UWP Canvas drawing out of bounds

I have a canvas (not InkCanvas!) and I am able to draw Polylines on it.我有一个画布(不是 InkCanvas!),我可以在它上面画折线。 This is working just fine but there is a huge problem with drawing out of bounds like shown in the GIF below.这工作得很好,但是像下面的 GIF 所示,绘制越界存在一个巨大的问题。

右侧是画布,左侧是空白区域。

My canvas is inside a ScrollViewer and the ScrollViewer is inside a GridView.我的画布在 ScrollViewer 内,而 ScrollViewer 在 GridView 内。

I tried to catch the pointer leaving the canvas with the following event handlers:我尝试使用以下事件处理程序捕获离开画布的指针:

canvas.PointerExited += Canvas_PointerExited;
canvas.PointerCaptureLost += Canvas_PointerCaptureLost;

But it seems those events are fired way too slow.但似乎这些事件的触发速度太慢了。

I tried to use the Clip property of my canvas but there is no change in behaviour.我尝试使用画布的 Clip 属性,但行为没有变化。 And there is no "ClipToBound" property for the UWP canvas. UWP 画布没有“ClipToBound”属性。

My whole view is generated in Code-Behind because I have to generate multiple canvases on one view.我的整个视图是在 Code-Behind 中生成的,因为我必须在一个视图上生成多个画布。

Is there a way to stop this behaviour?有没有办法阻止这种行为?

EDIT1:编辑1:

As requested: more insight of my code.根据要求:更深入地了解我的代码。

The XAML Page looks like this: XAML 页面如下所示:

<Grid x:Name="BoundingGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="15*"/>
    </Grid.RowDefinitions>
    <Grid x:Name="InkGrid" VerticalAlignment="Top" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
    <Grid x:Name="CanvasGrid" Grid.Row="1" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" VerticalAlignment="Top"/>
</Grid>

It's all inside a Page.这一切都在一个页面中。

My code behind looks like this:我背后的代码如下所示:

My constructors:我的构造函数:

public ImprovedCanvasManager(Grid boundingGrid, Grid overviewGrid, string filepath, double height)
    {
        drawCanvas = new Canvas();

        overviewGrid.Loaded += OverviewGrid_Loaded;
        overviewGrid.SizeChanged += OverviewGrid_SizeChanged;

        RowDefinition rd = new RowDefinition();
        rd.Height = new GridLength(height);

        overviewGrid.RowDefinitions.Add(rd);

        InitializeScrollViewer();

        Grid.SetRow(scroll, overviewGrid.RowDefinitions.Count);
        Grid.SetColumn(scroll, 0);

        scroll.Content = drawCanvas;
        overviewGrid.Children.Add(scroll);
        LoadImage(filepath);
    }

        public ImprovedCanvasManager(Grid boundingGrid, Grid overviewGrid, Grid inkToolGrid, string filepath, double height = 1000) : this(boundingGrid, overviewGrid, filepath, height)
    {
        AddDrawingToolsToCanvas(inkToolGrid, overviewGrid);
        EnableDrawingOnCanvas(drawCanvas);
    }

I only got two contructors to make it simple for me to instantiate canvases with the ability to draw and without the ability to draw.我只有两个构造函数,使我可以轻松地实例化具有绘图能力和​​不具有绘图能力的画布。

This is how i initialise my ScrollViewer:这就是我初始化 ScrollViewer 的方式:

private void InitializeScrollViewer()
    {
        scroll = new ScrollViewer();

        scroll.VerticalAlignment = VerticalAlignment.Top;
        scroll.VerticalScrollMode = ScrollMode.Auto;
        scroll.HorizontalScrollMode = ScrollMode.Auto;
        scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
        scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
        scroll.ZoomMode = ZoomMode.Enabled;
        scroll.ManipulationMode = ManipulationModes.All;

        scroll.MinZoomFactor = 1;
        scroll.MaxZoomFactor = 3;
    }

Those are the only lines of code that affect any viewbuilding.这些是影响任何视图构建的唯一代码行。

Edit 2:编辑2:

My canvas doesn't fill the surrounding Grid on the left, but on the bottom.我的画布没有填充左侧的周围网格,而是填充了底部。

在此处输入图片说明

The code in your PointerMoved handler should be relative to the canvas. PointerMoved处理程序中的代码应该是相对于画布的。

private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
{
    var point = e.GetCurrentPoint(canvas); // <-- relative to canvas.
    var x = point.Position.X;
    var y = point.Position.Y;

    x = Math.Max(x, 0);
    y = Math.Max(y, 0);
    x = Math.Min(canvas.ActualWidth, x);
    y = Math.Min(canvas.ActualHeight, y);


    // add point to polyline...
}

If x/y are negative or greater than the size of the canvas, then they are out of bounds.如果 x/y 为负数或大于画布的大小,则它们越界。 You can either limit the point to the border of the canvas as the code above does, or you can discard the point completely.您可以像上面的代码那样将点限制在画布的边界上,也可以完全丢弃该点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM