954,557 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Populating ListView in WPF Programmatically

I have started the familiarize myself with WPF and have gotten stuck with the ListView

I've read a lot of documentation about binding and I can't seem to find how to populate a ListView programmatically. It seems like a lot of work to create the binding and classes, etc, just to fill a ListView.

So I have 2 questions.
1. If you want to populate a ListView with data that a user has inputted, is the correct way in WPF to populate the ListView with binded data?

2. How do you add items and subitems to a ListView in code? (There doesn't seem to be a subitems in WPF.)

Thanks in advance!

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

Its actually not much work. Check this example:

The Designer part:

<Window x:Class="MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:local="clr-namespace:WpfApplication1"
		Title="MainWindow"
		Height="400"
		Width="600">
	<Grid>
		<Grid.RowDefinitions>
			<RowDefinition />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
			<RowDefinition Height="Auto" />
		</Grid.RowDefinitions>
		<Grid.Resources>
			<HierarchicalDataTemplate DataType="{x:Type local:Dummy}"
									  ItemsSource="{Binding Path=.}">
				<StackPanel>
					<StackPanel Orientation="Horizontal">
						<TextBlock Text="{Binding Path=ID}" />
						<TextBlock Text=" - " />
						<TextBlock Text="{Binding Path=Name}" />
					</StackPanel>
					<ItemsControl Margin="30,0,0,0"
								  ItemsSource="{Binding Data}" />
				</StackPanel>
			</HierarchicalDataTemplate>
		</Grid.Resources>
		<ListView x:Name="lst" />
		<Button Grid.Row="1"
				Margin="0,10,0,5"
				Content="Add items from code behind"
				Click="ManuallyAdded_Click" />
		<Button Grid.Row="2"
				Margin="0,5,0,10"
				Content="Clear Listview"
				Click="Clear_Click" />
		<Button Grid.Row="3"
				Content="Bind listview to source"
				Click="SourceBinding_Click" />
	</Grid>
</Window>


Code behind:

Imports System.Collections.ObjectModel

Class MainWindow

	Private Sub ManuallyAdded_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
		ResetItems()
		For i As Integer = 0 To 10
			Dim dum As Dummy = CreateDummy(i)
			GetDummies(dum)
			lst.Items.Add(dum)
		Next
	End Sub

	Private Sub SourceBinding_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
		Dim source As New List(Of Dummy)
		For i As Integer = 0 To 10
			Dim dum As Dummy = CreateDummy(i)
			GetDummies(dum)
			source.Add(dum)
		Next
		ResetItems()
		lst.ItemsSource = source
	End Sub

	Private Sub Clear_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
		ResetItems()
	End Sub

	Private Sub GetDummies(parent As Dummy)
		For i As Integer = 0 To 10
			parent.Data.Add(CreateDummy(i))
		Next
	End Sub

	Private Function CreateDummy(i As Integer) As Dummy
		Return New Dummy With {.ID = i, .Name = "Dummy" & i}
	End Function


	Private Sub ResetItems()
		lst.ItemsSource = Nothing
		lst.Items.Clear()
	End Sub
End Class

Public Class Dummy

	Public Property ID() As Integer
	Public Property Name() As String
	Public Property Data() As New ObservableCollection(Of Dummy)

End Class


Hope it helps.

GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

Thanks for the advice, I'm going through it at the moment.

I'm getting an unhandled exception error on the line:

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

After adding the Dummy Class, you have to compile the code. After compiling you can use the {x:Type local:Dummy}
Your application name is "Hello_World" i assume. Then make sure the Dummy class is not in a different namespace. If you in example have the dammy class in namespace "Models" then you have to change xmlns:local="clr-namespace:Hello_World" to xmlns:local="clr-namespace:Hello_World.Models"

If you cant get it to work, then you can attach your project here and i will take a look in it.

GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

Thanks again!

I just had to rebuild :)

I think it's something I'm going to have to get used to with WPF.

I'm going to use your code as a guide and see if I can figure this all out.

Much appreciated!

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

A quick question. How come the items are not put inside the ListView?

How does WPF know to put the StackPanel and the ItemsControl inside the ListView?

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

this is defined in the HierarchicalDataTemplate. Means, whenever a item in this window is of type "local:Dummy" then this template will get used.

GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

I'm starting to understand the binding now, thank you. I just don't understand what the point was of MS changing away from the way forms used to work to using binding? It really wasn't that much of a hassle to say Textbox1.Text = Textbox2.Text.

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

Once you fully understand the binding in WPF you won't waste a single thought on to winforms anymore ;)
The bindings in WPF is so much more powerful and scalable, i won't miss it anymore.

GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

I've just been thinking ahead as to where I'm probably going to struggle with binding.

I'm updating an accounting application at the moment. Where I think I'm going to have the first major issue is in the Invoice screen. What happens is that when the user is in the first column of the datagrid, they input an item code and press Enter. The application then fetches the data and populates some of the other columns in that row with the data. (eg: Description and Selling Price.) The user can then press Enter to get to the quantity and if they update the quantity, the Total Selling Price would need to be updated. It seems that this is going to be tough to do with binding.

Do you have any suggestions as to how to go about doing this?

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

If you populate your data from a SQL server then i would suggest you to take a look at "LINQ to SQL" or "Entity Framework Models".

GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

Had this project handed over to me, it's using mysql.

Would you suggest using a 3rd party datagrid control?

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

I've now managed to figure out the populating of the List from your example.

How do I now read those values if I want loop through the List?

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 
For Each item As Dummy In lst.Items
			Debug.WriteLine(item.Name)
		Next
GeekByChoiCe
Master Poster
721 posts since Jun 2009
Reputation Points: 208
Solved Threads: 168
 

:$ thanks!

danielgr
Light Poster
25 posts since Jun 2011
Reputation Points: 10
Solved Threads: 1
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: