Question

I have the following ItemsControl, for which I'm using a Canvas as the panel:

<ItemsControl ItemsSource="{Binding Widgets}">
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type widgetLayoutSpike:ColouredWidget}">
            <Grid Background="{Binding BgColour}">
                <TextBlock Text="{Binding Title}" />
            </Grid>
        </DataTemplate>
    </ItemsControl.Resources>

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid Background="Yellow">
                            <!--  <ContentPresenter />  -->
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

My requirements are:

  • ItemTemplates are set via typed DataTemplates (an example one is show above for ColouredWidget item types). There could be several of these for different item types.
  • I need to be able to specify an ItemContainer template, that wraps all of the different ItemTemplates. The specific use case is that I want this ItemContainer to set a common border chrome for all items (with buttons etc).

The Canvas creates a ContentPresenter for each bound item. As you can see above, I had hoped to be able to specify a ContentTemplate for the ContentPresenter in the ItemContainerStyle, but this doesn't work as I assume it essentially creates a circular reference.

Thanks in advance!

Was it helpful?

Solution

It is perhaps easier to do this with a ListBox instead of an ItemsControl as the container type is a ListBoxItem, which (in contrast to ContentPresenter) has a control template that you can replace in your Style:

<ListBox ItemsSource="{Binding Widgets}">
    <ListBox.Resources>
        <DataTemplate DataType="{x:Type widgetLayoutSpike:ColouredWidget}">
            <Grid Background="{Binding BgColour}">
                <TextBlock Text="{Binding Title}" />
            </Grid>
        </DataTemplate>
    </ListBox.Resources>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid Background="Yellow">
                            <ContentPresenter Margin="2"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

Edit: maybe you have to write

<ContentPresenter Margin="2"
                  Content="{TemplateBinding Content}"
                  ContentTemplate="{TemplateBinding ContentTemplate}"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top