Evitare l’autoscroll della ListBox in WPF
La settimana scorsa ho notato un comportamento standard della ListBox di WPF, che ho sempre accettato in realtà senza rendermene conto, ma che nell’applicazione che stiamo sviluppando non andava troppo bene. In pratica, la ListBox compie uno scroll automatico quando viene selezionato un elemento parzialmente visibile, allo scopo di farlo vedere completamente all’utente. Guardate il video qua sotto.
All’inizio del video, per esempio, viene cliccato e selezionato il numero 6. Trattandosi di un elemento parzialmente renderizzato, e quindi parzialmente visibile, cosa succede? Che WPF fa scorrere la ListBox verso l’alto per fare in modo che l’utente possa vedere l’intero item. La stessa cosa accade poco dopo con il numero 4094, e dopo ancora con il 4125.
Si può evitare questa cosa? Certo che sì.
Si tratta di intercettare l’evento RequestBringToView, che la ListBox scatena proprio nei casi citati sopra. By default, allo scatenarsi di quell’evento (ed in realtà anche di altri, come il GotFocus) la ListBox chiama automaticamente il metodo BringToView(), proprio per portare in visibilità l’elemento selezionato. Il gioco sta nel bloccare questo comportamento predefinito, in questo modo.
1 2 3 4 5 6 | <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <EventSetter Event="RequestBringIntoView" Handler="ListBoxItem_RequestBringIntoView" /> </Style> </ListBox.ItemContainerStyle> |
In pratica grazie ad un piccolo snippet XAML si va ad intercettare l’evento RequestBringToView, facendo eseguire una riga di codice C# che va marcare l’evento come gestito, evitando il normale comportamento della ListBox.
1 2 3 4 5 | private void ListBoxItem_RequestBringIntoView (object sender, RequestBringIntoViewEventArgs e) { e.Handled = true; } |
Questa piccola implementazione vale per ListBox, ListView, GridView, etc. etc.