Pimp my ListView - Rudi Grobler

Pimp my ListView

The ListView in WPF is a very powerfull control! While we wait patiently for the DataGrid to be released... lets see what we can do with a ListView

The Basics

Before we start pimping the control... lets look at the basics! I created a very simple data object to be displayed in the ListView

public class Disciple
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Website { get; set; }
}

and I also populate it with some data

List<Disciple> Disciples = new List<Disciple>()
     {
        new Disciple() { Name = "Andrew", Surname = "Smith", Website = "http://agsmith.wordpress.com/" },
        new Disciple() { Name = "Beatriz", Surname = "Costa", Website = "http://www.beacosta.com/blog/" }, 
        new Disciple() { Name = "Corrado", Surname = "Cavalli", Website = "http://blogs.ugidotnet.org/corrado" }, 
        new Disciple() { Name = "Dr. WPF", Surname = "", Website = "http://www.drwpf.com/" }, 
        new Disciple() { Name = "Ian", Surname = "Griffiths", Website = "http://www.interact-sw.co.uk/iangblog/" }, 
        new Disciple() { Name = "Jeremiah", Surname = "Morrill", Website = "http://jmorrill.hjtcentral.com/Home/tabid/428/Default.aspx" }, 
        new Disciple() { Name = "Josh", Surname = "Smith", Website = "http://joshsmithonwpf.wordpress.com/" }, 
        new Disciple() { Name = "Karl", Surname = "Shifflett", Website = "http://karlshifflett.wordpress.com/" }, 
        new Disciple() { Name = "Lester", Surname = "Lobo", Website = "http://blogs.msdn.com/llobo/default.aspx" },
        new Disciple() { Name = "Marlon", Surname = "Grech", Website = "http://marlongrech.wordpress.com/" }, 
        new Disciple() { Name = "Mike", Surname = "Brown", Website = "http://blog.planetwpf.com/" }, 
        new Disciple() { Name = "Pavan", Surname = "Podila", Website = "http://blog.pixelingene.com/" }, 
        new Disciple() { Name = "Rudi", Surname = "Grobler", Website = "http://dotnet.org.za/rudi/" }, 
        new Disciple() { Name = "Sacha", Surname = "Barber", Website = "http://sachabarber.net/" }, 
        new Disciple() { Name = "Zhou", Surname = "Yong", Website = "http://shevaspace.spaces.live.com/default.aspx" }
     };

Next, I set my Window's DataContext to this list

DataContext = Disciples;

and lastly, add the ListView to my Window

<ListView ItemsSource="{Binding}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}"/>
            <GridViewColumn Header="Website" DisplayMemberBinding="{Binding Website}"/>
        </GridView>
    </ListView.View>
</ListView>

Great, now we have a beautiful ListView!!

OK, maybe not beautiful but at least functional! What can be change now?

Column Header Style

To pimp the column headers, we need to create a new style for the GridViewColumnHeader. Here is the skeleton markup

<Style x:Key="{x:Type GridViewColumnHeader}" TargetType="GridViewColumnHeader">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="GridViewColumnHeader">
                <Grid>
                    <Border>
                        <ContentPresenter />
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Alternating background colors for each row

Another popular UI trend is to alternate the background colors for each row... Their are 2 components needed to achieve this... First we need to create a new value converter

public sealed class BackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ListView listView = ItemsControl.ItemsControlFromItemContainer((DependencyObject)value) as ListView;
        int index = listView.ItemContainerGenerator.IndexFromContainer(value);
        if (index % 2 == 0)
            return Brushes.LightBlue;
        return Brushes.White;
    }

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

All this value converter does is check if the item is on a odd or even line...

<local:BackgroundConverter x:Key="backgroundConverter" />

The next part is to bind the Background of every ListViewItem using the value converter (Read more about how this actually work here)

<Style x:Key="{x:Type ListViewItem}" TargetType="ListViewItem">
    <Setter Property="Background">
        <Setter.Value>
            <Binding RelativeSource="{RelativeSource Self}" Converter="{StaticResource backgroundConverter}"/>
        </Setter.Value>
    </Setter>
</Style>

The template for the ListViewItem is also where you can add mouse over effects, change the selection behaviour, etc!

More Information

Sorting and editing a ListView

MSDN ListView ControlTemplate Example

If you found this article useful, please kick it on DotNetKicks.com

Published Thursday, April 24, 2008 9:58 AM by rudi
Filed under: , ,

Comments

# Pimp my ListView

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Thursday, April 24, 2008 10:00 AM by DotNetKicks.com

# re: Pimp my ListView

And no screenshot to see the pimped listview :(

Thursday, April 24, 2008 11:22 AM by Adriaan

# re: Pimp my ListView

My design skills... or lack off... will not do the technique justice :)

Thursday, April 24, 2008 11:33 AM by rudi

# re: Pimp my ListView

You WPF disciples are great. :-) Thanks for this useful info.

Say, one thing that would be much appreciated by your readers is to post screenshots of the end result. Better yet, post a link to an XBAP to see it live. Give us some way to quickly try it out, I'm usually too lazy to download, compile, and try it from there. :-)

Thursday, April 24, 2008 11:10 PM by Judah

# re: Pimp my ListView

tnx,

i'll post a screen shot, code and binary later today!

Friday, April 25, 2008 6:05 AM by rudi

# Dew Drop - April 25, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - April 25, 2008 | Alvin Ashcraft's Morning Dew

# re: Pimp my ListView

Nice!  Posts like this are very useful.  Great job!  :)

Saturday, April 26, 2008 4:07 AM by Josh Smith

# re: Pimp my ListView

Tnx Josh!

Saturday, April 26, 2008 5:28 PM by rudi

# re: Pimp my ListView

Nice find atul,

It is suppose to be value!

Regards,

Rudi

Monday, April 28, 2008 1:41 PM by rudi

# re: Pimp my ListView

I had guessed so much, but hadn't had a change to try it out as yet. Just that and this works perfectly. Thanks.

The statement will hence read

int index = listView.ItemContainerGenerator.IndexFromContainer((DependencyObject)value);

btw, surprisingly, I don't see my original comment, but only your response to it :-)

Monday, April 28, 2008 2:43 PM by Atul Gupta

# re: Pimp my ListView

Oops again... their was a spam message before yours... only tried to delete it but must have deleted yours 2! sorry! Nice find again!

Monday, April 28, 2008 4:06 PM by rudi

# WPF/Silverlight/XAML Web News - 2008/04/30

WPF Frameworks Brian Noyes: Prism: Composite WPF Guidance . Great summary of &quot;Prism&quot; from Brian

Wednesday, April 30, 2008 12:18 PM by Rob Relyea - Xamlified

# re: Pimp my ListView

hi there,

Thursday, May 01, 2008 2:12 PM by Merlin