2010-11-05 3 views
1
<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. Пожалуйста, помогите мне, спасибо.Найти контроль внутри ListBox?

+0

Как вы хотите его найти? В коде? – codekaizen

ответ

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, то вы можете использовать дерево визуалов.

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; 
} 
+0

Большое спасибо, я ценю за вас. – doull

9

Пару вещей, чтобы добавить к ответу Meleak (и это было немного слишком долго, чтобы положить в комментарии.)

Обычно, как вы получить именованный элемент из шаблона в WPF является для вызова метода FindName шаблона. Однако, поскольку шаблоны в основном являются фабриками, вам также необходимо указать, какой именно экземпляр требуемого шаблона - один экземпляр ItemsPanelTemplate может быть создан несколько раз. Таким образом, вам понадобится примерно следующее:

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

Но что происходит в этом ??? заполнитель? Это не сам ListBox - ListBox фактически не использует эту ItemsPanel напрямую. В конечном счете, он используется ItemsPresenter в шаблоне ListBox. Так что вам нужно сделать, это:

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

... кроме того, нет никакого надежного способа заполучить ItemsPresenter либо. На самом деле, возможно, даже не может быть одного - законно создавать шаблон для ListBox, который просто предоставляет панель хостинга напрямую - для этой цели существует даже специальное свойство Panel.IsItemsHost.

И это приводит ко второму пункту, который я хотел добавить. В сценариях, где шаблон ListBox не использует ItemPresenter, ItemsPanel будет использоваться не будет. Так что на самом деле возможно, что UniformGrid, который вы пытаетесь заполучить, даже не существует.

+0

Nice add, +1 для этого –

+0

Хороший метод и объясните – doull