Оболочка ItemTemplate в UserControl на основе ItemsControl - PullRequest
0 голосов
/ 20 марта 2019

Я работаю над своим собственным пользовательским элементом управления, который происходит от ItemsControl.Чтобы дать краткое описание того, чего я хочу достичь, вот как выглядит XAML прямо сейчас:

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

Это представляет мои данные так, как я хочу, в горизонтальной StackPanel, ничего особенного.В визуальном дереве вы увидите следующее:

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

Теперь я хотел бы изменить XAML моего пользовательского элемента управления так, чтобы дерево выглядело так:

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

цель здесь - создать контейнер-обертку вокруг элемента шаблона.Его поведение будет привязано к внутренним свойствам UserControl, что позволит мне определять поведение элементов, не зависящее от выбора ItemTemplate, сделанного пользователем моего элемента управления.

Я пытался добавить DataTemplates в ContentPresenter в ItemsControl.Resources,но это не удалось.Может ли кто-нибудь помочь мне здесь?:)

1 Ответ

0 голосов
/ 20 марта 2019

Вы можете создать производный ContentPresenter или ContentControl в элементе ItemControl Получить контейнер для переопределения элемента метод:

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;
    }
}

Я бы также предложил перевести производный ItemsControl XAML в стиль по умолчанию в Themes\Generic.xaml (как это сделано по умолчанию для пользовательских элементов управления):

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

Также добавьте

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

к коду управления.

...