2017-10-06 5 views
2

J'ai une toile (pas InkCanvas!) Et je suis capable d'y dessiner des polylignes. Cela fonctionne très bien, mais il y a un énorme problème avec le dessin hors limites comme indiqué dans le fichier GIF ci-dessous.UWP Dessin de toile en dehors des limites

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

Ma toile est dans un ScrollViewer et ScrollViewer se trouve dans un GridView.

J'ai essayé d'attraper le pointeur en laissant la toile avec les gestionnaires d'événements suivants:

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

Mais il semble que ces événements sont déclenchés trop lent.

J'ai essayé d'utiliser la propriété Clip de ma toile, mais il n'y a aucun changement de comportement. Et il n'y a pas de propriété "ClipToBound" pour le canevas UWP.

Toute ma vue est générée dans Code-Behind parce que je dois générer plusieurs canevas sur une seule vue.

Y at-il un moyen d'arrêter ce comportement?

EDIT1:

Comme demandé: plus de perspicacité de mon code.

Le XAML page ressemble à ceci:

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

Il est tout à l'intérieur d'une page.

Mon code ressemble derrière comme ceci:

Mes constructeurs:

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

Je ne me suis fait deux contructeurs pour le rendre simple pour moi de instancier toiles avec la possibilité de dessiner et sans la capacité de dessiner .

Voilà comment j'INITIALISER mon 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; 
    } 

Ce sont les seules lignes de code qui affectent toute viewbuilding.

Edit 2:

Ma toile ne remplit pas la grille entourant à gauche, mais sur le fond.

enter image description here

+0

Une réponse rapide à ce qui précède, les définitions de ligne avec des étoiles sont censées être des pourcentages. Donc '15 *' est égal à '1500%'.Lorsque vous utilisez des étoiles, je recommande fortement que toutes les valeurs totalisent un. '' et < ' – Laith

+0

Où la polyligne est-elle ajoutée? Comment ça se passe-t-il? – Laith

+0

Merci pour cette réponse. Et j'ai découvert que votre code fonctionne parfaitement. Mais ma toile n'est pas assez large pour remplir la grille environnante. Ainsi, votre code coupe parfaitement la ligne sur les bords supérieur et inférieur, mais pas sur les côtés gauche et droit. Je poste une capture d'écran dans ma queston. – eXodiquas

Répondre

1

Le code dans votre gestionnaire PointerMoved doit être par rapport à la toile.

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

Si x/y sont négatifs ou supérieurs à la taille de la zone de dessin, ils sont hors limites. Vous pouvez limiter le point à la bordure du canevas comme le fait le code ci-dessus, ou vous pouvez le supprimer complètement.

+0

Votre code fonctionne parfaitement bien, théoriquement. Quand je dessine très lentement sur le bord de la toile, elle coupe parfaitement la ligne. Mais si je dessine très vite, je peux encore sortir des limites. Est-ce que ces événements sont vraiment si lents? – eXodiquas

+0

Cela ne devrait pas être possible. Si vous plafonnez les valeurs x et y du point, elles ne doivent jamais dessiner en dehors des limites du canevas, quelle que soit la vitesse. Avez-vous des bourrelets/marges/transformations affectant le dessin? Peut-être poster un peu plus de code sur la façon dont vous dessinez les lignes et je vais vous aider à déboguer. – Laith

+0

J'ai ajouté plus de détails à ma question. J'espère que cette information vous a aidé. Peut-être est-il important de dire que ma toile obtient sa taille après le chargement de la grille, parce que je n'ai pas trouvé une autre façon d'obtenir une hauteur et une largeur avant que la grille environnante soit construite sur la vue. – eXodiquas