2
votes


I would like to write a ItemsControl derived custom control. This is partially from need and partially as a learning exercise - please don't suggest I Style, DataTemplate, ControlTemplate a ListBox etc... I.e. please don't question the need - just assume its genuine.
I've trolled the web and found lots of useful ItemControl info but no clear cut examples. When I create I new Custom Control in VS I get practically empty code behind and Generic.xaml with a <Style> block where its possible to set ControlTemplates, DataTemplates, Presenters etc via <Setter Property="Template"> etc. But what is the minimum xaml/code needed here to get a control that will bind to an ObservableCollection to ItemsSoruce to display as a list? Put another way: whats the canoical form of a ItemsControl derived custom control?
Do I need an ItemsPresenter? Do I have to specify a stack pannel in the ControlTemplate? Do I have to set TargetType on the <Setter Property="ItemTemplate">? etc.
Spoon feeding prefered eg saying: its easy and I just need to intergrate the DataTemplate over the vector space of item control containers with respect to the panel presenter yada yada... aint a great help. Further info: The control is a display only orientated ie there is no concept of selected item etc. Thanks in advance!

Default Generic.xaml (whats minimum to add here?):

<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>
2

2 Answers

3
votes

Just take a look at the default styles (follow the Default WPF Themes link):

e.g. 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>
0
votes

Adding the default style as H.B suggests works and renders the control usable (items display). Removing the ItemsPresenter (inside the ScrollViewer) breaks the control (no content display). This post explains whats going on: http://drwpf.com/blog/2009/05/12/itemscontrol-l-is-for-lookless/
Essentially the ControlTemplate must have either:
a) an ItemPresenter OR
b) a panel with IsItemsHost property set true.
I.e the bare minimum you need to add to the stye is a ControlTemplate with either:
<StackPanel IsItemsHost="True" />
OR
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>