2011-01-20 4 views
21

Ogni ItemsControl ha il suo contenuto memorizzato nel Pannello giusto? Siamo in grado di specificare il pannello da utilizzare in XAML come questo:Come ottenere l'istanza del Pannello che contiene il contenuto di ItemsControl?

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

La mia domanda è come ottenere un'istanza di Panel che viene utilizzato nel ItemsPanel di proprietà (di tipo ItemsPanelTemplate) della particolare ItemsControl? Ad esempio ListView chiamato LView dall'esempio di codice precedente?

non posso usare Name proprietà o x:Name, questo deve funzionare per qualsiasi ItemsControl anche quelli che utilizzano di default ItemsPanel.

Nel caso non sia chiaro si prega di commentare, penso che ci sia una soluzione molto semplice. Se sembra complicato è solo perché non riesco a spiegarlo correttamente.

+0

Dove stai cercando di ottenere tale istanza da? Proviene da 'ItemsControl' o da uno dei modelli di elementi al suo interno? –

+0

Da 'ItemsPanelTemplate' esattamente. Non voglio assolutamente ottenerlo dai modelli di articoli. – drasto

+0

Ho capito correttamente la tua domanda o stavi cercando qualcos'altro? –

risposta

15

E 'un po' difficile in quanto non si conosce il nome del pannello in modo non è possibile utilizzare FindName ecc Questo funziona per la maggior parte dei casi in cui sia presente un ItemsPresenter

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

Un'implementazione di 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; 
} 

Tuttavia, ItemsPanel non viene sempre utilizzato. Vedi this answer di Ian Griffiths per una grande spiegazione.

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

Questo funziona come un fascino nel mio ItemsControl! Detto questo, ha IsItemsHost="True" sul Panel all'interno, ma potrebbe anche funzionare senza di esso.

trucco è da questa discussione: Can I access ItemsHost of ItemsControl using reflection?

Problemi correlati