2011-06-13 2 views
2

J'ai récemment développé un composant de dessin pour mon entreprise, avec un canevas sur lequel vous pouvez dessiner certaines formes en cliquant-glissant. Pour chaque forme, j'ai placé deux ornements sur son AdornerLayer: Un pour la détection de coup accru (essentiellement un rectangle transparent qui dépasserait les limites de la forme de quelques pixels), et un autre pour le redimensionnement (quatre contrôles Thumb sur les coins). Mais, j'ai rencontré de nombreux problèmes lors de l'implémentation de certaines des fonctionnalités du composant, toutes liées à l'adorer.À quoi servent les ornements WPF?

  • Ils ont capturé tous les événements aperçu, car ils se trouvaient dans un autre arbre visuel que la toile elle-même, qui était inattendu, mais je trouve une solution, même si je ne l'aimais pas beaucoup. Utilisation d'un AdornerDecorator n'a pas résolu ce problème, un adorateur de sélection que j'ai mis en œuvre est un trou noir pour les événements de prévisualisation. Lorsque j'ai implémenté la manipulation des formes sur le canevas par l'index z (envoi vers l'arrière, mise en avant, etc.), cela a bien fonctionné avec Panel.SetZIndex, comme vous pouvez vous y attendre. Mais, les ornements sont dans un autre arbre visuel! donc ils n'étaient pas affectés et les ornements de sélection étaient TOUJOURS au-dessus de toutes les autres formes, même si ces formes étaient au-dessus de celle pour laquelle l'amateur de sélection détectait des hits. Par exemple: Shape1, SelectionAdorner1. Shape2, SelectionAdorner2. Shape1 est sur le dessus (ajouté plus tard à la toile) de Shape2, donc il se chevauche. Donc un clic dessus sera détecté par SelectionAdorner1. J'ai manipulé le ZIndex pour l'envoyer en arrière, maintenant Shape2 est sur le dessus et chevauche Shape1. Je clique en haut de Shape2, mais le clic est détecté par SelectionAdorner1 au lieu de SelectionAdorner2. C'était particulièrement agaçant. Donc, apparemment depuis que les Adorners sont sur un autre arbre visuel, ils ne respectent pas ZIndexes. J'ai essayé de le résoudre en créant un DataBinding (et aussi en réglant manuellement) entre le ZIndex de la forme et le ZIndex de son SelectionAdorner. Mais cela n'a pas résolu le problème. Changer le ZIndex d'Adorners n'affectait pas la façon dont ils étaient affichés à l'écran, peut-être qu'il me manquait quelque chose, mais ça ne devrait pas être si difficile, puisque les Adorners sont censés être faits pour faciliter les choses. La seule solution que je pouvais trouver était de supprimer manuellement tous les ornements et de les rajouter manuellement un par un, en ajoutant pour finir celui qui était censé être en haut. C'était retardé, mais ça a marché.

  • Ensuite, les Adorners ne respectent pas ClipToBounds! J'ai mis ClipToBounds = true dans le Canevas sur lequel je dessinais, et ça a bien fonctionné, mais les putains d'ornements continueraient à fonctionner! La solution à ce problème était relativement indolore, j'ai juste ajouté un AdornerDecorator sur chaque forme. Pas une solution idéale IMO, mais celle qui était assez simple.

  • Les ornements ne réagissent pas toujours bien aux LayoutTransforms effectués sur leurs éléments ornés. J'ai un panneau sur le dessus de la toile qui implémente la fonctionnalité de Zoom et Pan. Il a utilisé des animations pour faire un zoom avant et arrière plus lisse. Mais en utilisant des animations, mes Adorners sont devenus des singes! Le premier zoom, ils ignoreraient simplement le redimensionnement et resteraient de la même taille et la position, sur le deuxième zoom, ils seraient à l'échelle de la précédente taille de l'élément orné. Cela n'a aucun sens! seule solution que je pouvais trouver était de désactiver les animations, qui, heureusement, a travaillé

Je ne me souviens pas tout à fait que d'autres questions que j'avais, mais cela était plus que suffisant pour me mame interroger sur l'utilité de Adorners, et je J'envisage sérieusement de ne pas les utiliser dans mon prochain projet, qui est similaire à celui que j'ai décrit. Donc, quelqu'un peut-il me dire ce qui pourrait être les avantages de l'utilisation de ces choses apparemment utiles mais incroyablement ennuyeux?

Merci.

Répondre

6

Je pense que vous connaissez déjà la réponse à votre question. Ils gagnent du temps à certains égards et causent des problèmes dans d'autres. Si vous deviez coder ce comportement de concepteur en utilisant une variété de UserControls, vous vous retrouveriez à écrire beaucoup de classes de contrôle standard pour envelopper les éléments que vous vouliez éditer. Si, d'un autre côté, vous essayez d'écrire des commandes d'édition séparées et de les superposer intelligemment, vous écrivez un code standard pour conserver la synchronisation de leurs positions et de leurs tailles. L'approche que vous avez adoptée, en utilisant des ornements, a abouti à beaucoup de code (assez passablement) pour gérer les événements.

Bien que les ornements ne soient pas le meilleur outil pour cette tâche , ils constituent toujours un outil utile pour d'autres tâches plus simples. J'ai récemment écrit un genre similaire de "surface de conception" et les ornements ont été une aubaine pour deux pièces:

  1. Le comportement de glisser-déposer. Lorsque je traînais différents éléments, ils devaient avoir des aperçus visuels différents; C'était remarquablement facile à accomplir en utilisant un adorateur personnalisé et des modèles de données.
  2. Le rectangle de sélection ou "lasso". Vous pouvez voir quelque chose de similaire lorsque vous maintenez le bouton gauche de la souris sur un bureau Windows et faites glisser le pointeur. Il crée une boîte semi-transparente qui peut sélectionner plusieurs éléments. J'ai été capable de créer ce comportement presque instantanément avec la couche adorner, alors que la création de mon propre contrôle personnalisé a entraîné beaucoup de comptabilité inutile.

Je pense que ce que vous avez découvert dans votre projet est que vous utilisiez peut-être des ornements pour essayer d'accomplir trop de choses. Mais ne jetez pas le bébé avec l'eau du bain - ils sont encore très utiles dans certains scénarios.

+0

Vous avez très raison, vos exemples d'où ils pourraient être utiles m'intéressent, et particulièrement puisque j'aurais besoin de quelque chose comme ça pour le glisser-déposer, merci pour le conseil. –