Справка по производному пользовательскому элементу управления WPF ItemsControl

#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}"/>