locked
Lists within lists, databinding? RRS feed

  • Question

  • I have a list of Elements. Each Element has a list of Activities and a list of ComplementaryActivities. These lists might be empty.

    I want to display each Element, Activity and ComplementaryActivity with two buttons (Edit and Remove) after each of them.

    Preferably this would look something like this

    I've tried doing this with stackpanels and databinding and listboxes within listboxes, but the databinding doesn't work on a listbox that haven't yet been created, and it haven't been created because it exists within a stackpanel within an other listbox. Is there any half-easy way to do this? When creating the lists I have no way of knowing how big they are. I don't have to do it with databinding if there is an easier way, but all data is loaded dynamically.

    /d
     

    Friday, November 28, 2008 8:46 AM

Answers

  • Hi ,

    You need to setup your source to something like this:
      

    Public Class Element
        Private _Name As String
        Private _lstActivity As List(Of Activity)
        Private _lstComplementaryActivity As List(Of ComplementaryActivity)
    
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Public Property Ele_Avtivity() As List(Of Activity)
            Get
                Return _lstActivity
            End Get
            Set(ByVal value As List(Of Activity))
                _lstActivity = value
            End Set
        End Property
        Public Property Ele_ComplementaryActivity() As List(Of ComplementaryActivity)
            Get
                Return _lstComplementaryActivity
            End Get
            Set(ByVal value As List(Of ComplementaryActivity))
                _lstComplementaryActivity = value
            End Set
        End Property
        Public Sub New(ByVal n As String, ByVal lstAct As List(Of Activity), ByVal lstCA As List(Of ComplementaryActivity))
            Name = n
            Ele_Avtivity = lstAct
            Ele_ComplementaryActivity = lstCA
        End Sub
    End Class
    
    Public Class Activity
        Private _Name As String
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Public Sub New(ByVal n As String)
            Name = n
        End Sub
    End Class
    
    Public Class ComplementaryActivity
        Private _Name As String
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Public Sub New(ByVal n As String)
            Name = n
        End Sub
    End Class

     

    I have used the above classes to construct my Nested data list and here is  the xaml file:

     

    <UserControl x:Class="SilverlightDeployment.NestedListbox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Loaded="UserControl_Loaded">
        <Grid x:Name="LayoutRoot" Background="White">
            <ListBox x:Name="ElementListBox" ItemsSource="{Binding}" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Name}" />
                                <Button Content="Edit"/>
                                <Button Content="Remove"/>
                            </StackPanel>
                            <ListBox x:Name="ActivityListBox" ItemsSource="{Binding Ele_Avtivity}" >
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Name}" />
                                            <Button Content="Edit"/>
                                            <Button Content="Remove"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                            <ListBox x:Name="ComplementaryActivityListBox" ItemsSource="{Binding Ele_ComplementaryActivity}" >
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Name}" />
                                            <Button Content="Edit"/>
                                            <Button Content="Remove"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    
        </Grid>
    </UserControl>
    

      and related code behind:

     

    Imports System.Windows.Data
    
    Partial Public Class NestedListbox
        Inherits UserControl
    
        Public Sub New()
            InitializeComponent()
        End Sub
    
        Private Sub UserControl_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            Dim lstActivity1 As New List(Of Activity)
            lstActivity1.Add(New Activity("Activity11"))
            lstActivity1.Add(New Activity("Activity12"))
    
            Dim lstActivity2 As New List(Of Activity)
            lstActivity2.Add(New Activity("Activity21"))
            lstActivity2.Add(New Activity("Activity22"))
    
            Dim lstCA1 As New List(Of ComplementaryActivity)
            lstCA1.Add(New ComplementaryActivity("CA11"))
            lstCA1.Add(New ComplementaryActivity("CA12"))
    
            Dim lstCA2 As New List(Of ComplementaryActivity)
            lstCA2.Add(New ComplementaryActivity("CA2"))
    
            Dim lstElement As New List(Of Element)
            lstElement.Add(New Element("Element1", lstActivity1, lstCA1))
            lstElement.Add(New Element("Element2", lstActivity2, Nothing))
            lstElement.Add(New Element("Element3", Nothing, lstCA2))
            lstElement.Add(New Element("Element4", Nothing, Nothing))
            lstElement.Add(New Element("Element5", Nothing, Nothing))
    
            Dim b As New Binding()
            b.Source = lstElement
            ElementListBox.SetBinding(ListBox.ItemsSourceProperty, b)
        End Sub
    End Class
     (Let me know if still have problem else mark reply as answer) 
    -Vinit 
    Monday, December 22, 2008 8:25 AM

All replies

  • <ListBox x:Name="MainList">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Height="30" Orientation="Horizontal">                        
                            <TextBlock Width="200" Text="{Binding Name}"/>                            
                            <Button Width="40" Content="Edit"/>
                            <Button Width="40" Content="Remove"/>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

    So here you should have a List with a Name variable say like

      public class Activity
        {
            public string Name { get; set; }
        }

        List<Activity> myAct = new List<Activity>();

    Binding can be done by:

    MainList.ItemsSource = myAct;

    Friday, November 28, 2008 9:57 AM
  •  Thanks for your answer. Sure, that works. The problem is that I want to have a list outside of that list. I want this:

     XAML:

     <ListBox x:Name="ElementListBox" >
    <ListBox.ItemTemplate>
    <DataTemplate>
    <StackPanel Orientation="Vertical">
    <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Name}" />
    <Button Content="Edit"/>
    <Button Content="Remove"/>
    </StackPanel>
    <ListBox x:Name="ActivityListBox" >
    <ListBox.ItemTemplate>
    <DataTemplate>
    <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Name}" />
    <Button Content="Edit"/>
    <Button Content="Remove"/>
    </StackPanel>
    </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>
    <ListBox x:Name="ComplementaryActivityListBox" >
    <ListBox.ItemTemplate>
    <DataTemplate>
    <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Name}" />
    <Button Content="Edit"/>
    <Button Content="Remove"/>
    </StackPanel>
    </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>
    </StackPanel>
    </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>
     

    C#:

     

    ListBox elementListBox = (ListBox)grid.FindName("ElementListBox");
    ListBox acticvityListBox = (ListBox)grid.FindName("ActivityListBox");
    ListBox complementaryActicvityListBox = (ListBox)grid.FindName("ComplementaryActivityListBox");

    acticvityListBox.ItemsSource = cie.activities;
    complementaryActicvityListBox.ItemsSource = cie.complementaryActivities;
    elementListBox.ItemsSource = elements;
     

     

    But since activityListBox and complementaryActicvityListBox are inside a DataTemplate, FindName() can't find them, which means I can't set the ItemsSource.

    Tuesday, December 2, 2008 5:16 AM
  • Sorry for bumping this, but I have yet to find a solution to this problem. 

    Monday, December 22, 2008 7:40 AM
  • Hi ,

    You need to setup your source to something like this:
      

    Public Class Element
        Private _Name As String
        Private _lstActivity As List(Of Activity)
        Private _lstComplementaryActivity As List(Of ComplementaryActivity)
    
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Public Property Ele_Avtivity() As List(Of Activity)
            Get
                Return _lstActivity
            End Get
            Set(ByVal value As List(Of Activity))
                _lstActivity = value
            End Set
        End Property
        Public Property Ele_ComplementaryActivity() As List(Of ComplementaryActivity)
            Get
                Return _lstComplementaryActivity
            End Get
            Set(ByVal value As List(Of ComplementaryActivity))
                _lstComplementaryActivity = value
            End Set
        End Property
        Public Sub New(ByVal n As String, ByVal lstAct As List(Of Activity), ByVal lstCA As List(Of ComplementaryActivity))
            Name = n
            Ele_Avtivity = lstAct
            Ele_ComplementaryActivity = lstCA
        End Sub
    End Class
    
    Public Class Activity
        Private _Name As String
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Public Sub New(ByVal n As String)
            Name = n
        End Sub
    End Class
    
    Public Class ComplementaryActivity
        Private _Name As String
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        Public Sub New(ByVal n As String)
            Name = n
        End Sub
    End Class

     

    I have used the above classes to construct my Nested data list and here is  the xaml file:

     

    <UserControl x:Class="SilverlightDeployment.NestedListbox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Loaded="UserControl_Loaded">
        <Grid x:Name="LayoutRoot" Background="White">
            <ListBox x:Name="ElementListBox" ItemsSource="{Binding}" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Name}" />
                                <Button Content="Edit"/>
                                <Button Content="Remove"/>
                            </StackPanel>
                            <ListBox x:Name="ActivityListBox" ItemsSource="{Binding Ele_Avtivity}" >
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Name}" />
                                            <Button Content="Edit"/>
                                            <Button Content="Remove"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                            <ListBox x:Name="ComplementaryActivityListBox" ItemsSource="{Binding Ele_ComplementaryActivity}" >
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="{Binding Name}" />
                                            <Button Content="Edit"/>
                                            <Button Content="Remove"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    
        </Grid>
    </UserControl>
    

      and related code behind:

     

    Imports System.Windows.Data
    
    Partial Public Class NestedListbox
        Inherits UserControl
    
        Public Sub New()
            InitializeComponent()
        End Sub
    
        Private Sub UserControl_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            Dim lstActivity1 As New List(Of Activity)
            lstActivity1.Add(New Activity("Activity11"))
            lstActivity1.Add(New Activity("Activity12"))
    
            Dim lstActivity2 As New List(Of Activity)
            lstActivity2.Add(New Activity("Activity21"))
            lstActivity2.Add(New Activity("Activity22"))
    
            Dim lstCA1 As New List(Of ComplementaryActivity)
            lstCA1.Add(New ComplementaryActivity("CA11"))
            lstCA1.Add(New ComplementaryActivity("CA12"))
    
            Dim lstCA2 As New List(Of ComplementaryActivity)
            lstCA2.Add(New ComplementaryActivity("CA2"))
    
            Dim lstElement As New List(Of Element)
            lstElement.Add(New Element("Element1", lstActivity1, lstCA1))
            lstElement.Add(New Element("Element2", lstActivity2, Nothing))
            lstElement.Add(New Element("Element3", Nothing, lstCA2))
            lstElement.Add(New Element("Element4", Nothing, Nothing))
            lstElement.Add(New Element("Element5", Nothing, Nothing))
    
            Dim b As New Binding()
            b.Source = lstElement
            ElementListBox.SetBinding(ListBox.ItemsSourceProperty, b)
        End Sub
    End Class
     (Let me know if still have problem else mark reply as answer) 
    -Vinit 
    Monday, December 22, 2008 8:25 AM
  • Thanks! It seems to be working now!  

    Monday, December 22, 2008 9:22 AM