.NET Framework Developer Center >
.NET Development Forums
>
Windows Presentation Foundation (WPF)
>
ListView with NO items at all
ListView with NO items at all
- Hi, it's me again.
I've been asking about empty items, object's names instead of values and now this. It seems I'm having lots of problems with ListViews.
My previous questions were all about code, now all of these are ok, I'm trying now with XAML. Please, look at my case.
When I run my app, my list has zero items. I'm trying to bind from xaml, this is my code:
*******
*******<Page x:Class="ListViewSample5" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataContext="{Binding RelativeSource={RelativeSource Self}}" Title="ListView1" Background="CadetBlue" Name="Page1"> <Grid Height="217" Width="591"> <ListView Name="lstBooks" Margin="0,10,0,0" ItemsSource="{Binding books}"> <ListView.View> <GridView> <GridViewColumn Width="240" Header="Titulo" DisplayMemberBinding="{Binding Titulo}" /> <GridViewColumn Width="240" Header="Autor" DisplayMemberBinding="{Binding Autor}" /> </GridView> </ListView.View> </ListView> <Button Height="23" HorizontalAlignment="Right" Margin="0,0,29,-29" Name="cmdAdd" VerticalAlignment="Bottom" Width="75">Agregar</Button> </Grid> </Page>
I see my Items Source is not working at my xaml... what is wrong (if any) with this single line?:
<ListView Name="lstBooks" Margin="0,10,0,0" ItemsSource="{Binding books}">
(if I put lstBooks.ItemsSource = books on the page_loaded event, it works right. But I want to do that binding from xaml)
I also don't understand the following line, I get it from a sample that doesn't explain anything about it:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
*******
*******Imports System.Collections.ObjectModel Partial Public Class ListViewSample5 Private books As New ObservableCollection(Of bookBO) Private Sub Page1_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded fillTable() 'lstBooks.ItemsSource = books End Sub Sub fillTable() books.Add(New bookBO("Windows Presentation Foundation Unleashed", "Adam Nathan")) books.Add(New bookBO("Pro WPF with VB 2008", "Matthew McDonald")) books.Add(New bookBO("3D Programming-for-windows by WPF", "Charles Petzold")) End Sub End Class
books is just a collection, declared as follows:
Private books As New ObservableCollection(Of bookBO)
And this is bookBO
*******
*******Public Class bookBO Private mTitulo As String Private mAutor As String Public Sub New(ByVal Titulo As String, ByVal Autor As String) mTitulo = Titulo mAutor = Autor mCalificacion = 5 End Sub Public Property Titulo() As String Get Titulo = mTitulo End Get Set(ByVal value As String) mTitulo = value End Set End Property Public Property Autor() As String Get Autor = mAutor End Get Set(ByVal value As String) mAutor = value End Set End Property Public Overrides Function ToString() As String ToString = mTitulo + " - " + mAutor End Function End Class
Thank you guys,
Zameb
Answers
- First to answer your question about the RelativeSource markup extension :
"I also don't understand the following line, I get it from a sample that doesn't explain anything about it: DataContext="{Binding RelativeSource={RelativeSource Self}}"
What this is doing is setting the source for your binding to the ListViewSample5 class. The RelativeSource markup extension allows you to traverse the VisualTree looking for an element matching your relative source path. When that element is found it is used as the source for your binding.
In your case you specified RelativeSource Mode=Self (the Mode attribute is implied as it is the default attribute for the RelativeSource markup extension and you have only one value therefore it sets the default attribute)
What "self" means is the instance of the object that the binding is set on. So in your case you are setting the DataContext property of the Page class (which is an instance of ListViewSample5). So the "self" refers to the instance of ListViewSample5. Therefore you are setting your Binding source equal to your code behind. RelativeSource can be very confusing so hopefully this helps a little?
Now, to your actual problem. Why are you not getting any items in your list view. Well, from the above explanation we know that your Binding source is set to your code behind. In your code behind you have a private member declared called books. You are trying to bind to that collection in XAML, however, since the member is private the Binding extension cannot see it. If you provide a public accessor for your private member variable that should fix your problem.
the binding pipeline in WPF makes use of reflection to perform these bindings, when doing reflection on your object it will only find public properties of your class, therefore you cannot bind to anything that is not public.
Hope that helps
--Brad
- Proposed As Answer byDutchMarcel Thursday, November 05, 2009 7:47 AM
- Marked As Answer byzameb Thursday, November 05, 2009 10:46 AM
All Replies
- First to answer your question about the RelativeSource markup extension :
"I also don't understand the following line, I get it from a sample that doesn't explain anything about it: DataContext="{Binding RelativeSource={RelativeSource Self}}"
What this is doing is setting the source for your binding to the ListViewSample5 class. The RelativeSource markup extension allows you to traverse the VisualTree looking for an element matching your relative source path. When that element is found it is used as the source for your binding.
In your case you specified RelativeSource Mode=Self (the Mode attribute is implied as it is the default attribute for the RelativeSource markup extension and you have only one value therefore it sets the default attribute)
What "self" means is the instance of the object that the binding is set on. So in your case you are setting the DataContext property of the Page class (which is an instance of ListViewSample5). So the "self" refers to the instance of ListViewSample5. Therefore you are setting your Binding source equal to your code behind. RelativeSource can be very confusing so hopefully this helps a little?
Now, to your actual problem. Why are you not getting any items in your list view. Well, from the above explanation we know that your Binding source is set to your code behind. In your code behind you have a private member declared called books. You are trying to bind to that collection in XAML, however, since the member is private the Binding extension cannot see it. If you provide a public accessor for your private member variable that should fix your problem.
the binding pipeline in WPF makes use of reflection to perform these bindings, when doing reflection on your object it will only find public properties of your class, therefore you cannot bind to anything that is not public.
Hope that helps
--Brad
- Proposed As Answer byDutchMarcel Thursday, November 05, 2009 7:47 AM
- Marked As Answer byzameb Thursday, November 05, 2009 10:46 AM
- Thank you Brad, I did as you recommended and it's working now.
And I also found all your explanation very clear and useful.
I have created getter and setter for my private variable and its working very well now
Cheers,
Zameb - Awesome, glad I could help


