简体   繁体   中英

ItemTemplate Wrapper in UserControl Based on ItemsControl

I am working on my own user control which derives from ItemsControl. To give a brief description of what I want to achieve here is what the XAML looks like right now:

<ItemsControl x:Class="MyApp.MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyApp"
             mc:Ignorable="d"
             d:DesignHeight="60" d:DesignWidth="600">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate>
            <Grid>
                <Border Background="{TemplateBinding Background}" 
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ItemsPresenter/>
                </Border>
            </Grid>
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

This presents my data the way I want to, in a horizontal StackPanel, nothing fancy. In the visual tree you'll see this:

  ItemsControl
    [...Other Visual Item in The Tree...]
    ItemsPresenter
      ContentPresenter
         Item1 (ItemTemplate)
      ContentPresenter
         Item2 (ItemTemplate)

Now I would like to modify the XAML of my user control so that the tree would look like this:

  ItemsControl
    [...Other Visual Item in The Tree...]
    ItemsPresenter
      ContentPresenter
         SomeContainerDefinedInMyUserControlXAML
           Item1 (ItemTemplate)
      ContentPresenter
         SomeContainerDefinedInMyUserControlXAML
           Item2 (ItemTemplate)

The goal here is to have a wrapper container around the templated item. Its behavior would be bound to internal properties of the UserControl, allowing me to define item behaviors immune to the ItemTemplate choice made by the user of my control.

I was trying to add DataTemplates on ContentPresenter in ItemsControl.Resources, but that failed. Could someone help me out here? :)

You may create a derived ContentPresenter or ContentControl in the ItemControl's Get​Container​For​Item​Override method:

public class MyContainer : ContentControl
{
}

public class MyItemsControl : ItemsControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new MyContainer();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is MyContainer;
    }
}

I'd also suggest to move the derived ItemsControl's XAML to a default Style in Themes\\Generic.xaml (as done by default for custom controls):

<Style TargetType="local:MyItemsControl">
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyItemsControl">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ItemsPresenter/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Also add

static MyItemsControl()
{
    DefaultStyleKeyProperty.OverrideMetadata(
        typeof(MyItemsControl),
        new FrameworkPropertyMetadata(typeof(MyItemsControl)));
}

to the control's code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM