Distinct item template for first and last item in a ListView

浪尽此生 提交于 2019-12-03 12:53:16

As an alternative approach, I would suggest binding the AlternationCount of your ItemsControl to the number of items in your collection (e.g. the Count property). This will then assign to each container in your ItemsControl a unique AlternationIndex (0, 1, 2, ... Count-1). See here for more information:

http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.alternationcount.aspx

Once each container has a unique AlternationIndex you can use a DataTrigger in your container Style to set the ItemTemplate based off of the index. This could be done using a MultiBinding with a converter that returns True if the index is equal the count, False otherwise. Of course you could also build a selector around this approach as well. With the exception of the converter, this approach is nice since it is a XAML only solution.

An example using a 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>

Where the converter might look something like:

class MyAlternationEqualityConverter : IMultiValueConverter
{
    #region Implementation of IMultiValueConverter

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values != null && values.Length == 2 &&
            values[0] is int && values[1] is int)
        {
            return Equals((int) values[0], (int) values[1] + 1);
        }

        return DependencyProperty.UnsetValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    #endregion
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!