Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
534 views
in Technique[技术] by (71.8m points)

.net - Metro app - ListView - how to alternate background colour of ListViewItems

In my Metro style app for Windows 8, I'm binding a Listview to an ObservableCollection and I would like the background color of each ListViewItem to alternate (white, gray, white, etc)

   <ListView x:Name="stopsListView" ItemsSource="{Binding}" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Height="66" >
                    <TextBlock Text="{Binding Title}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>

In WPF, this is done using a Style with Triggers - see this page.

How do you accomplish this in a Metro app?

Update:

After the correct answer was given below, I went away and actually coded it. Here's some code for anyone who needs it:

Code for value converter class:

public class AltBackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (!(value is int)) return null;
        int index = (int)value;

        if (index % 2 == 0)
            return Colors.White;
        else
            return Colors.LightGray;
    }

    // No need to implement converting back on a one-way binding
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Code for XAML listview:

    <ListView x:Name="stopsListView" ItemsSource="{Binding}">

        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Width="250" Height="66" Margin="5">
                    <Grid.Background>
                        <SolidColorBrush Color="{Binding IndexWithinParentCollection, Mode=OneWay, Converter={StaticResource AltBGConverter}}" />
                    </Grid.Background>

...and, when adding items to the collection, or modifying the collection, remember to set their Index within the collection:

myCollection.add(item);
item.IndexWithinParentCollection = myCollection.Count;

Of course, if your collection changes often this approach will be costly to maintain, since you'll have to re-index your items, so I found it easier to store a reference to the parent collection within each item, then calculate the Index on-the-fly using .IndexOf() to avoid having to constantly update the index values every time the collection changes.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use a converter - grab a row index from an item and convert it to a brush. Also - if ItemTemplate does not give you enough control - use ItemContainerStyle to modify the brush at the ListViewItem template level.

Another option might be to specify an ItemTemplateSelector that gives you a different template with a different brush depending on an item. You would still need to generate row indices though or somehow enable the selector to determine if the item is at an even or odd position.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...