将多个 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>
我有一个带有两个模板的自定义用户控件,我想将它们一起用于选项卡控件中的每个项目。我一次只能用一个。
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>