基于 ItemsControl 的 UserControl 中的 ItemTemplate Wrapper
ItemTemplate Wrapper in UserControl Based on ItemsControl
我正在开发我自己的派生自 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 选择影响的项目行为。
我试图在 ItemsControl.Resources 中的 ContentPresenter 上添加 DataTemplates,但失败了。有人可以帮我吗? :)
您可以在 ItemControl 的 GetContainerForItemOverride 方法中创建派生的 ContentPresenter 或 ContentControl:
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)));
}
到控件的代码。
我正在开发我自己的派生自 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 选择影响的项目行为。
我试图在 ItemsControl.Resources 中的 ContentPresenter 上添加 DataTemplates,但失败了。有人可以帮我吗? :)
您可以在 ItemControl 的 GetContainerForItemOverride 方法中创建派生的 ContentPresenter 或 ContentControl:
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)));
}
到控件的代码。