#wpf #custom-controls #itemscontrol
#wpf #пользовательские элементы управления #itemscontrol
Вопрос:
Я хотел бы написать пользовательский элемент управления, производный от ItemsControl. Это частично по необходимости, а частично в качестве учебного упражнения — пожалуйста, не предлагайте мне использовать Style, DataTemplate, ControlTemplate для ListBox и т.д. … Т.Е., пожалуйста, не подвергайте сомнению необходимость — просто предположите, что она подлинная.
Я прошерстил Интернет и нашел много полезной информации о ItemControl, но никаких четких примеров. Когда я создаю новый пользовательский элемент управления в VS, я получаю практически пустой код и Generic.xaml с <Style>
блоком, в котором можно устанавливать ControlTemplates, DataTemplates, презентаторы и т.д. Через <Setter Property="Template">
etc. Но какой минимальный xaml / код необходим здесь, чтобы получить элемент управления, который будет привязываться к ObservableCollection к ItemsSoruce для отображения в виде списка? Другими словами: какова каноническая форма пользовательского элемента управления, производного от ItemsControl?
Нужен ли мне ItemsPresenter? Должен ли я указывать панель стека в ControlTemplate? Должен ли я устанавливать TargetType для <Setter Property="ItemTemplate">
? и т.д.
Предпочтительнее подавать с ложечки, например, говоря: это просто, и мне просто нужно интегрировать DataTemplate в векторное пространство контейнеров элементов управления относительно панели presenter, yada yada … не очень помогает. Дополнительная информация: Элемент управления ориентирован только на отображение, т. Е. нет понятия выбранного элемента и т.д. Заранее спасибо!
Общий файл по умолчанию.xaml (что минимум нужно добавить сюда?):
<Style TargetType="{x:Type local:MyItemsControlDerivedClass}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyItemsControlDerivedClass}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Ответ №1:
Просто взгляните на стили по умолчанию (перейдите по Default WPF Themes
ссылке):
например, ListBox:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true"
Padding="1">
<ScrollViewer Padding="{TemplateBinding Padding}"
Focusable="false">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
<Trigger Property="IsGrouping"
Value="true">
<Setter Property="ScrollViewer.CanContentScroll"
Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Комментарии:
1. Спасибо HB — это очень помогло в том, что добавление этого кода работает и удаление его фрагментов до сбоя позволило мне найти необходимые части (см. Мой собственный ответ).
Ответ №2:
Добавление стиля по умолчанию, как предлагает H.B, работает и делает элемент управления пригодным для использования (элементы отображаются). Удаление ItemsPresenter (внутри ScrollViewer) приводит к разрыву элемента управления (не отображается содержимое). В этом посте объясняется, что происходит: http://drwpf.com/blog/2009/05/12/itemscontrol-l-is-for-lookless /
По сути, ControlTemplate должен иметь либо:
a) ItemPresenter, ЛИБО
b) панель, для свойства IsItemsHost которой установлено значение true.
Т.е. минимальный элемент, который вам нужно добавить в stye, — это ControlTemplate с любым:
<StackPanel IsItemsHost="True" />
или
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>