模板选择器不起作用
TemplateSelector doesn't work
我有 Items Control
,但我想改进此代码以处理不同类型的输入数据。
<Grid>
<ItemsControl x:Name="control"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ItemsSource="{x:Bind ItemsSource, Mode=OneWay}"
ItemTemplate="{x:Bind CellTemplate, Mode=OneWay, Converter={StaticResource SimpleSelector}}">
<!--I want make like this-->
<ContentControl VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ContentTemplate="{Binding SelectedCollageTemplate, Converter={StaticResource CollageTemplateSelector}}" />
<!-- -->
<!--now I have this-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:SimplePanel SelectedCollage="{Binding SelectedCollage, Mode=TwoWay}"
SelectedCollagePattern="{Binding SelectedCollagePattern}">
<controls:SimplePanel.Background>
<ImageBrush Stretch="Fill"
ImageSource="ms-appx:///Images/Background/5.jpg" />
</controls:SimplePanel.Background>
</controls:SimplePanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- -->
</ItemsControl>
</Grid>
如您所见,我想将硬编码更改为更灵活的方式并使用 Template selector
我创建选择器:
<templateSelector:CollageTemplateSelector x:Key="CollageTemplateSelector"
SimpleTemplate="{StaticResource SimpleTemplate}"
ShapeTemplate="{StaticResource ShapeTemplate}"/>
并添加了DataTemplate
:
<DataTemplate x:Key="SimpleTemplate">
<controls:SimplePanel
SelectedCollage="{Binding SelectedCollage, Mode=TwoWay}"
SelectedCollagePattern="{Binding SelectedCollagePattern}">
<controls:SimplePanel.Background>
<ImageBrush Stretch="Fill"
ImageSource="ms-appx:///Images/Background/5.jpg" />
</controls:SimplePanel.Background>
</controls:SimplePanel>
我的转换器returns 简单面板。但是当我启动它时,我的 SimplePanel
没有启动(我在构造函数上有断点)并且部分代码不起作用。我的问题是什么?
您正在将 ContentControl
的 ContentTemplate
设置为您的选择器;您应该改为设置 ContentTemplateSelector
属性。
在您的 ItemsControl
中,您将 ItemsTemplate
设置为看起来像模板选择器的东西;您应该改为设置 ItemsTemplateSelector
属性。
您不应绑定到模板选择器,而应将它们作为 StaticResource
s 访问。
我不完全理解你正在尝试做的事情的细节,所以这里有一个 DataTemplateSelector
有效的例子。
首先,我使用以下 ItemsSource
,目的是使字符串 "Three" 显示为红色:
public string[] ItemsSource => new[]
{
"One", "Two", "Three",
};
模板选择器有两个 DataTemplate
属性,它们将从 XAML 开始设置——一个用于 "Three" 个字符串;另一个用于所有其他字符串:
public sealed class ItemTemplateSelector : DataTemplateSelector
{
/// <summary>
/// This property is set in XAML.
/// </summary>
public DataTemplate NormalTemplate { get; set; }
/// <summary>
/// This property is set in XAML.
/// </summary>
public DataTemplate ThreeTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if ("Three".Equals(item))
{
return ThreeTemplate;
}
return NormalTemplate;
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return SelectTemplateCore(item);
}
}
数据模板选择器有两个版本SelectTemplateCore
。 This page讨论在什么情况下使用哪一个:
If your ItemsControl.ItemsPanel is an ItemsStackPanel or ItemsWrapGrid, provide an override for the SelectTemplateCore(Object) method. If the ItemsPanel is a different panel, such as VirtualizingStackPanel or WrapGrid, provide an override for the SelectTemplateCore(Object, DependencyObject) method.
XAML(将数据模板分配给选择器的两个属性)如下所示:
<Grid>
<Grid.Resources>
<local:ItemTemplateSelector x:Key="ItemTemplateSelector">
<local:ItemTemplateSelector.NormalTemplate>
<DataTemplate>
<TextBlock Foreground="Blue" Text="{Binding}" />
</DataTemplate>
</local:ItemTemplateSelector.NormalTemplate>
<local:ItemTemplateSelector.ThreeTemplate>
<DataTemplate>
<TextBlock Foreground="Red" Text="{Binding}" />
</DataTemplate>
</local:ItemTemplateSelector.ThreeTemplate>
</local:ItemTemplateSelector>
</Grid.Resources>
<ItemsControl
VerticalAlignment="Center"
HorizontalAlignment="Center"
ItemsSource="{x:Bind ItemsSource, Mode=OneWay}"
ItemTemplateSelector="{StaticResource ItemTemplateSelector}">
</ItemsControl>
</Grid>
结果如下所示,字符串 "Three" 显示为红色:
我希望这足以让您走上正轨。
我有 Items Control
,但我想改进此代码以处理不同类型的输入数据。
<Grid>
<ItemsControl x:Name="control"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ItemsSource="{x:Bind ItemsSource, Mode=OneWay}"
ItemTemplate="{x:Bind CellTemplate, Mode=OneWay, Converter={StaticResource SimpleSelector}}">
<!--I want make like this-->
<ContentControl VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ContentTemplate="{Binding SelectedCollageTemplate, Converter={StaticResource CollageTemplateSelector}}" />
<!-- -->
<!--now I have this-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:SimplePanel SelectedCollage="{Binding SelectedCollage, Mode=TwoWay}"
SelectedCollagePattern="{Binding SelectedCollagePattern}">
<controls:SimplePanel.Background>
<ImageBrush Stretch="Fill"
ImageSource="ms-appx:///Images/Background/5.jpg" />
</controls:SimplePanel.Background>
</controls:SimplePanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- -->
</ItemsControl>
</Grid>
如您所见,我想将硬编码更改为更灵活的方式并使用 Template selector
我创建选择器:
<templateSelector:CollageTemplateSelector x:Key="CollageTemplateSelector"
SimpleTemplate="{StaticResource SimpleTemplate}"
ShapeTemplate="{StaticResource ShapeTemplate}"/>
并添加了DataTemplate
:
<DataTemplate x:Key="SimpleTemplate">
<controls:SimplePanel
SelectedCollage="{Binding SelectedCollage, Mode=TwoWay}"
SelectedCollagePattern="{Binding SelectedCollagePattern}">
<controls:SimplePanel.Background>
<ImageBrush Stretch="Fill"
ImageSource="ms-appx:///Images/Background/5.jpg" />
</controls:SimplePanel.Background>
</controls:SimplePanel>
我的转换器returns 简单面板。但是当我启动它时,我的 SimplePanel
没有启动(我在构造函数上有断点)并且部分代码不起作用。我的问题是什么?
您正在将
ContentControl
的ContentTemplate
设置为您的选择器;您应该改为设置ContentTemplateSelector
属性。在您的
ItemsControl
中,您将ItemsTemplate
设置为看起来像模板选择器的东西;您应该改为设置ItemsTemplateSelector
属性。您不应绑定到模板选择器,而应将它们作为
StaticResource
s 访问。
我不完全理解你正在尝试做的事情的细节,所以这里有一个 DataTemplateSelector
有效的例子。
首先,我使用以下 ItemsSource
,目的是使字符串 "Three" 显示为红色:
public string[] ItemsSource => new[]
{
"One", "Two", "Three",
};
模板选择器有两个 DataTemplate
属性,它们将从 XAML 开始设置——一个用于 "Three" 个字符串;另一个用于所有其他字符串:
public sealed class ItemTemplateSelector : DataTemplateSelector
{
/// <summary>
/// This property is set in XAML.
/// </summary>
public DataTemplate NormalTemplate { get; set; }
/// <summary>
/// This property is set in XAML.
/// </summary>
public DataTemplate ThreeTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if ("Three".Equals(item))
{
return ThreeTemplate;
}
return NormalTemplate;
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return SelectTemplateCore(item);
}
}
数据模板选择器有两个版本SelectTemplateCore
。 This page讨论在什么情况下使用哪一个:
If your ItemsControl.ItemsPanel is an ItemsStackPanel or ItemsWrapGrid, provide an override for the SelectTemplateCore(Object) method. If the ItemsPanel is a different panel, such as VirtualizingStackPanel or WrapGrid, provide an override for the SelectTemplateCore(Object, DependencyObject) method.
XAML(将数据模板分配给选择器的两个属性)如下所示:
<Grid>
<Grid.Resources>
<local:ItemTemplateSelector x:Key="ItemTemplateSelector">
<local:ItemTemplateSelector.NormalTemplate>
<DataTemplate>
<TextBlock Foreground="Blue" Text="{Binding}" />
</DataTemplate>
</local:ItemTemplateSelector.NormalTemplate>
<local:ItemTemplateSelector.ThreeTemplate>
<DataTemplate>
<TextBlock Foreground="Red" Text="{Binding}" />
</DataTemplate>
</local:ItemTemplateSelector.ThreeTemplate>
</local:ItemTemplateSelector>
</Grid.Resources>
<ItemsControl
VerticalAlignment="Center"
HorizontalAlignment="Center"
ItemsSource="{x:Bind ItemsSource, Mode=OneWay}"
ItemTemplateSelector="{StaticResource ItemTemplateSelector}">
</ItemsControl>
</Grid>
结果如下所示,字符串 "Three" 显示为红色:
我希望这足以让您走上正轨。