WPF ListBox - Ottenere UIElement invece di SelectedItem
-
03-07-2019 - |
Domanda
Ho creato un ListBox
che ha un DataTemplate
come Itemtemplate
. Tuttavia, esiste un modo semplice per accedere al UIElement
generato anziché al SelectedItem
in codebehind?
Quando accedo a SelectedItem
, ottengo semplicemente l'oggetto selezionato dal mio
Raccolta ItemsSource
. Esiste un modo per accedere al UIElement
(cioè
elemento generato da DataTemplate
insieme all'oggetto associato)?
Soluzione
Stai cercando ItemContainerGenerator proprietà. Ogni ItemsSource
ha un ItemContainerGenerator istanza. Questa classe ha il seguente metodo che potrebbe interessarti: ContainerFromItem (istanza dell'oggetto) .
Una volta che hai un handle per ListBoxItem
, puoi andare avanti e sfogliare l'albero logico e visivo. Dai un'occhiata a Logical Tree Helper e Visual Tree Helper .
Come ha detto Andy nei commenti, solo perché l'oggetto esiste nella tua raccolta non significa che è stato generato un contenitore per esso. Qualsiasi tipo di scenario del pannello di virtualizzazione solleverà questo problema; Gli UIElement verranno riutilizzati tra i diversi elementi. Fai attenzione anche a questo.
Altri suggerimenti
siz , Andy e Bodeaker hanno assolutamente ragione.
Ecco come sono stato in grado di recuperare la casella di testo dell'elemento selezionato della casella di riepilogo usando la sua maniglia.
var container = listboxSaveList.ItemContainerGenerator.ContainerFromItem(listboxSaveList.SelectedItem) as FrameworkElement;
if (container != null)
{
ContentPresenter queueListBoxItemCP = VisualTreeWalker.FindVisualChild<ContentPresenter>(container);
if (queueListBoxItemCP == null)
return;
DataTemplate dataTemplate = queueListBoxItemCP.ContentTemplate;
TextBox tbxTitle = (TextBox)dataTemplate.FindName("tbxTitle", queueListBoxItemCP);
tbxTitle.Focus();
}
(Nota: qui VisualTreeWalker è il mio wrapper su VisualTreeHelper con varie utili funzioni esposte)