Utilizzare un behavior per selezionare l'elemento padre di un DataTemplate in Silverlight 4.0

di Alessio Leoncini, in Silverlight 4.0,

Nello script #97 (https://www.silverlightitalia.com/script/97/Cambiare-Programmaticamente-DataTemplate-Controllo-Silverlight-4.0.aspx) abbiamo visto come i DataTemplate possano contenere qualsiasi controllo di cui si abbia bisogno, anche all'interno di un ListBox. L'insieme dei controlli definiti nel template viene inserito nel ListBoxItem.

Nel caso di una ListBox, come nell'esempio dello script #97, qualora il template contenga controlli che possano catturare il focus, come un TextBox, il click diretto del mouse sul TextBox stesso da parte dell'utente non causa la selezione del ListBoxItem contenitore.
Questo comporta un disallineamento visivo, l'utente sta interagendo con un controllo diverso da quello selezionato nella lista, oltre chè ad eventuali disallineamenti funzionali basati sulla corrispondenza dell'elemento selezionato, ad esempio come funzioni personalizzate di copia/incolla.

Per allineare il ListBoxItem selezionato con il controllo contenuto su cui l'utente ha posizionato il mouse possiamo utilizzare il seguente behavior da associare direttamente al controllo contenuto:

public class SelectListBoxItemParentBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.GotFocus += new RoutedEventHandler(AssociatedObject_GotFocus);
    }

    void AssociatedObject_GotFocus(object sender, RoutedEventArgs e)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(this.AssociatedObject);

        while (parent != null)
        {
            parent = VisualTreeHelper.GetParent(parent);
            if (parent is ListBoxItem)
            {
                ((ListBoxItem)parent).IsSelected = true;
                break;
            }
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        this.AssociatedObject.GotFocus -= new RoutedEventHandler(AssociatedObject_GotFocus);
    }
}

Il punto chiave consiste nel risalire la gerarchia dei controlli parent, con la classe VisualTreeHelper, al momento del focus sul controllo, fino a trovare un ListBoxItem di cui impostare la proprietà IsSelected.

Il suo utilizzo nel codice è come di consueto:

<ListBox x:Name="listBox"
            ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding FirstName, Mode=OneWay}">
                <i:Interaction.Behaviors>
                    <local:SelectListBoxItemParentBehavior />
                </i:Interaction.Behaviors>
            </TextBox>
        </DataTemplate>
    </ListBox.ItemTemplate>


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