2010-01-08 3 views
1

Je crée actuellement une application WPF de type MSPaint et je suis aux prises avec l'implémentation d'une grille pouvant être capturée. La peinture de la grille n'est pas un problème avec un VisualBrush et un Rectangle mais le problème est que ces lignes sont alors purement pour l'apparence et ne peuvent pas être changées facilement (par exemple en surbrillance lorsque l'alignement sur une ligne spécifique est déclenché) . Mon autre idée était d'avoir une solution 2 Canvas où 1 Canvas est utilisé pour les éléments et un Canvas (qui est positionné au-dessus de l'autre) contient toutes les lignes de la grille. Cependant j'ai le sentiment que cela signifierait un coup de performance.WPF: Création de lignes de quadrillage pouvant être interceptées avec un espacement variable

Existe-t-il d'autres moyens d'implémenter ce type de fonctionnalité?

Répondre

2

considérations d'efficacité d'une approche à deux panneaux vs DrawingContext

J'ai de bonnes nouvelles pour vous: Vous avez tort au sujet de la perte de performance significative. Votre idée de deux canevas est presque optimale, même si vous utilisez des objets individuels pour les lignes de la grille. C'est parce que WPF utilise le rendu en mode retenu: Lorsque vous créez le canevas, tout ce qui y est est sérialisé dans une structure compacte au niveau natif. Cela ne change que lorsque vous modifiez les lignes de la grille d'une manière ou d'une autre, par exemple en modifiant l'espacement de la grille. Dans tous les autres cas, les performances seront indiscernables des méthodes de code managé les plus rapides possibles.

Une légère augmentation des performances pourrait être obtenue en utilisant DrawingContext comme décrit par Nicholas.

plus simple et plus solution efficace

Peut-être une meilleure façon puis tracer des lignes individuelles sur la toile de la grille est d'utiliser deux brosses visuelles carrelés (horizontale, verticale) pour dessiner toutes les lignes unhilighted, puis utilisez Rectangle (s) ajouté (s) dans code-behind pour hilight la ligne (s) que vous accrochez à. Le principal avantage de cette technique est que votre grille peut être effectivement infinie, il n'est donc pas nécessaire de calculer le bon nombre de lignes de la grille pour dessiner puis mettre à jour chaque fois que la fenêtre se redimensionne ou que le zoom change. Vous n'avez également que trois UIElements impliqués, plus un de plus pour chaque ligne de la grille qui est actuellement hilighted. Cela me semble aussi plus propre que de suivre les collections de lignes de la grille. La raison pour laquelle vous voulez utiliser deux pinceaux visuels est que le dessin est plus efficace: Le pinceau dessinant les lignes verticales est étiré sur une grande distance (par exemple double.MaxValue/2) dans le sens vertical pour que le GPU ne reçoive qu'un appel de dessin par ligne verticale, la même chose pour l'horizontal. Faire un carrelage à deux voies est beaucoup moins efficace.

couche Adorner

Depuis que vous avez demandé des alternatives, une autre possibilité est d'utiliser Adorner et AdornerLayer avec l'une des solutions ci-dessus plutôt que empiler votre toile en utilisant par exemple une grille ou contenant toile. Pour une application semblable à Paint, c'est bien parce que la couche adorner peut être au-dessus de votre couche graphique (s), mais les ornements peuvent toujours attacher à des éléments individuels qui sont affichés.

+0

Je ne comprends pas vraiment votre idée avec 2 pinceaux visuels. Peux-tu être plus précis? Je ne savais même pas qu'il y avait un moyen d'utiliser 2 pinceaux visuels différents sur un seul panneau. – chrischu

+0

Si vous utilisez '' vous pouvez le remplacer par ' 'pour dessiner deux rectangles chacun avec son propre pinceau visuel. HorizBrush sera transparent à l'exception d'une zone de largeur de la ligne de quadrillage en haut et VertBrush sera transparent à l'exception d'une zone de largeur de ligne de la grille à gauche. Viewport/Viewbox et la mosaïque seront définies de sorte que chaque pinceau soit répété à l'intervalle de ligne de quadrillage approprié dans la direction donnée, créant ainsi une grille. –

+0

Notez qu'il peut y avoir des moyens plus efficaces pour effectuer la mise en page que d'utiliser un '' séparé. Par exemple, il peut exister un '' que vous pouvez partager, ou un ''. –

1

Vous pouvez envisager de dessiner votre grille à l'aide du DrawingContext à l'intérieur de OnRender. Dessiner de cette manière n'introduit pas de nouveaux UIElements dans l'arbre visuel, ce qui aide à maintenir les performances. À certains égards, il est similaire à ce que vous faites actuellement avec VisualBrush, qui ne crée pas non plus de nouveaux éléments d'interface utilisateur par copie. Cependant, comme vous dessinerez chaque ligne individuellement au lieu de copier l'apparence d'une seule ligne, vous pourrez mettre en surbrillance la ou les lignes de quadrillage qui participent à l'accrochage sans changer les couleurs de celles qui le font. ne pas.

Si vous allez aller dans cette voie, assurez-vous d'avoir un regard sur GuidelineSet s pour le positionnement de vos lignes de guidage (plus de détails here), puisque vous aurez probablement envie d'avoir vos lignes de guidage encliqueter aux pixels de l'appareil afin qu'ils dessinent nettement.

Questions connexes