1

I have tried to bind a List of objects to a ListBox, but when run it has no items in the ListBox, the List itself does have items.

List<Module> _modules

public class Module
{
    public Module(string ModuleName, string ModuleAbbreviation, string ModuleColor, bool ModuleAvailable)
    {
        this.ModuleName = ModuleName;
        this.ModuleAbbreviation = ModuleAbbreviation;
        this.ModuleColor = ModuleColor;
        this.ModuleAvailable = ModuleAvailable;
    }

    public string ModuleName { get; set; }
    public string ModuleAbbreviation { get; set; }
    public string ModuleColor { get; set; }
    public bool ModuleAvailable { get; set; }
}

ViewModel code is below (it has been shortened, the relevant code for the Module List has been included):

namespace Users.ViewModel
{
    public class AllUsersViewModel
    {
        public List<Module> _modules = new List<Module>();

        #region Constructor

        public AllUsersViewModel()
        {
            this.SetModuleList();
            this.CreateAllUsers();
        }

        void SetModuleList()
        {
            _modules = ModuleRepository.GetModules();
        }

        public IEnumerable<Module> Modules
        {
            get { return _modules; }
        }

        void CreateAllUsers()
        {
            List<UserViewModel> all =
                (from cust in _userRepository.GetUsers()
                 select new UserViewModel(cust, _userRepository)).ToList();

            foreach (UserViewModel cvm in all)
                cvm.PropertyChanged += this.OnUserViewModelPropertyChanged;

            this.AllUsers = new ObservableCollection<UserViewModel>(all);
            this.AllUsers.CollectionChanged += this.OnCollectionChanged;
        }

        public ObservableCollection<UserViewModel> AllUsers { get; private set; }

        ....
    }
}

Following is the XAML: (A bit further than half way you'll see a ListBox called lstModules)

<UserControl.Resources>
    <CollectionViewSource x:Key="UserCollection" Source="{Binding Path=AllUsers}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Name" Direction="Ascending" />
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</UserControl.Resources>
<DataGrid AutoGenerateColumns="False" ItemContainerStyle="{StaticResource UserItemStyle}" AlternatingRowBackground="{x:Null}" ItemsSource="{Binding}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
        <DataGridTextColumn Header="Job Title" Binding="{Binding Path=Job_Title}"/>
        <DataGridTextColumn Header="Department" Binding="{Binding Path=Department}"/>
        <DataGridTextColumn Header="Company" Binding="{Binding Path=Company}"/>

        <DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=Company}" CanUserResize="False" Width="580">
            <DataGridTextColumn.Header>
                <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                    <TextBlock HorizontalAlignment="Center">Modules</TextBlock>
                    <ListBox x:Name="lstModules" Width="190" ItemsSource="{Binding Modules}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding ModuleName}"></TextBlock>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>
            </DataGridTextColumn.Header>
        </DataGridTextColumn>
        <DataGridTextColumn Header="Contact Detail" Binding="{Binding Path=Name}"/>
    </DataGrid.Columns>
</DataGrid>

[Edit] Full XAML

<UserControl x:Class="Users.View.AllUsersView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase" 
             mc:Ignorable="d" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             d:DesignHeight="160" d:DesignWidth="1100">

    <UserControl.Resources>
        <CollectionViewSource x:Key="UserCollection" Source="{Binding Path=AllUsers}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Name" Direction="Ascending" />
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>

        <Style x:Key="UserItemStyle" TargetType="{x:Type DataGridRow}">
            <!-- 
              Stretch the content of each cell so that we can 
              right-align text in the Total Sales column. 
              -->
            <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            <!-- 
              Bind the IsSelected property of a ListViewItem to the 
              IsSelected property of a UserViewModel object.
              -->
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
            <Style.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <!--
                        <Condition Property="ItemsControl.AlternationIndex" Value="1" />
                        -->
                        <Condition Property="IsSelected" Value="False" />
                        <Condition Property="IsMouseOver" Value="False" />
                    </MultiTrigger.Conditions>
                    <Setter Property="Background" Value="#EEEEEEEE" />
                </MultiTrigger>
            </Style.Triggers>
        </Style>

        <DataTemplate x:Key="headerTemplate">
            <TextBlock Padding="0,0,0,0" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text="{Binding}"/>
        </DataTemplate>

        <Style x:Key="RowHeaderStyle2" TargetType="DataGridRowsPresenter">
            <Setter Property="Background" Value="{x:Null}"/>
        </Style>
        <Style x:Key="ColumnHeaderStyle" TargetType="DataGridColumnHeader">
            <Setter Property="VerticalContentAlignment" Value="Bottom"/>
            <Setter Property="VerticalAlignment" Value="Bottom"/>
            <Setter Property="Height" Value="25"/>
        </Style>
        <Style x:Key="ModuleColumnHeaderStyle" TargetType="GridViewColumnHeader">
            <Setter Property="VerticalContentAlignment" Value="Bottom"/>
            <Setter Property="Width" Value="550"/>
        </Style>
        <Style x:Key="rotatedTextStart" TargetType="TextBlock">
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="-45" />
                </Setter.Value>
            </Setter>
            <Setter Property="VerticalAlignment" Value="Bottom"/>
            <Setter Property="Width" Value="130"/>
            <Setter Property="Margin" Value="12,0,0,0"/>
        </Style>
        <Style x:Key="rotatedTextMiddle" TargetType="TextBlock">
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="-45" />
                </Setter.Value>
            </Setter>
            <Setter Property="VerticalAlignment" Value="Bottom"/>
            <Setter Property="Width" Value="130"/>
            <Setter Property="Margin" Value="-50,0,0,0"/>
        </Style>
        <Style x:Key="rotatedTextEnd" TargetType="TextBlock">
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="-45" />
                </Setter.Value>
            </Setter>
            <Setter Property="VerticalAlignment" Value="Bottom"/>
            <Setter Property="Width" Value="130"/>
            <Setter Property="Margin" Value="-50,0,12,0"/>
        </Style>
        <Style x:Key="ListViewItemRotatedText" TargetType="ListViewItem">
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="-45" />
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <DockPanel>
        <Grid DockPanel.Dock="Bottom" Margin="0,2,4,2">
            <StackPanel HorizontalAlignment="Right" Orientation="Horizontal" VerticalAlignment="Center">
                <TextBlock Text="Selected Users: " />
                <ContentPresenter Content="{Binding Path=TotalSelectedUsers}" ContentStringFormat="0" />
                <TextBlock Text=" of " />
                <ContentPresenter Content="{Binding Path=TotalUsers}" ContentStringFormat="0" />
            </StackPanel>
        </Grid>

        <DataGrid AutoGenerateColumns="False" ItemContainerStyle="{StaticResource UserItemStyle}" AlternatingRowBackground="{x:Null}" DataContext="{StaticResource UserCollection}" ItemsSource="{Binding}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" HeaderTemplate="{StaticResource headerTemplate}" Binding="{Binding Path=Name}"/>
                <DataGridTextColumn Header="Job Title" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" HeaderTemplate="{StaticResource headerTemplate}" Binding="{Binding Path=Job_Title}"/>
                <DataGridTextColumn Header="Department" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" HeaderTemplate="{StaticResource headerTemplate}" Binding="{Binding Path=Department}"/>
                <DataGridTextColumn Header="Company" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" HeaderTemplate="{StaticResource headerTemplate}" Binding="{Binding Path=Company}"/>

                <DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=Company}" CanUserResize="False" Width="580">
                    <DataGridTextColumn.Header>
                        <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                            <TextBlock HorizontalAlignment="Center">Modules</TextBlock>
                            <ListBox x:Name="lstModules" Width="190" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,  AncestorType={x:Type Window}}, Path=DataContext.Modules}">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding ModuleName}"></TextBlock>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </StackPanel>
                    </DataGridTextColumn.Header>
                </DataGridTextColumn>
                <DataGridTextColumn Header="Contact Detail" IsReadOnly="True" HeaderStyle="{StaticResource ColumnHeaderStyle}" HeaderTemplate="{StaticResource headerTemplate}" Binding="{Binding Path=Name}"/>
            </DataGrid.Columns>
        </DataGrid>
    </DockPanel>
</UserControl>
0

1 Answer 1

2

The ListBox belongs to DataGrid control, which has it's own DataContext (AllUsers), which doesn't have Modules property. You should get Modules from UserControl's DataContext:

<ListBox x:Name="lstModules" Width="190" 
    ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
         AncestorType={x:Type UserControl}},
         Path=DataContext.Modules}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ModuleName}"></TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Sign up to request clarification or add additional context in comments.

2 Comments

Just so I understand this, this has looked up the control hierarchy until it finds the UserControl and the UserControl is the AllUsersView which is attached to AllUsersViewModel, so it now knows about the Modules property??? Is this happening because I am in a set of data already e.g. the DataGrid with AllUsers?
That's correct. The ListBox is defined inside DataGrid control, which has it's own DataContext (AllUsers), which doesn't have Modules property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.