模板选择器不起作用

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 没有启动(我在构造函数上有断点)并且部分代码不起作用。我的问题是什么?

  1. 您正在将 ContentControlContentTemplate 设置为您的选择器;您应该改为设置 ContentTemplateSelector 属性。

  2. 在您的 ItemsControl 中,您将 ItemsTemplate 设置为看起来像模板选择器的东西;您应该改为设置 ItemsTemplateSelector 属性。

  3. 您不应绑定到模板选择器,而应将它们作为 StaticResources 访问。

我不完全理解你正在尝试做的事情的细节,所以这里有一个 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);
    }
}

数据模板选择器有两个版本SelectTemplateCoreThis 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" 显示为红色:

我希望这足以让您走上正轨。