【问题标题】:TemplateSelector doesn't work模板选择器不起作用
【发布时间】:2016-11-21 17:46:55
【问题描述】:

我有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>

我的转换器返回简单面板。但是当我启动它时,我的SimplePanel 没有启动(我在构造函数上有断点)并且部分代码不起作用。我的问题是什么?

【问题讨论】:

    标签: c# xaml uwp win-universal-app windows-10-universal


    【解决方案1】:
    1. 您将ContentControlContentTemplate 设置为您的选择器;您应该设置 ContentTemplateSelector 属性。

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

    3. 您不应绑定到模板选择器,而应以StaticResources 的身份访问它们。

    我不完全了解您要执行的操作的详细信息,因此这里有一个 DataTemplateSelector 有效的示例。

    首先,我使用以下ItemsSource,目的是使字符串“三”显示为红色:

    public string[] ItemsSource => new[]
        {
            "One", "Two", "Three",
        };
    

    模板选择器有两个 DataTemplate 属性,它们将从 XAML 中设置——一个用于“三”字符串;另一个用于所有其他字符串:

    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 讨论在什么情况下使用哪一个:

    如果您的 ItemsControl.ItemsPanel 是 ItemsStackPanel 或 ItemsWrapGrid,请为 SelectTemplateCore(Object) 方法提供覆盖。如果 ItemsPanel 是不同的面板,例如 VirtualizingStackPanel 或 WrapGrid,请为 SelectTemplateCore(Object, DependencyObject) 方法提供覆盖。

    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”显示为红色:

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

    【讨论】:

    • 关于覆盖DataTemplateSelector 方法的警告确实有帮助。是的,该页面提到了它,但不幸的是,描述如何编写自己的选择器的其他 MS 文档页面没有...
    猜你喜欢
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多