Navigare la struttura visuale di un UIElement fino a recuperare l'elemento logico in Silverlight 3.0

di Marco Leoncini, in Silverlight 3.0,

Nel sofisticato sistema di layout di Silverlight esiste una netta distinzione tra elementi logici e visuali. Un esempio di elemento logico è il controllo Button, che deve il suo aspetto all'utilizzo di diversi elementi visuali, come Border, Grid ed altri.

Questa distinzione, se da un lato ci permette di realizzare raffinate interfacce grafiche, può determinare un aumento della complessità nello stabilire quando il mouse si trova sopra un elemento logico.
Tipicamente questo problema si presenta quando viene utilizzato un generico Event Handler a livello di contenitore, per la gestione dell'evento MouseEnter.
In questo caso il primo parametro che riceve l'Event Handler non c'è d'aiuto, poiché è sempre l'elemento al quale è associato l'Event Handler (e non l'oggetto effettivamente sotto il Mouse).

Da questo punto di vista è più utile la proprietà OriginalSource esposta dal tipo MouseEventArgs, che contiene effettivamente un elemento del Visual Tree dell'elemento sotto il mouse.
Per recuperare l'elemento logico partendo dall'elemento visuale, possiamo realizzare un Extension Method che ricorsivamente risalga il Visual Tree fino a raggiungere l'elemento logico.

C#
using System.Windows;
using System.Windows.Media;

namespace SLGuiEditor.Helper
{
  public static class FindLogicalElementFormVisual
  {
    public static T FindLogicaElement<T>(this UIElement parent) where T : UIElement
    {
      var parentElement = (UIElement)VisualTreeHelper.GetParent(parent);
      if (parentElement != null)
      {
        T seachedELement = parentElement as T;
        if (seachedELement != null)
          return seachedELement;
        else { return parentElement.FindLogicaElement<T>(); }
      }
      else
      {
        return null;
      }
    }
  }
}

L'utilizzo di questo Extension Method è semplicissimo, è sufficiente importare il namespace che lo definisce è richiamarlo così:

C#
MyUIElement.FindLogicaElement<Control>();

Il metodo esegue la sua ricerca ricorsiva fermandosi solo quando trova il tipo specificato come argomento generico.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi