我需要以不同方式设置列表视图的第一个和最后一个项目的样式。为实现这一目标,我开始根据答案开发解决方案:Use different template for last item in a WPF itemscontrol
基本上,我有一个自定义的ItemsTemplateSelector,它根据列表视图项中的项索引决定要应用的模板(下面的代码)。
它正常工作,除了当列表更新(添加或删除项目)时,模板不会再次被选中(例如,最初,SingleItemTemplate被选中,因为有一个项目。当我添加一个项目到列表,第一项的模板没有切换到FirstItemTemplate)。如何强制所有项目的模板选择?
public class FirstLastTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate FirstItemTemplate { get; set; }
public DataTemplate LastItemTemplate { get; set; }
public DataTemplate SingleItemTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ListView lv = VisualTreeHelperEx.FindParentOfType<ListView>(container);
if (lv != null)
{
if (lv.Items.Count == 1)
{
return SingleItemTemplate;
}
int i = lv.Items.IndexOf(item);
if (i == 0)
{
return FirstItemTemplate;
}
else if (i == lv.Items.Count - 1)
{
return LastItemTemplate;
}
}
return DefaultTemplate;
}
}
答案 0 :(得分:15)
作为替代方法,我建议将AlternationCount
的{{1}}绑定到集合中的项目数(例如ItemsControl
属性)。然后,这将为Count
中的每个容器分配一个唯一的ItemsControl
(0,1,2,... Count-1)。有关更多信息,请参见此处:
http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.alternationcount.aspx
每个容器都有一个唯一的AlternationIndex
后,您可以在容器AlternationIndex
中使用DataTrigger
来设置基于索引的Style
。这可以使用带有转换器的ItemTemplate
来完成,如果索引等于计数,则返回MultiBinding
,否则为True
。当然,你也可以围绕这种方法构建一个选择器。除转换器外,这种方法很好,因为它只是一个XAML解决方案。
使用False
的示例:
ListBox
转换器可能类似于:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:l="clr-namespace:WpfApplication4"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<Collections:ArrayList x:Key="MyCollection">
<System:String>Item One</System:String>
<System:String>Item Two</System:String>
<System:String>Item Three</System:String>
</Collections:ArrayList>
<l:MyAlternationEqualityConverter x:Key="MyAlternationEqualityConverter" />
<Style x:Key="MyListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource MyAlternationEqualityConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListBox}}" Path="Items.Count" />
<Binding RelativeSource="{RelativeSource Self}" Path="(ItemsControl.AlternationIndex)" />
</MultiBinding>
</DataTrigger.Binding>
<!-- Could set the ItemTemplate instead -->
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ListBox ItemsSource="{Binding Source={StaticResource MyCollection}}"
AlternationCount="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}"
ItemContainerStyle="{StaticResource MyListBoxItemStyle}" />
</Grid>