2009-03-04 23 views
10

Ho creato uno ListBox che ha un come Itemtemplate. Tuttavia, esiste un modo semplice per accedere allo UIElement generato anziché allo SelectedItem in codebehind?ListBox WPF - Ottenere UIElement invece di SelectedItem

Quando accesso a SelectedItem, ottengo l'oggetto selezionato dalla raccolta ItemsSource. C'è un modo per accedere allo UIElement (ad esempio l'elemento generato dallo DataTemplate insieme all'oggetto associato)?

risposta

11

Stai cercando la proprietà ItemContainerGenerator. Ogni ItemsSource ha un'istanza ItemContainerGenerator. Questa classe ha il seguente metodo che potrebbe interessarti: ContainerFromItem(object instance).

Dopo aver gestito l'ListBoxItem, è possibile andare avanti e visualizzare l'albero logico e visivo. Controlla Logical Tree Helper e Visual Tree Helper.

Come ha detto Andy nei commenti, solo perché l'elemento esiste nella raccolta non significa che un contenitore sia stato generato per esso. Qualsiasi tipo di scenario del pannello di virtualizzazione solleverà questo problema; UIElements saranno riutilizzati tra i diversi elementi. Stai attento anche a questo.

+0

Nota che solo perché un oggetto è stato aggiunto al controllo, che non significa che il suo contenitore interfaccia utente è stato ancora generato. Assicurati di tenere conto del caso in cui non ci sono ancora contenitori UI. – Andy

+0

Sto scrivendo in C# e WPF e questa proprietà non compare in ListBox.ItemsContainer Come ottengo l'istanza per questa listbox? – sprite

+0

@size, hai una soluzione per la mia domanda? http://stackoverflow.com/questions/6148279/record-items-visible-to-user-in-listbox (+250 bounty) – tofutim

4

siz, Andy e Bodeaker assolutamente ragione.

Ecco come sono stato in grado di recuperare la casella di testo dell'elemento selezionato della casella di riepilogo utilizzando il relativo handle.

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 involucro sopra VisualTreeHelper con varie funzioni utili a vista)