Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP Canvas drawing out of bounds

Tags:

c#

canvas

uwp

I have a canvas (not InkCanvas!) and I am able to draw Polylines on it. This is working just fine but there is a huge problem with drawing out of bounds like shown in the GIF below.

Right side is the canvas, left side is empty space.

My canvas is inside a ScrollViewer and the ScrollViewer is inside a 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. And there is no "ClipToBound" property for the UWP canvas.

My whole view is generated in Code-Behind because I have to generate multiple canvases on one view.

Is there a way to stop this behaviour?

EDIT1:

As requested: more insight of my code.

The XAML Page looks like this:

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

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:

My canvas doesn't fill the surrounding Grid on the left, but on the bottom.

enter image description here

like image 281
eXodiquas Avatar asked Nov 19 '25 11:11

eXodiquas


1 Answers

The code in your PointerMoved handler should be relative to the canvas.

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. You can either limit the point to the border of the canvas as the code above does, or you can discard the point completely.

like image 96
Laith Avatar answered Nov 21 '25 02:11

Laith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!