Ask a questionAsk a question
 

AnswerListView with NO items at all

  • Thursday, November 05, 2009 12:27 AMzameb Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    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

  • Thursday, November 05, 2009 1:50 AMFoovanadil Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    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

  • Thursday, November 05, 2009 1:50 AMFoovanadil Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    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
    •  
  • Thursday, November 05, 2009 10:46 AMzameb Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    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
  • Thursday, November 05, 2009 3:29 PMFoovanadil Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Awesome, glad I could help