在ListBox中查找控件?

时间:2010-11-05 08:49:35

标签: wpf listbox controls find

   <Style TargetType="ListBoxItem" x:Key="ListBoxItemTemplate">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Button Content="{TemplateBinding Content}"></Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>     
    <ListBox ItemsSource="{Binding S}" 
             x:Name="listBox" 
             ItemContainerStyle="{StaticResource ListBoxItemTemplate}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid x:Name="grid" Columns="5"></UniformGrid>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

我想从ListBox Control中找到“grid”。请帮助我,谢谢。

2 个答案:

答案 0 :(得分:10)

在Meleak的回答中添加了一些内容(这有点太长了,无法发表评论。)

通常,从WPF中的模板获取命名元素的方法是调用模板的FindName方法。但是,因为模板基本上是工厂,所以您还需要说明您需要的模板的哪个特定实例 - 单个ItemsPanelTemplate可能已经多次实例化。所以你需要这样的东西:

var grid = (UniformGrid) listBox.ItemsPanel.FindName("grid", ???);

但那是什么???占位?它不是ListBox本身 - ListBox实际上并不直接使用ItemsPanel。最终,它由ListBox模板中的ItemsPresenter使用。所以你需要这样做:

var grid = (UniformGrid) listBox.ItemsPanel.FindName("grid", myItemsPresenter);

...除此之外,没有可靠的方法来获取ItemsPresenter。事实上,甚至可能没有一个 - 为ListBox创建一个直接提供托管面板的模板是合法的 - 为了这个目的,甚至还有一个特殊的属性Panel.IsItemsHost。

这导致我想要添加的第二点。在ListBox的模板不使用ItemsPresenter的情况下,ItemsPanel将不使用。所以实际上你想要掌握的UniformGrid实际上是不可能存在的。

答案 1 :(得分:4)

一种方法是在加载后将其存储在代码中。

<ListBox ItemsSource="{Binding S}"  
         x:Name="listBox"  
         ItemContainerStyle="{StaticResource ListBoxItemTemplate}"> 
    <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
            <UniformGrid x:Name="grid" Columns="5" Loaded="grid_Loaded"></UniformGrid> 
        </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox> 

在代码背后

private UniformGrid m_uniformGrid = null;  
private void grid_Loaded(object sender, RoutedEventArgs e) 
{ 
    m_uniformGrid = sender as UniformGrid; 
} 

如果要从ListBox中找到它,则可以使用Visual Tree。

UniformGrid uniformGrid = GetVisualChild<UniformGrid>(listBox);

public static T GetVisualChild<T>(object parent) where T : Visual
{
    DependencyObject dependencyObject = parent as DependencyObject;
    return InternalGetVisualChild<T>(dependencyObject);
}
private static T InternalGetVisualChild<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;
}