Reason 7. The ListView
Earlier I introduced a series of posts entitled
10 reasons to consider WPF for your next desktop application. If you haven't read the intro yet, better head on back and
read it first.
Long term readers of this blog may recall my love of the ListView in Windows Forms. In the post that introduced my
PropertyListView control I briefly mentioned why I'm a big fan of the ListView.
"I use the ListView control in my WinForm applications a lot. I mainly use it in Details mode where you get multiple columns just like you do in Windows Explorer. This is also the reason I use it so much - it's familiar and it looks good too. "
Well I've got some good news for likeminded ListView fans - things just got much better with WPF.
As with all things WPF, databinding has been baked into the ListView from the start and it works a treat. To create a simple list using the same object model as the previous examples in this series is as easy as this:
<ListView x:Name="_lstBooks" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Author}" Header="Author" />
<GridViewColumn DisplayMemberBinding="{Binding CustomerRating}" Header="Customer Rating" />
</GridView>
</ListView.View>
</ListView>

And if we wanted to use our funky RatingBar from "
My dirty little secret from Reason 3. ControlTemplates" it's as easy as specifying the cell's template using a good old
DataTemplate:
<GridViewColumn Header="Customer Rating">
<GridViewColumn.CellTemplate>
<DataTemplate>
<src:RatingBar Template="{StaticResource ratingBarTemplate}"
Maximum="5" Value="{Binding CustomerRating}"
Width="100" Height="20" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>

Neat. But what else can it do?
In two recent posts (
Binding to the Current Item and
How binding to the Current Item works) I discussed how, when binding to a collection in WPF for any type of ItemsControl, an underlying CollectionViewSource is created and this can be reached using CollectionViewSource.GetDefaultView(object source). This returns an implemetation of the ICollectionView interface which has two properties I want to look at: SortDescriptions and GroupDescriptions.
SortDescriptions
You've probably guessed by now that the SortDescriptions property allows me to sort my collection. Bingo, and it's as easy as this:
ICollectionView icv = CollectionViewSource.GetDefaultView(_books);
icv.SortDescriptions.Add(new SortDescription("Author", ListSortDirection.Ascending));
I don't really need to explain that - suffice to point out that performing a sort changes the order that items appear in the ListView. In fact, I've talked about this in more detail in my post
about creating a Sortable ListView where we used Attached Properties and the natural extensibility of WPF to create a SortableListView control that will automatically sort items when the user clicks the column header.
GroupDescriptions
Again, you've probably guessed that the GroupDescriptions property has something to do with the grouping of items and you'd be right. Programmatically it's just as easy to group an ICollectionView:
ICollectionView icv = CollectionViewSource.GetDefaultView(_books);
icv.GroupDescriptions.Add(new PropertyGroupDescription("CustomerRating"));
However, doing this alone will have no impact on your GridView based ListView. We need to specify what the grouping should look like and we call on our old friend the
ControlTemplate here.
<ListView x:Name="_lstBooks" Grid.Row="1" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" BorderBrush="Black" BorderThickness="0,0,0,1" Background="Navy">
<Expander.Header>
<TextBlock Foreground="White">
<Run>Customer Rating: </Run>
<TextBlock FontWeight="Bold"
Text="{Binding Path=Name}" />
<TextBlock Text=" ("/>
<TextBlock
Text="{Binding Path=ItemCount}"/>
<TextBlock Text=" items)" />
</TextBlock>
</Expander.Header>
<Expander.Content>
<Border Background="White" Margin="2" CornerRadius="3">
<ItemsPresenter />
</Border>
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
...
</ListView>

As you can see, grouping now works a treat and we've wrapped each group in an Expander control. Why not have a play with the
Reason 7 ClickOnce sample to see for yourself.

Post By
Josh Twist
10:30
17 Nov 2007
» Next Post:
Silverlight to get full WPF databinding honors
« Previous Post:
How binding to the Current Item works
Comments:
Posted by
Henrik
@
19 Nov 2007
00:43
Great series of WPF posts, please add more..
Posted by
David
@
23 Jan 2008
14:23
When I view almost any WPF application, including the click once application from this post, the text is blurry. I have wanted to start using WPF for a while, but if reading the text (a pretty important thing in most of the applications I design) makes my eyes hurt, I'm not likely to pick it up soon. Have you ever encountered this, and do you have any idea what the problem is?
Posted by
Josh
@
26 Jan 2008
04:42
Crikey David, have you just read this whole blog in a day? Thanks for taking the time to comment tho'
I'm not sure what you mean. The screenshots shown here are actual shots of the WPF app - the text is no blurrier than when you have cleartype enabled (which I do). Do you think that text is blurry?
Text will blur in WPF sometimes during an animation or for a split second after a transform but I've had no problems otherwise.
Posted by
David
@
27 Jan 2008
22:47
Not the whole blog no :) A WPF-ophile friend of mine pointed me to your 10 reasons. He has been trying to persuade me to take the plunge. I have seen a number of impressive things, but I am still not convinced it is worth the effort to climb the learning curve just yet.
About the blurry text - no, the text in your screenshots is not blurry. But when I run the app on my system (with ClearType on), it is. I will try to send you a screenshot.
Posted by
Per Gunnar
@
28 Mar 2008
05:54
ClearType is only for modern flat screens, and does not work in all cases. You can read more about it on Wikipedia.
Posted by
raffaeu
@
08 Jun 2009
13:06
Great sample especially for the grouping!
Posted by
Ed
@
12 Aug 2010
15:16
Yes, surely an WPF app can look good. And you can easily do thinks that are too hard with other approachs. Thats the most that I can say about WPF.
On the other hand, you need converters to format columns (!!!) even to align a number, you need to add an "x:" to a control's name just because it is defined in the same assembly (!?!?)... I could continue with more and more.
Now I am surprised that you need to work so hard to sort a ListView. Come on! The data is loaded, the columns have values, most of the values could have a default logic for sorting... but with WTF you have to do everything from zero to implement any sorting.
Yes, WPF has a lot of fresh and good ideas (user point of view is welcome), but people is overvaluating things that were solved before and now suck with WTF.
For now, I call it WTF instead of WPF