Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Silverlight : Contrôle et zone cliquable, astuce...

Une petite astuce toute simple pour aujourd'hui (une fois que l'on connaît la réponse).

Un contrôle très basique pour commencer

Prenons un contrôle, un UserControl carré avec un joli cercle à l'intérieur. Pour que tout cela soit facile à comprendre et à tester, disons que le UserControl fait 200x200 pixels, et que l'ellipse à l'intérieur remplie toute la zone (c'est un cercle donc). Cette ellipse aura un Stroke noir par exemple et une épaisseur de trait de 12. Le LayoutRoot sera un Canvas.

Donc, nous avons : un UserControl de 200x200 contenant un Canvas (toutes les propriétés par défaut), ce Canvas contient une ellipse qui remplit la zone du contrôle, l'ellipse possède un Stroke de 12 en noir. En gros nous avons dessiné un cercle noir sur fond transparent.

"Hou la la ! Mais c'est du super haut niveau tout ça !" ... On ne s'inquiète pas, ça va très vite se compliquer ...

Première petite amélioration : nous allons mettre un curseur personnalisé à notre contrôle. Dans les propriétés du UserControl, propriété Cursor, on choisit Hand, (la main). Et on exécute (F5).

Ca se complique...

Passer la souris au-dessus de votre magnifique contrôle : la main s'affiche bien, mais uniquement lorsque votre souris survole le Stroke du cercle ! Rien à l'intérieur.

Qu'est ce qu'il se passe ?

Pour ce que j'en comprends, tout ce qui n'a pas une brosse n'existe pas. Notre contrôle et le Canvas sous-jacent n'ont pour l'instant aucune couleur de fond (Background). L'ellipse n'a pas de Fill non plus. Tous ces espaces "sans rien" ne sont visiblement pas détectés. Bug ou feature, après tout ça peut être l'un ou l'autre selon le point de vue...

Mais comment régler le problème ?

En fait qu'importe qu'il s'agisse d'un problème ou d'un choix délibéré des concepteurs, nous devons remplir ces "riens" si nous voulons que le curseur de souris (et la zone cliquable du contrôle) apparaisse sur toute la surface.

Mais il est hors de question d'aller placer une brosse, donc une couleur, pour faire ce travail ! On pourrait bien entendu mettre un Background blanc au Canvas, cela règlerait le problème. Mais si nous changeons le fond de notre page, nous allons obtenir un cercle dans un carré blanc sur un fond différent. Une horreur. Quant à s'enliser dans l'erreur pour faire en sorte de trouver une astuce pour que le fond de notre UserControl soit synchro avec celui de son conteneur parent...

Une "fausse" brosse

Il faut remplir notre ellipse pour que le curseur soit visible et que même son espace intérieur soit cliquable. Mais pas avec n'importe quoi. Xaml nous fournit une brosse un peu spéciale, disons une "non brosse", ou une "fausse" brosse puisque visuellement elle ne se voit pas. Il s'agit de la brosse "Transparent".

Dès lors, il suffit d'ajouter dans le code Xaml de notre ellipse Fill="Transparent" et de relancer l'application. Miracle ! Le curseur en forme de main est visible même à l'intérieur de l'ellipse. Et si nous changeons la couleur de fond de la page, comme cette brosse est transparente, on n'y verra que du feu ...

Sous Blend vous pouvez agir directement dans le code Xaml ou bien simplement cliquer sur le carré de binding de la propriété Fill et choisir "custom expression". Tapez "Transparent" (sans les guillemets) dans le champ de saisie et l'affaire est jouée.

Comme quoi, même un UserControl ne contenant qu'un cercle peut déjà soulever des problèmes pas si simples à résoudre. Ca force à l'humilité... :-)

Stay Tuned !

blog comments powered by Disqus