bytecode77
bytecode77

Reputation: 14820

WPF ItemsControl bound to UserControls

An ItemsControl binding to a collection of UserControl objects works fine. However, I would like to apply additional XAML, such as a Border, etc.

However, instead of a Border with the UserControl, only the UserControl itself is rendered. The <ItemsControl.ItemTemplate> does not seem to have any effect.

Question: How can I design an ItemTemplate with additional XAML? Currently, this tag seems to be "ignored".


ViewModel: ObservableCollection<UserControl> MyUserControls

<ItemsControl ItemsSource="{Binding MyUserControls, lementName=popupContainer}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border ...>
                <ContentControl Content="{Binding}" />
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Upvotes: 0

Views: 397

Answers (1)

Clemens
Clemens

Reputation: 128013

A look at the reference source reveals that the IsItemItsOwnContainerOverride method of the ItemsControl class has this implementation:

protected virtual bool IsItemItsOwnContainerOverride(object item)
{
    return (item is UIElement);
}

So if you pass a collection of UIElements to the ItemsSource of an ItemsControl, these elements are used directly as item containers, without the usual wrapping inside a ContentPresenter. Hence no ItemTemplate is applied at all.

So the answer to the question

How can I design an ItemTemplate with additional XAML?

is: Not at all if the ItemsSource is a collection of UIElements.

You should instead follow the basic idea of the ItemsControl class, and assign a collection of data item objects to the ItemsSource property. Then select appropriate UI controls by DataTemplates that have their DataType property set to the types of the different data items.


Or you create a derived ItemsControl which overrides the IsItemItsOwnContainerOverride method:

public class MyItemsControl : ItemsControl
{
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return false;
    }
}

Upvotes: 1

Related Questions