Search code examples
c#wpfdata-bindinglistbox

WPF Select item in one ListBox and show corresponding list in a second ListBox


I'm currently getting into c# and WPF and want to build my first small app. I want to select an Album in a first ListBox and then show the corresponding Songs in a second ListBox. I need some help with that. I splitted my View into two UserControls, one for the Albums and one for the Songs with some additional functionalities. Here's my code so far:

Album list code:

namespace BandManager.ViewModel
{
    public class AlbumViewModel
    {
        public List<Album> AlbumsList { get; set; }

        public AlbumViewModel()
        {
            AlbumsList = new List<Album>
            {
                new Album
                {
                    name ="Gravitous"
                },
                new Album
                {
                    name ="EP Two"
                }
            };
        }

    }

    public class Album
    {
        public string name { get; set; }
    }


}

Album List Xaml:

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BandManager"
             xmlns:ViewModel="clr-namespace:BandManager.ViewModel" x:Class="BandManager.AlbumSelection"
             mc:Ignorable="d" 
             d:DesignHeight="350" d:DesignWidth="250">



    <UserControl.DataContext> 
        <ViewModel:AlbumViewModel/>
    </UserControl.DataContext>


    <Grid Margin="10">

        <ListBox
            FontSize="20"
            ItemsSource="{Binding AlbumsList}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding name}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>


    </Grid>
</UserControl>

Song List code:

namespace BandManager.ViewModel
{
    public class SongListViewModel
    {

        public List<Song> SongsList { get; set; }

        public SongListViewModel()
        {
            SongsList = new List<Song>
            {
                new Song
                {
                    name ="Apodictic Certainty"
                },
                new Song
                {
                    name ="Ascension"
                },
                new Song
                {
                    name ="Catharsis"
                },
                new Song
                {
                    name ="The Journey"
                }
            };
        }

    }

    public class Song
    {
        public string name { get; set; }
    }
}

Song List Xaml:

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BandManager"
             xmlns:ViewModel="clr-namespace:BandManager.ViewModel" x:Class="BandManager.SongSelection"
             mc:Ignorable="d" 
             d:DesignHeight="350" d:DesignWidth="450">

    <UserControl.DataContext>
        <ViewModel:SongListViewModel/>
    </UserControl.DataContext>

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="4*" />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <ListBox 

            Grid.RowSpan="4" Margin="10">
        </ListBox> 

        <Image Grid.Column="1" Margin="20,10,20,10"/>

        <ComboBox Grid.Column="1" Grid.Row="2" Margin="10" FontSize="18">
            <ComboBoxItem FontSize="18" Content="Tabs"/>
            <ComboBoxItem FontSize="18" Content="Lyrics"/>
        </ComboBox>

        <Button Grid.Column="1" Grid.Row="3" Margin="10" FontSize="14" Content="Download"/>
        <Button Content="Play" Grid.Column="1" Grid.Row="1" Margin ="10,10,160,10" FontSize="14" />
        <Button Content="Stop" Grid.Column="1" Grid.Row="1" Margin ="70,10,100,10" FontSize="14" />
        <Slider Grid.Column="1" Grid.Row="1" Margin ="140,15,10,15"/>

    </Grid>
</UserControl>

Solution

  • I have modified your view model little bit, i hope this what you are looking for. I have added Selected Property in AlbumViewModel to get the selected album from ListBox. And the Songs of the selected album is displayed in the another list box next to it.

    Below is the view model code

    public class Song
    {
        public string name
        {
            get;
            set;
        }
    }
    public class Album
    {
        public string name
        {
            get;
            set;
        }
    
        public List<Song> Songs
        {
            get;
            set;
        }
    
        public Album(string name)
        {
            this.name = name;
            Songs = new List<Song>() { new Song { name = this.name+ " Song 1" }, new Song { name = this.name + " Song 2" } };
        }
    }
    public class AlbumViewModel
    {
        public List<Album> Albums
        {
            get;
            set;
        } = new List<Album>();
    
        public AlbumViewModel()
        {
            Albums.Add(new Album("Album 1"));
            Albums.Add(new Album("Album 2"));
            Albums.Add(new Album("Album 3"));
            Albums.Add(new Album("Album 4"));
        }
    
        public Album Selected
        {
            get;
            set;
        }
    }
    

    Here is the modified xaml

    <UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BandManager"
             xmlns:ViewModel="clr-namespace:BandManager.ViewModel" x:Class="BandManager.AlbumSelection"
             mc:Ignorable="d" 
             d:DesignHeight="350" d:DesignWidth="250">
    
    
    
    <UserControl.DataContext> 
        <ViewModel:AlbumViewModel/>
    </UserControl.DataContext>
    <StackPanel Orientation="Horizontal">
    
        <ListBox ItemsSource="{Binding Albums}" Margin="10"  SelectedValue="{Binding Selected}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    
        <ListBox ItemsSource="{Binding Selected.Songs}" Margin="10" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>