2009-03-04 15 views
10

Creé un ListBox que tiene un DataTemplate como Itemtemplate. Sin embargo, ¿hay una manera fácil de acceder al UIElement generado en lugar del SelectedItem en código subyacente?WPF ListBox - Obtención de UIElement en lugar de SelectedItem

Cuando tengo acceso a SelectedItem, obtengo el objeto seleccionado de mi ItemsSource colección. ¿Hay alguna manera de acceder al UIElement (es decir, el elemento generado a partir del DataTemplate junto con el objeto enlazado)?

Respuesta

11

Está buscando la propiedad ItemContainerGenerator. Cada ItemsSource tiene una instancia ItemContainerGenerator. Esta clase tiene el siguiente método que podría interesarle: ContainerFromItem(object instance).

Una vez que tenga un identificador en el ListBoxItem, puede continuar y explorar el árbol lógico y visual. Consulte Logical Tree Helper y Visual Tree Helper.

Como dijo Andy en los comentarios, el hecho de que el artículo exista en su colección no significa que se haya generado un contenedor para él. Cualquier tipo de escenario de panel de virtualización planteará este problema; Los elementos de UIE se reutilizarán en los diferentes elementos. Ten cuidado con eso también.

+0

Tenga en cuenta que sólo porque un elemento ha sido añadido al control, eso no quiere decir que su contenedor de la interfaz de usuario ha sido generado aún. Asegúrese de dar cuenta del caso donde aún no hay un contenedor de UI. – Andy

+0

Escribo en C# y WPF y esta propiedad no aparece en ListBox.ItemsContainer ¿Cómo obtengo la instancia para este listbox? – sprite

+0

@size, ¿tiene una solución para mi pregunta? http://stackoverflow.com/questions/6148279/record-items-visible-to-user-in-listbox (+250 bounty) – tofutim

4

Tam, Andy y Bodeaker toda la razón.

Así es como pude recuperar el cuadro de texto del elemento seleccionado del cuadro de lista usando su identificador.

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: Aquí, VisualTreeWalker es mi propio envoltorio sobre VisualTreeHelper con varias funciones útiles expuestas)

Cuestiones relacionadas