将多个 CustomUserControl 模板组合成一个模板

Posted

技术标签:

【中文标题】将多个 CustomUserControl 模板组合成一个模板【英文标题】:Combine multiple CustomUserControl templates into a single template 【发布时间】:2021-12-14 15:20:53 【问题描述】:

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

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 模板。

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

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 与模板化类型'ContentControl' 不匹配。'

如果我将 ControlTemplate 的 TargetType 更改为 ContentControl,项目将无法编译。

有没有办法做到这一点? 还是我需要以完全不同的方式做到这一点?

【问题讨论】:

【参考方案1】:

我将 UserControl 的名称设置为 UserControlName

<UserControl ...
             Name="UserControlName">

然后我使用 Source & Path 来访问我在 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>

【讨论】:

以上是关于将多个 CustomUserControl 模板组合成一个模板的主要内容,如果未能解决你的问题,请参考以下文章

Cloud Formation 模板将入口规则添加到现有安全组

Django模板:如果用户属于多个组,则仅显示一次链接

zabbix模板化监控

Blade:在多个子视图中扩展模板

迭代 Django 模板中数组内的多个列表

可变参数模板