WPF - ItemTemplate не работает должным образом
У меня есть UserControl
который я использую для отображения списка UIElement
s. Элемент управления состоит из одного ItemsControl
с этими ItemPanelTemplate
переключился на горизонтальный StackPanel
, его ItemsSource
привязан к DependencyProperty
выставлено UserControl
И его ItemTemplate
установить в UserControl.Resources
,
Все отлично работает кроме ItemTemplate
никогда не применяется, и я не понимаю почему. Полный источник ниже.
UserControl.xaml -
<UserControl x:Name="UC" x:FieldModifier="private" x:Class="ContentSliderControl.ContentSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<DataTemplate x:Key="pageTemplate">
<Border CornerRadius="10" Padding="5" Height="200" Width="200" Background="#333">
<ContentControl Content="{Binding}"/>
</Border>
</DataTemplate>
<ItemsPanelTemplate x:Key="template">
<StackPanel IsItemsHost="True"
Orientation="Horizontal"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"/>
</ItemsPanelTemplate>
</UserControl.Resources>
<ItemsControl ItemsPanel="{StaticResource template}"
ItemTemplate="{StaticResource pageTemplate}"
ItemsSource="{Binding ElementName=UC,Path=Pages}"/>
UserControl.xaml.cs -
[ContentProperty("Pages")]
public partial class ContentSlider : UserControl
{
public List<UIElement> Pages
{
get { return (List<UIElement>)GetValue(PagesProperty); }
//set { SetValue(PagesProperty, value); }
}
// Using a DependencyProperty as the backing store for Pages. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PagesProperty =
DependencyProperty.Register("Pages", typeof(List<UIElement>), typeof(ContentSlider), new UIPropertyMetadata(null));
public ContentSlider()
{
InitializeComponent();
}
}
}
Я использую элемент управления в моем главном окне, как это -
<slider:ContentSlider >
<slider:ContentSlider.Pages>
<Button>1</Button>
<Button>2</Button>
<Button>3</Button>
<Button>4</Button>
</slider:ContentSlider.Pages>
</slider:ContentSlider>
Кнопки выглядят хорошо, но не внутри квадратной границы размером 200 пикселей.
Любая помощь будет очень ценна. Благодарю.
5 ответов
Это потому, что это список UIElement, шаблон элемента применяется, только если элементы не могут быть отображены напрямую.
Нир прав, ItemsControl
добавит элемент непосредственно к его Panel
если они являются элементами UIE. Я не нашел упоминаний об этом поведении в MSDN, но доктор WPF упоминает об этом в своей статье о контейнерах предметов:
Если UIElement добавлен в коллекцию Items явного экземпляра ItemsControl (в отличие от экземпляра производного класса, такого как ListBox), он станет прямым потомком панели элементов. Если не-UIElement добавлен, он будет заключен в ContentPresenter.
Ваше решение, вероятно, заключается в использовании ListBox
вместо этого и установить ItemContainerStyle
к новому Style
за ListBoxItem
и в этом стиле используйте ControlTemplate
с вашим Border
в этом.
Nir прав, эта пользовательская реализация ItemsControl решит проблему и позволит использовать ваш собственный ItemTemplate:
public class ItemsControlForUIElement : ItemsControl
{
protected override DependencyObject GetContainerForItemOverride()
{
return new ContentPresenter();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return false;
}
}
Роберт Макни прибил причину по голове. Его решение включает использование шаблона управления, который может быть излишним для данного сценария. В качестве альтернативы используйте ListBox
- установить ItemContainerStyle
в новый стиль для ListBoxItem
и в этом стиле установите ContentTemplate
к DataTemplate
что вы хотели использовать в ListBox
ItemTemplate
,
Если вы установите DataType
собственность на DataTemplate
это бы начало работать.