Many of the controls in WPF have a downright dizzying array of capabilities and features, due in large part to the composibility of all the components. The ListView control is a great example of this - the possibilities are almost endless. This series of tutorials on the ListView will hopefully make the space of possible options seem not quite as daunting.
We will be starting today with a simple grid based list view, showing how to create columns and some different ways of getting data into those columns. This tutorial won't be very exciting - we will mostly just be setting up the basics for use in some of the later parts. Hopefully, the series will culminate in a sort of "DataGridView" for WPF (a control that, sadly, does not yet exist in WPF). I say hopefully cause I haven't yet written the code for those parts :P
Ok, so here's a screenshot of a ListView with a few columns and no data. Nothing really fancy, but the basic starting point.

The code to create this is just as boring:
<Window x:Class="ListViewTest.Test0.ListViewTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Empty ListView Grid" Height="216" Width="435">
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Column 1" />
<GridViewColumn Width="140" Header="Column 2" />
<GridViewColumn Width="140" Header="Column 3" />
</GridView>
</ListView.View>
</ListView>
</Window>
The special code here is in the ListView.View section. This is what
changes the list view from your standard wrapping list of items into
something else - in this case a GridView. Don't confuse the GridView
with the standard WPF Grid control - they are very different. Pretty
much the only thing that is the same is that they both have the word
Grid in the name.
So we make a GridView and then we make a couple GridViewColumns.
These GridViewColumns have a lot more functionality than is used here
- we will start to see that in the later examples and especially in
later tutorials. There are a couple nice things that you automatically
get with the GridView and GridViewColumns - first off, the columns
can be resized by the user exactly like, say, the columns in Windows
Explorer. Also, the user can drag+drop to reorder columns, and you don't
have to worry about it at all. One thing that is missing, though, is
some built in sorting capability - but it isn't that hard to add on (we
will be doing that in a later tutorial).
Ok, enough about that. Lets throw some data into this grid!

And heres the xaml code:
<Window x:Class="ListViewTest.Test1.ListViewTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Some Dates" Height="216" Width="435">
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Width="120" Header="Date" />
<GridViewColumn Width="120" Header="Day Of Week"
DisplayMemberBinding="{Binding DayOfWeek}" />
<GridViewColumn Width="120" Header="Year"
DisplayMemberBinding="{Binding Year}" />
</GridView>
</ListView.View>
<sys:DateTime>1/2/3</sys:DateTime>
<sys:DateTime>4/5/6</sys:DateTime>
<sys:DateTime>7/8/9</sys:DateTime>
<sys:DateTime>10/11/12</sys:DateTime>
</ListView>
</Window>
So there are a couple changes to the xaml here. First, I imported the
System namespace and registered it to "sys", because I wanted to use
some DateTime objects as my ListView data. Next, you can see that
two of the GridViewColumns have a DisplayMemberBinding property now.
And finally, there are the 4 dates which are the data for the
ListView.
The only part that probably needs explaining is the
DisplayMemberBinding property. This property tells the column what
data from an entry should be displayed in that column. As you can see,
the first column does not have this property set, so it just does a
toString on the date object for each row to determine what to put in
that column. The second column is bound to the DayOfWeek property on
the DateTime object - and so in that column the day of the week for
each of those dates is printed. And for the third column, we have bound
to the Year property, and so we get the year out. Pretty cool, eh?
Now you're probably thinking thats all well and good, but you want to display your own data objects, and you want to be able to add and remove them on the fly. No worries there - the ListView has got you covered!

Here we make a departure for using just XAML - there is actually (gasp!) some C# code behind. So lets take a look:
<Window x:Class="ListViewTest.Test2.ListViewTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Some Game Data" Height="216" Width="435">
<StackPanel>
<ListView ItemsSource="{Binding GameCollection}">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Game Name"
DisplayMemberBinding="{Binding GameName}" />
<GridViewColumn Width="140" Header="Creator"
DisplayMemberBinding="{Binding Creator}" />
<GridViewColumn Width="140" Header="Publisher"
DisplayMemberBinding="{Binding Publisher}" />
</GridView>
</ListView.View>
</ListView>
<Button HorizontalAlignment="Right" Margin="5,5,5,5"
Content="Add Row" Click="AddRow_Click" />
</StackPanel>
</Window>
And the code behind:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
namespace ListViewTest.Test2
{
public partial class ListViewTest : Window
{
ObservableCollection<GameData> _GameCollection =
new ObservableCollection<GameData>();
public ListViewTest()
{
_GameCollection.Add(new GameData {
GameName = "World Of Warcraft",
Creator = "Blizzard",
Publisher = "Blizzard" });
_GameCollection.Add(new GameData {
GameName = "Halo",
Creator = "Bungie",
Publisher = "Microsoft" });
_GameCollection.Add(new GameData {
GameName = "Gears Of War",
Creator = "Epic",
Publisher = "Microsoft" });
InitializeComponent();
}
public ObservableCollection<GameData> GameCollection
{ get { return _GameCollection; } }
private void AddRow_Click(object sender, RoutedEventArgs e)
{
_GameCollection.Add(new GameData {
GameName = "A New Game",
Creator = "A New Creator",
Publisher = "A New Publisher" });
}
}
public class GameData
{
public string GameName { get; set; }
public string Creator { get; set; }
public string Publisher { get; set; }
}
}
So what we have here is a set of GameData objects that we want to
display in the ListView. The GameData objects have a Game Name, a
Creator, and a Publisher, and so we create three columns in the
ListView and bind them each to the appropriate fields. One thing to
note - and I'll probably elaborate on this more if I ever get around to
a tutorial on WPF Binding - you can only bind to public
properties/methods/dependency properties. You can't bind to private
things, or to fields. The syntax I used in the GameData class right
above is syntactic sugar for not having to write out the full property
definition. When the code is compiled, those lines for GameName, etc.,
turn into properties with a backing private field.
So we have some GameData objects - how do we get them into the
ListView? Well, we create an ObservableCollection of them.
ObservableCollection is not your normal everyday generic list - it can
tell other pieces of code when the contents of the collection change.
You'll see why this comes in handy in a moment.
Now that we have this collection (and we have created a public field for
it) what do we do with it? Well, we bind it as the ItemsSource of the
ListView. This is where the fact that the collection is observable
comes in handy - now the ListView gets alerted whenever anything
changes inside of the collection, and can update accordingly. For
example, when you press the "Add Row" button, a new GameData instance
is added to the collection. The ListView is notified, and so is able
to update and display the new row.
Ok, well that is it for this first tutorial on the WPF ListView. You
can get the source code for all three examples
here if you
would like it. Stay tuned for future tutorials on the ListView,
covering topics like sorting, filtering, and how to configure the look
of the cells in the view.
Source Files:
Hi. This is great. I have learned a lot of things from this post. I have one more question. How to bind data when you have an undetermined number of columns at design time. From example bind from an string[] at runtime, and create as many columns as needed. Thanks.
to do that, you access the GridView component of your ListView: var grid = YourListView.View as GridView; grid.Columns.Add(new GridViewColumn() { DisplayMemberBinding = new Binding("String1") }); grid.Columns.Add(new GridViewColumn() { DisplayMemberBinding = new Binding("String2") }); etc.
But how do you add the title headers? And the items?
Hi, Thank you very much, this was very usefull for me, like all the others posts. Greate job.
excelente
Great article.
Ray Akkanson
Interesting and useful article. I think it would be worthwhile to call a little more attention to the addition of the "DataContext="{Binding RelativeSource={RelativeSource Self}}"" line in the Window definition in the XAML though.
Took me a while to figure out that this was what was preventing the databinding in my application from working . . .
That is a HUGE and good point Steve. Beat my head against a wall for three weeks on this problem (along with some others) and I want to thank you for pointing that out.
Thanks
Yeah thanks from me too.
I was trying to figure this for ages.
Also wanted to agree - this is a HUGE omission.
Thanks alot for pointing this out. I am new to WPF but i did think that datacontext needed to be set but like many others i missed that line.
thanks again
Hi,
Thanks for the great article. I want to know how to make listview data editable?? (Editable Cells).
As I have seen with several other forums, we can celltemplate for this and we can add text boxes to each and every cell. But this is quite complex, do you have any other simple solution for making editable ?
Thanks!
hI, cAN ANYONE PLZ TELL ME HOW CAN I SET WIDTH OF COLUMN DYANAMICALLY EQUAL TO SIZE OF DATA COMING IN COLUMN
THANKS IN ADVANCE
According to the MSDN article on column width, the column defaults to that behavior. You can also explicitly set the Width to "Auto".
The only downside is that this only works for currently visible rows since the ListView is virtualized. Meaning when the collection is bound, the only rows that will affect the column's width will be those that are currently visible - so if you have a longer item that is not scrolled into view, it will be cut off. You can probably get around it by changing the ItemsPanel, but it's not something I've tried on a ListView.
I know the article is 5 years old at the time I'm replying but... Wonderful! Really helped me out.
However setting the column width to auto does not work in 2012.
Any updates for how to do this?
This article is horrible. The author set forth to create a simple ListView tutorial- Great! However the author added complexity on top of the simplicity that makes it hard for the intended audience to understand. Worse episode ever! You reader calling it great suck too.
A Person, unfortunately the ListView in WPF is inherently difficult to use by requiring binding. This article is about as simple as it gets for creating and populating one.
I like hearing different views about articles, however I think this article and our readers are great!
Pretty simple and well explained. If you didn't get it, then you are in the wrong business
I'm new to WPF myself. This article is QUITE good. Please don't be insulting the good people who do their best to spread the knowledge, and do it well.
To the author, my gratitude.
Hi A Person, I don't agree with you. I think the article is good. I think you'd better ask the author or other audience any parts you don't understand. That's much better than moaning.
A Person, I can't disagree with you more. This article was extremely useful in explaining a rather difficult concept, for beginners. The only part he missed as Steve pointed out was not drawing more attention to the DataContext.
Great job by the author on this, it was super helpful.
It is simplest one I ever see the only thing that is missing is no mentiin of that relative source as others already commented
Many thanks! Short, clear, useful. Great!
Gud tutorial!!! for a beginner....
can u please explain me how to delete a selected row from the grid......
Hi! Very usefull artice, like 4 me :)
Thanks!
I have noticed that it works ok when adding/deleting items to an ObservableCollection. However, when editing an item (via a separate dialog), the listview is not repopulated automatically or should I call some change notification?
hi can anyone say how to show some animation when user just move the mouse pointer over the list items in listview using wpf & c#.for example. i ve 3 items in the listview, when i move over th first item,then that list item should show some animation letting to know to the user that he/she ve move over that correspoding listitem.
expecting a great help from the .net lovers to solve this problem, as this is my first and foremost requirement in my assignment, kindly make it as fast as possible please, thanks to all in advance and the article abov is of vey great for the users, thanks to the author
Excellently written and not precisely what I was looking for but very related and saved me a large amount of time. Thanks yet again for teaching me something I didn't know. I love this site.
Excellently written and Very Good. Thanks
Can anyone tel me how can we turn on the gridlines, i mean both the horizontal and vertical.
Unfortunately, I don't think there's an easy way to do that. Here's a solution I've used in the past.
http://www.designerwpf.com/2007/12/11/how-do-i-set-up-grid-lines-for-my-listview/
Hi There Thanks, it was a very good article. My question is, how to get data from SQL server.
Thanks MikeA
Excellent example, both clear and simple! Spent a vary frustraiting day trying to find this solution online before I ran across yours.
I still don't understand why:
doesn't work but figure I'll run across the answer eventually. (It doesn't crash but the DisplayMemeberBinding can't find them so you get a blank ListView.)
Thanks So Much! Bruce
It doesn't work because those fields aren't properties, they're just public member variables. To make it work change those fields to properties:
One addition: make sure that the list is a propery too. Else it will not work.
Is there an explanation for why these must be properties, and cannot just be data objects?
This was a great article. I struggled during the day to get my ListView to populate from a collection, and a quick search brought me here and you had the answer. Thank you.
Thanks , it was very useful.
This was very informative and easy to understand. Thanks.
Its good stuff of code ......working good .... Thanks buddy......
Hi,
I've done my first WCF services recently and now trying to build a WPF webclient to view some data.
Your tutorial helped me with my first steps with ListView in WPF. But now I'm trying to refresh the data and can't get it working. I've already refreshed the objects in the bound collection but the ListView doesn't reflect the changes.
So I think I'm missing something don't I?
Since the ListView is bound to an ObservableCollection, changes made to the collection will be reflected (items added, removed, etc). Since the objects themselves do not implement INotifyPropertyChanged or use Dependency Properties, changes made to the object will not be reflected in the ListView. The object will have to implement something that will allow the ListView to know when a property has changed.
You have to modify the Properties to be DependencyProperty. Note that if you put in the static declaration, you have to change the get and sets to use GetValue() and SetValue(). If you don't, you won't see the value update. It took me forever to track this down. Thought I would add it here.
[C#] public static readonly DependencyProperty SftpTransferStatusProperty = DependencyProperty.Register("SftpTransferStatus", typeof(TransferStatus), typeof(SftpTransfer), new UIPropertyMetadata(null)); public TransferStatus SftpTransferStatus { get { return (TransferStatus)GetValue(SftpTransferStatusProperty); } set { SetValue(SftpTransferStatusProperty, value); } } [/C#]
Just wanted to say that this is indeed a great tutorial.
I would also wanted to say(at least, that is what my experiments showed after a few hours) that you must init the ObservableCollection in the begining or add in the get a
statment as follows(and please correct me if I am wrong):
Yes, it would make sense that you would need to initialize the observable collection. If you do not do this and then try to add an element to it then it will throw an error. The sample does this at the beginning of the class which from what I've seen is best practice. I like to keep my properties as clean as possible.
In the first part, the date format defaults to the US foramat, most of the rest of the world uses ISO date format (yyyy/mm/dd) my computer is set to Canada with the correct date format (Not the WRONG one that MS defaults Canada to) and I still get the incorrect format when i run it. A little off topic, but how do i correct the date format in this example (applies to real world aps). Even this website shows the wrong date format for comments... this is much more serious issue in the real world of commerce than most people realize. Thanks.
By default the ToString method will be called on objects to generate what's displayed in the ListView. What you'll need to do is create a binding converter to convert the DateTime to the string you'd like displayed.
DateTime has dozens of default string generators as well as accepting parameters to its overridden ToString to create pretty much any format you can imagine.
Very helpful article, thanks.
Great article and works great when the control is a WPF window. I have a legacy WinForms solution that we are slowly adding WPF controls to.
When I use this code as a user control (change the word 'Window' with 'UserControl') and embed into a WinForms control with hosted content, adding items to the ObservableCollection does not cause a redraw of the WPF listview.
Does anyone know why this is? I even added a call to the WPF listview's InvalidateVisual() but it did not draw the items in the collection.
Thanks!
One problem I have with using the class data as listviewitems is you loose many of the features and functions of a listviewitem itself, like IsSelected. Any ideas? Should the class derive from ListViewItem?
Well-written and to the point. I did get snagged for a few mins on this:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
but that wasn't your fault. You all should pay attention to that line or your list won't bind.
Hey,
great article. Thx for that! But i got one question. Your example works fine but i add three rows in the code behind and several new rows with a "add a row" button. That works as well...the new rows are added under the first three rows.
My problem is that i cant select the new rows with the mouse. The new rows arent selected with a blue background...only with a dotted border around them which is generated when i use the arrow keys to go up/down in the listview.
anyone any idea to solve this problem?
I just realized that i can select the new rows with pressed crtl key and mousebutton but thats not a good solution. I need them beeing selected only using left mouse button but that doesnt work.
in fact the first new row added with the "add a new row" button can be selected...but the rest doesnt work :(
I know this article is old but I just wanted to thank you for your excellent work! I'm a WPF noob & was totally stuck with listview & gridview. Thanks again!
how do i create listview dynamically using c# code instead of writing it in xaml.
Thanks for this great article! I have just one more question:
How can I get this ListView to show a scrollbar when the amount of contents warrants it?
Ah, I just found it!
You have to place the StackPanel inside a ScrollViewer!
Excellent article. I have several WPF books but this was exactly what I needed. Worked perfectly. Thanks.
As "good Job" described before, without the line
DataContext="{Binding RelativeSource={RelativeSource Self}}"
the sample did not work. But what, if the window itself HAS a (different) datacontext? In that moment the sample did not work for me and currently i did not find a solution to refresh the listview after adding items to the collection.
*sick*
@ Linus
It's also my question so I posted it here
http://www.codeproject.com/Questions/204390/WPF-Binding-multiple-DataContexts-code-behind.aspx
How do I bind the observable collection in code ratehr than xaml?
_myListView.ItemsSource = _GameCollection;
Great article, my friend! The first on listview and gridview I could completely understand!!! Much thanks!
I copied your code and just changed the name of the collection from GameCollection to CustomerCollection. and it doesn't work. I modified the ItemsSource on the xaml as well. What could be the problwm?
You need to set the itemsource in code
give the list view a name like this
then in your code set the itemsource listview1.ItemsSource = GameCollection;
Very helpful!
Thank you from me!
Thank You very much! Realy nice solution.
Hi,
After I can add the value. How can I remove from the list according to GameName?
Hi, Firstsly, love your article! I wanted to know, if there is any way this way that i could have an event handler for the item chosen? I dont want to change the code from what you have done in this. Thanks!
Simply hook the SelectionChanged event.
the data is added to the colletion but not displayed in the listview..
Great bit of work!!
I'm used to Silverlight datagrids so this helped me a great deal as i am new to WPF (althou there doesn't seem to be too much different)
Keep em coming!!
How do I get rid of that extra column (on the right)????
THIS IS KILLING ME!
It's not technically a column, it's just the extra space. This ListView doesn't have a direct means to make the columns fill the available space. The DataGrid does however. If you set the width of a DataGridColumn to "*", that column will expand to fill the remaining available space.
Sorry -- Hit anon before.
The example (and my own code) doesn't use a DataGrid; it uses a GridView, which doesn't support Width="*", at least not out of the box. I've tried using added behaviours to set the width to "*" but that doesn't remove the "extra space." I also tried "Auto", as you can see from the snippet below.
I've been beating my head against this for days now...
The easiest solution is to switch to the DataGrid. Since that was released, creating GridViews isn't really an approach I do very often.
If you have to use a ListView, I could see using a Multibinding and a converter to get that done. Basically setup a Multibinding to bind the width of the column you'd like to stretch to the width of the ListView and the widths of every other column. Then, whenever any of those change, the converter can set the width of the stretch column equal to the total width of the ListView minus the widths of each column. That should make it fill the remaining space.
Easy to understand. Got my class collection displaying quickly and easily. Thank you.
Great Tutorial!!
Post in my Blog http://santimacnet.wordpress.com/ in section Tutorials
In my blog U can find another WPF Tutorial
http://santimacnet.wordpress.com/2010/12/02/curso-gratis-windows-presentation-foundation-wpf/
But how to delete the row?
What does it mean?
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Can I replace this line with code (and not in the XAML file)?
Thanks.
That line sets the DataContext to itself. In code it's equivalent to saying:
Could someone please explain how I can make the ListView update when one of the fields changes? From earlier comments I can see that this should be done by either implementing INotifyPropertyChanged or making the fields Dependency properties but I am unsure how to do this. Cheers.
Thank-you for this tutorial... :)