WPF is powerful. So powerful in fact, that sometimes it's hard to find styles and settings to make it do what you want. Aligning ListView items was one such example for me. This snippet tutorial will show you how to use a style to vertically and horizontally align the contents of ListView cells.
I came across the need to vertically align the contents of my ListView when I had columns that contained elements that were different heights. By default, the ListView vertically aligns all of the content to the middle. I wanted them aligned to the top.
Here's a quick application I threw together to demonstrate what I'm talking about. It has a ListView bound to a collection of VideoGame objects. Each video game contains the title and an image of the box art. First, the object and some code to populate it:
{
public string Name
{
get;
set;
}
public string Image
{
get;
set;
}
}
...
{
private ObservableCollection<VideoGame> _games =
new ObservableCollection<VideoGame>();
public ObservableCollection<VideoGame> Games
{
get { return _games; }
}
public Window1()
{
_games.Add(new VideoGame() {
Name = "Crysis",
Image = @"C:\Crysis_Boxart_Final.jpg" });
_games.Add(new VideoGame() {
Name = "Unreal Tournament 3",
Image = @"C:\Gearsofwar.JPG" });
_games.Add(new VideoGame() {
Name = "Gears of War",
Image = @"C:\Crysis_Boxart_Final.jpg" });
InitializeComponent();
}
}
And here's the XAML that displays this information:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="512" Width="512" Name="myWindow">
<Grid>
<ListView Name="myListView"
ItemsSource="{Binding ElementName=myWindow, Path=Games}">
<ListView.View>
<GridView>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Image">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Image Source="{Binding Image}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
When you launch this application, you'll get something that looks like this:
As you can see, each title is centered vertically to the image. I want to align it to the top. Here's the style needed to accomplish this:
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
</ListView.ItemContainerStyle>
Now if we slap that into our ListView, we'll get exactly what we're looking for:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="512" Width="512" Name="myWindow">
<Grid>
<ListView Name="myListView"
ItemsSource="{Binding ElementName=myWindow, Path=Games}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Image">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Image Source="{Binding Image}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
We can also use this style to horizontally align the content. Let's say I wanted to align all of the titles to the right as well as the top. All we'd have to do is change our style to this:
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="HorizontalContentAlignment" Value="Right" />
</Style>
</ListView.ItemContainerStyle>
That's it. You can now go off and align to your hearts content. By the way, I got all of the box art from Wikipedia: here, here, and here.
09/02/2008 - 12:10
Before I find this post I tried this using this on Windows.Resources:
and it didnt work. I thought a Style applied to a parent resource without a x:key clause would be applied to all children of the type defined on TargetType. Isn't that true?
09/02/2008 - 12:11
to the post above:
09/19/2008 - 04:00
hi, your article is nice, but if I want one column align to left and another align to right, how to do this?
11/22/2008 - 02:24
hi can i ask if i can still use my code in populating data into wpf listview? since i can't find a subitems in wpf i need a little help out here.
here's my xaml code:
and here's my vb code:
Private Sub getlist()
ssql = ""
ssql = "select value1,value2 from mytable;"
If rssource.State = 1 Then rssource.Close()
rssource.Open(ssql, dbsource, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockReadOnly)
While Not rssource.EOF
lstdetails.Items.Add(rssource.Fields.Item(1).Value.ToString)
rssource.MoveNext()
End While
End Sub
11/22/2008 - 02:25
here’s my xaml code:
and here’s my vb code:
Private Sub getlist()
ssql = “”
ssql = “select value1,value2 from mytable;”
If rssource.State = 1 Then rssource.Close()
rssource.Open(ssql, dbsource, ADODB.CursorTypeEnum.adOpenDynamic, ADODB.LockTypeEnum.adLockReadOnly)
While Not rssource.EOF
lstdetails.Items.Add(rssource.Fields.Item(1).Value.ToString)
rssource.MoveNext()
End While
End Sub
10/24/2009 - 06:30
thank you very much for such tutorial.
you helped me alot, one question though
-if later I modified the collection right after the binding is done , does it affect the listview , like if i changed the crysis's image on run time ?
Add Comment
[language] [/language]
Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]
See here for supported languages.
Javascript must be enabled to submit anonymous comments - or you can login.