将多个 CustomUserControl 模板合并为一个模板

Combine multiple CustomUserControl templates into a single template

我有一个带有两个模板的自定义用户控件,我想将它们一起用于选项卡控件中的每个项目。我一次只能用一个。

CustomUserControl.xaml.cs

public partial class CustomUserControl : UserControl
{
    public CustomUserControl ()
    {
        InitializeComponent();
        var style = (Style)FindResource("Styling");
        Style = style;
    }

    public static readonly DependencyProperty ItemHeaderTemplateProperty = DependencyProperty.Register(
        nameof(ItemHeaderTemplate), typeof(DataTemplate),
        typeof(ConfigurableCollectionControl), new PropertyMetadata(default(DataTemplate)));

    public DataTemplate ItemHeaderTemplate
    {
        get => (DataTemplate) GetValue(ItemHeaderTemplateProperty);
        set => SetValue(ItemHeaderTemplateProperty, value);
    }

    public static readonly DependencyProperty ItemContentTemplateProperty = DependencyProperty.Register(
        nameof(ItemContentTemplate), typeof(DataTemplate),
        typeof(ConfigurableCollectionControl), new PropertyMetadata(default(DataTemplate)));

    public DataTemplate ItemContentTemplate
    {
        get => (DataTemplate) GetValue(ItemContentTemplateProperty);
        set => SetValue(ItemContentTemplateProperty, value);
    }
}

我可以像这样在选项卡控件中引用其中之一:

CustomUserControl.xaml

<Style x:Key="Styling" TargetType="{x:Type local:CustomUserControl}">
    <Setter Property="Template">
        <Setter.Value>          
            <ControlTemplate TargetType="{x:Type local:CustomUserControl}">
                
                <TabControl Style="{Static CustomStyle}"
                            ItemsSource="{Binding Items}"
                            ContentTemplate="{TemplateBinding ItemContentTemplate}"/>                    
            
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

注意:我是从主页引用它的,如下所示: MainPage.xaml

<test:CustomUserControl Content="{Binding}"
                        ItemHeaderTemplate="{StaticResource TestHeaderTemplate}"
                        ItemContentTemplate="{StaticResource TestContentTemplate}"/>

我试过像这样使用 DataTemplate 引用它们,但项目无法编译:

CustomUserControl.xaml

<DataTemplate x:Key="TestTemplate" DataType="{x:Type local:CustomUserControl}">
    <StackPanel>
        <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ItemHeaderTemplate}"/>
        <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ItemContentTemplate}"/>
    </StackPanel>
</DataTemplate>

<Style x:Key="Styling" TargetType="{x:Type local:CustomUserControl}">
    <Setter Property="Template">
        <Setter.Value>          
            <ControlTemplate TargetType="{x:Type local:CustomUserControl}">
                
                <TabControl Style="{Static CustomStyle}"
                            ItemsSource="{Binding Items}"
                            ContentTemplate="{StaticResource TestTemplate}"/>                    
            
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

如果我做同样的事情,但使用 ControlTemplate,它会编译,但当我导航到页面时崩溃:

CustomUserControl.xaml

<ControlTemplate x:Key="TestTemplate" DataType="{x:Type local:CustomUserControl}">
    <StackPanel>
        <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ItemHeaderTemplate}"/>
        <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ItemContentTemplate}"/>
    </StackPanel>
</ControlTemplate>

<Style x:Key="Styling" TargetType="{x:Type local:CustomUserControl}">
    <Setter Property="Template">
        <Setter.Value>          
            <ControlTemplate TargetType="{x:Type local:CustomUserControl}">
                
                <TabControl ItemsSource="{Binding Items}"
                            ContentTemplate="{StaticResource TestTemplate}"/>                    
            
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

ControlTemplate 似乎允许我引用 CustomUserControl 模板,但不能将其用作 ContentTemplate。 虽然 DataTemplate 可以用作 ContentTemplate,但不允许我引用 CustomUserControl 模板。

这让我尝试使用 DataTemplate 和内部引用的 ControlTemplate,如下所示。

CustomUserControl.xaml

<ControlTemplate x:Key="TestControlTemplate" DataType="{x:Type local:CustomUserControl}">
    <StackPanel>
        <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ItemHeaderTemplate}"/>
        <ContentControl Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ItemContentTemplate}"/>
    </StackPanel>
</ControlTemplate>

<DataTemplate x:Key="TestDataTemplate" DataType="{x:Type local:CustomUserControl}">
    <StackPanel>
        <ContentControl Template="{StaticResource TestControlTemplate}"/>
    </StackPanel>
</DataTemplate>

<Style x:Key="Styling" TargetType="{x:Type local:CustomUserControl}">
    <Setter Property="Template">
        <Setter.Value>          
            <ControlTemplate TargetType="{x:Type local:CustomUserControl}">
                
                <TabControl ItemsSource="{Binding Items}"
                            ContentTemplate="{StaticResource TestDataTemplate}"/>                    
            
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

但是它又崩溃了。 我收到这条消息

''CustomUserControl' ControlTemplate TargetType does not match templated type 'ContentControl'.'

如果我将 ControlTemplate 的 TargetType 更改为 ContentControl,则项目不会编译。

有办法做到这一点吗? 或者我需要用完全不同的方式来做这件事吗?

我将 UserControl 的名称设置为 UserControlName

<UserControl ...
             Name="UserControlName">

然后我使用源和路径访问我在 CustomUserControl 中定义的 ItemHeaderTemplate 和 ItemContentTemplate 模板

<ControlTemplate x:Key="TestControlTemplate" DataType="{x:Type local:CustomUserControl}">
    <StackPanel>
        <ContentControl Content="{Binding}" 
                ContentTemplate="{Binding Source={x:Reference UserControlName},
                    Path=ItemHeaderTemplate}"/>
        <ContentControl Content="{Binding}" 
                ContentTemplate="{Binding Source={x:Reference UserControlName},
                    Path=ItemContentTemplate}"/>
    </StackPanel>
</ControlTemplate>

<DataTemplate x:Key="TestDataTemplate" DataType="{x:Type local:CustomUserControl}">    
    <ContentControl Template="{StaticResource TestControlTemplate}"/>    
</DataTemplate>

<Style x:Key="Styling" TargetType="{x:Type local:CustomUserControl}">
    <Setter Property="Template">
        <Setter.Value>          
            <ControlTemplate TargetType="{x:Type local:CustomUserControl}">
                
                <TabControl ItemsSource="{Binding Items}"
                            ContentTemplate="{StaticResource TestDataTemplate}"/>                    
            
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>