【问题标题】:Combine multiple CustomUserControl templates into a single template将多个 CustomUserControl 模板组合成一个模板
【发布时间】: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,项目将无法编译。

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

【问题讨论】:

    标签: c# wpf xaml


    【解决方案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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多