【问题标题】:Style Nth item in ItemsControlItemsControl 中的样式第 N 项
【发布时间】:2013-10-27 07:45:28
【问题描述】:

我有一个ItemsControl 和一个关联的DataTemplate,如下所示。我的问题是如何以不同的方式设置ItemsControl 中的第 N 个项目?我正在尝试仅在某些项目上设置边框。

    <DataTemplate x:Key="CTemplate">
        <Grid HorizontalAlignment="Left" Width="200" Height="Auto" Margin="0,0,30,30">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="10"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <StackPanel Orientation="Vertical" Grid.Column="0">
                <TextBlock Text="Device Name:" Style="{StaticResource i2_TB}"/>
                <TextBlock Text="Device ID:" Style="{StaticResource i2_TB}" />
            </StackPanel>
            <StackPanel Orientation="Vertical" Grid.Column="2">
                <TextBlock Text="{Binding DeviceName}" Style="{StaticResource i2_TB}" TextTrimming="CharacterEllipsis" />
                <TextBlock Text="{Binding DeviceID}" Style="{StaticResource i2_TB}" TextTrimming="CharacterEllipsis" />
            </StackPanel>
        </Grid>
    </DataTemplate>

【问题讨论】:

标签: wpf xaml styles datatemplate


【解决方案1】:

如果您的项目属于不同类型,那么只需为每种不同类型提供一个DataTemplate没有设置x:Key

<DataTemplate DataType="{x:Type DataTypes:ThisType}">
    ...
</DataTemplate>
<DataTemplate DataType="{x:Type DataTypes:ThatType}">
    ...
</DataTemplate>

但是,如果您的项目都是同一类型,那么执行此操作的标准方法是为您想要的每种不同外观创建一个名为 DataTemplate 并使用 DataTemplateSelector。在DataTemplateSelector.SelectTemplate 方法中,您可以决定为每个项目显示哪个DataTemplate

public class TaskListDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;
        if (element != null && item != null && item is Task)
        {
            Task taskitem = item as Task;
            if (taskitem.Priority == 1) return element.FindResource(
                "importantTaskTemplate") as DataTemplate;
            else return element.FindResource("myTaskTemplate") as DataTemplate;
        }
        return null;
    }
}

示例取自 MSDN 上的链接页面(如下)

您可以从 MSDN 上的DataTemplateSelector Class 页面了解更多信息。

【讨论】:

    【解决方案2】:

    我可以想到 3 种方法。

    第一种方式

    在你想要模板的东西上有一个简单的属性,然后有一个 TemplateSelector 将根据该属性选择正确的模板

    第二种方式

    或者您可以使用 TemplateSelector 和 ItemContainerGenerator.IndexFromContainer 的组合,您可以使用 TemplateSelector 中的容器和项目来获取索引并返回正确的 DataTemplate

    第三种方式

    或者另一个想法可能在于使用 ValueConverter/MarkupExtension。

    您可能需要像这样设置 MultiValueConverter

    Item[0] : DataTemplate 标准资源 项目[1]:替代数据模板资源 Item[2] : 列表框(相对源查找) Item[3] : listboxitem(相对源查找)

    然后你可以使用ItemContainerGenerator.IndexFromContainer,然后只返回匹配索引的DataTemplate。

    我曾经做过这样的事情。我认为它在这段代码中: http://www.codeproject.com/Articles/30021/WPF-Sticky-Notes-ListBox

    【讨论】:

      【解决方案3】:

      我想通了,它很简单

      1. 首先设置一个与您的N 匹配的AlternationCount。就我而言,我每行有 3 个项目,我希望第 3 个项目有所不同。

        <ItemsControl ItemTemplate="{StaticResource CTemplate}" AlternationCount="3">
        
      2. 其次在模板本身中设置您的数据触发器,使用AlternationIndex 作为数据触发器

        <DataTemplate.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="2">
                <Setter Property="BorderThickness" Value="0,0,0,1" TargetName="controlHost"/>
            </Trigger>
        </DataTemplate.Triggers>
        

      【讨论】:

        猜你喜欢
        • 2018-03-09
        • 2011-07-07
        • 2011-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-20
        • 2019-03-01
        • 1970-01-01
        相关资源
        最近更新 更多