2011-01-20 10 views
21

Cada ItemsControl tiene su contenido almacenado en el panel ¿verdad? Podemos especificar el panel para ser utilizado en XAML como esto:¿Cómo obtener una instancia del Panel que contiene el contenido de ItemsControl?

<ListView Name="LView"> 
    <ListView.ItemsPanel> 
     <ItemsPanelTemplate > 
      <StackPanel/> 
     </ItemsPanelTemplate> 
    </ListView.ItemsPanel> 
</ListView> 

Mi pregunta es cómo conseguir instancia de Panel que se utiliza en el ItemsPanel propiedad (de tipo ItemsPanelTemplate) de lo particular ItemsControl? Por ejemplo, ListView llamado LView desde la muestra de código anterior?

no puedo usar Name propiedad o x:Name, esto debe funcionar para cualquier ItemsControl incluso aquellos que utilizan por defecto ItemsPanel.

En el caso de que no esté claro, por favor comenten, creo que hay una solución muy simple. Si parece complicado, es solo porque no puedo explicarlo correctamente.

+0

¿Dónde está usted tratando de conseguir que el ejemplo de? ¿Es de 'ItemsControl' o de una de las plantillas de elementos dentro de él? –

+0

De 'ItemsPanelTemplate' exactamente. Definitivamente no quiero obtenerlo de las plantillas de elementos. – drasto

+0

¿Entendí bien tu pregunta o estabas buscando algo más? –

Respuesta

15

Es un poco complicado ya que no se conoce el nombre del panel de modo que no se puede utilizar FindName etc. Esto funciona para la mayoría de los casos en que un ItemsPresenter está presente

private Panel GetItemsPanel(DependencyObject itemsControl) 
{ 
    ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(itemsControl); 
    Panel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel; 
    return itemsPanel; 
} 

Una implementación de GetVisualChild

private static T GetVisualChild<T>(DependencyObject parent) where T : Visual 
{ 
    T child = default(T); 

    int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
    for (int i = 0; i < numVisuals; i++) 
    { 
     Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
     child = v as T; 
     if (child == null) 
     { 
      child = GetVisualChild<T>(v); 
     } 
     if (child != null) 
     { 
      break; 
     } 
    } 
    return child; 
} 

Sin embargo, el Panel de elementos no siempre se utiliza. Ver this answer por Ian Griffiths para una gran explicación.

2
protected Panel ItemsHost { 
    get { 
     return (Panel) typeof (MultiSelector).InvokeMember("ItemsHost", 
      BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance, 
      null, this, null); 
    } 
} 

Esto funciona como un encanto en mi ItemsControl! Dicho esto, tiene IsItemsHost="True" en el interior de Panel, pero incluso podría funcionar sin él.

truco es de este tema: Can I access ItemsHost of ItemsControl using reflection?

Cuestiones relacionadas