В чем разница между ItemTemplate и ItemPanelTemplate?

В WPF Listbox я смущен этими двумя понятиями: ItemTemplate и ItemsPanelTemplate Может кто-нибудь объяснить мне больше?

Спасибо Джон

Ответы

Ответ 1

Позвольте мне объяснить это на примере:

<ListBox ItemsSource="{Binding}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Border Background="SteelBlue" Padding="5" BorderBrush="Black"
        BorderThickness="1" Margin="0,2">
        <TextBlock Text="{Binding}"/>
      </Border>
    </DataTemplate>
  </ListBox.ItemTemplate>
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Background="DarkKhaki"/>
    </ItemsPanelTemplate>
  </ListBox.ItemsPanel>
</ListBox>

И результат:

WPF ListBox templates example

ItemTemplate определяет расположение каждого элемента в списке. С другой стороны, ItemsPanel - панель, которая будет содержать отдельные элементы. Учитывая указанное выше определение, визуальное дерево будет чем-то похожее на это:

<StackPanel>
  <Border>
    <TextBlock Text="Alpha"/>
  </Border>
  <Border>
    <TextBlock Text="Beta"/>
  </Border>
  ....
</StackPanel>

Ответ 2

ItemTemplate используется для указания DataTemplate, используемого для визуализации элемента в вашем ListBox. ItemPanelTemplate используется для указания панели, используемой для размещения дочерних элементов вашего списка ListBox.

Например, если ваш ListBox привязан к ObservableCollection, вы должны указать DataTemplate, чтобы рассказать ему, как визуализировать каждый объект Person.

<ListBox ItemsSource={Binding Persons}>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel>
        <TextBlock Text={Binding FirstName}/>
        <TextBlock Text={Binding LastName}/>
        <TextBlock Text={Binding Age}/>
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Это упорядочивает каждый элемент по вертикали, потому что ListBox по умолчанию использует StackPanel. Если вы хотите изменить это поведение, используйте свойство ItemPanelTemplate:

<ListBox>
  <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal"/>
    </ItemsPanelTemplate>            
  </ListBox.ItemsPanel>
</ListBox>

Вы даже можете изменить StackPanel на любую другую панель (например, WrapPanel).