2017-10-06 1 views
2

Ich habe eine Leinwand (nicht InkCanvas!) Und kann Polylinien darauf zeichnen. Das funktioniert ganz gut, aber es gibt ein riesiges Problem mit dem Zeichnen von Grenzen, wie in der GIF unten gezeigt.UWP Canvas Zeichnung außerhalb der Grenzen

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

Meine Leinwand ist in einem Scrollviewer und die Scroll innerhalb eines Gridview ist.

Ich habe versucht, den Zeiger verlassen die Leinwand mit den folgenden Event-Handler zu fangen:

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

Aber es scheint, diese Ereignisse viel zu langsam abgefeuert werden.

Ich habe versucht, die Clip-Eigenschaft meines Canvas zu verwenden, aber das Verhalten ändert sich nicht. Und es gibt keine "ClipToBound" -Eigenschaft für die UWP-Leinwand.

Meine gesamte Ansicht wird in Code-Behind generiert, weil ich mehrere Canvases in einer Ansicht erzeugen muss.

Gibt es eine Möglichkeit, dieses Verhalten zu stoppen?

EDIT1:

Wie gefordert: mehr Einsicht meines Codes.

Die XAML Seite sieht wie folgt aus:

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

Es ist alles in einer Seite.

Mein Code sieht hinter wie folgt aus:

Meine Erbauer:

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); 
    } 

Ich habe nur zwei contructors es einfach zu machen für mich Leinwände mit der Fähigkeit, zu instanziiert zu ziehen und ohne die Fähigkeit zu zeichnen . Diese

ist, wie ich meine Scroll initialisieren:

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

Das sind die einzigen Codezeilen, die jede viewbuilding beeinflussen.

Edit 2:

Meine Leinwand das umgebende Gitter auf der linken Seite nicht füllen, sondern auf der Unterseite.

enter image description here

+0

Eine schnelle Antwort auf das Obige, die Zeilen-Definitionen mit Sternen sollen Prozentsätze sein. So ist '15 *' tatsächlich gleich '1500%'.Wenn Sie Sterne verwenden, empfehle ich dringend, dass alle Werte eins ergeben. '' und '' – Laith

+0

Wo wird die Polylinie hinzugefügt? Wie wird das zusammengebaut? – Laith

+0

Danke für diese Antwort. Und ich habe herausgefunden, dass dein Code perfekt funktioniert. Aber meine Leinwand ist nicht breit genug, um das umgebende Raster zu füllen. Ihr Code schneidet also die Linie perfekt an der oberen und unteren Kante, aber nicht an der linken und rechten Seite. Ich poste einen Screenshot in meiner Queston. – eXodiquas

Antwort

1

Der Code in Ihre PointerMoved Handler sollte auf die Leinwand relativ sein.

Wenn x/y negativ oder größer als die Größe der Leinwand sind, sind sie außerhalb der Grenzen. Sie können den Punkt entweder auf den Rand des Zeichenbereichs beschränken, wie es der obige Code tut, oder Sie können den Punkt vollständig verwerfen.

+0

Ihr Code funktioniert vollkommen in Ordnung, theoretisch. Wenn ich sehr langsam über den Rand der Leinwand zeichne, schneidet es perfekt die Linie. Aber wenn ich sehr schnell zeichne, kann ich immer noch Grenzen überschreiten. Sind diese Ereignisse wirklich so langsam? – eXodiquas

+0

Es sollte nicht möglich sein. Wenn Sie die x- und y-Werte des Punkts überdecken, sollten sie unabhängig von der Geschwindigkeit niemals außerhalb der Grenzen der Zeichenfläche zeichnen. Haben Sie Padding/Margen/Transformationen, die sich auf die Zeichnung auswirken? Vielleicht poste ein wenig mehr Code, wie du die Linien zeichnest und ich helfe dir beim Debuggen. – Laith

+0

Ich habe mehr Details zu meiner Frage hinzugefügt. Ich hoffe, diese Information ist hilfreich. Vielleicht ist es wichtig zu sagen, dass meine Leinwand erst nach dem Laden des Rasters ihre Größe erhält, weil ich keine andere Möglichkeit gefunden habe, eine Höhe und Breite dafür zu erhalten, bevor das umgebende Raster auf der Ansicht erstellt wurde. – eXodiquas