5

I am currently creating an MP3 player in C# WPF. My MP3 player has a ListView on the side, which shows the full current playlist, allowing the user to choose a song, or let the MP3 player scroll through the songs. I am currently attempting to implement the following feature:

Having a CheckBox next to every item. When the current song is finished, if the next song IsChecked, then play it, otherwise, skip it.

I have searched extensively for an answer that suits me, however all I seem to find are answers which don't make sense to me, so I can't implement them to suit my program.

I have no idea how to even go about implementing this feature.

Since the songs are loaded from an openFileDialog, I can't find a way to programatically add CheckBoxes to every item in the ListView.

Moreover, I have attempted at using Wpf Extended Toolkit's CheckListBox control, however this wasn't suitable, as many of the events and/or properties of that control weren't the same as the ListView's, rendering some of the program's features unusable, such as the 'Revert Song Change' (plays back the previous song to the time at which the user changed it) or the feature to load the same songs as the ones when the program was closed.

If someone could lead me to an answer, or explain this to me in a simple manner, it would be greatly appreciated.

Thanks for the help.

3
  • You can design the item presentation as you like with checkboxes, bells and whistles. Look out for ItemTemplate Commented Dec 24, 2016 at 23:11
  • Possible duplicate of WPF Listview Checkboxcolumn Binding Commented Dec 24, 2016 at 23:15
  • Thanks a lot Sir Rufo! I'm onto something, I managed to get the checkboxes. If this works, I'll post a solution for anyone looking into this thread in the future. Commented Dec 24, 2016 at 23:29

2 Answers 2

11

Hello! As I said in my post's comments, I actually found the solution thanks to the lead Sir Rufo gave me about item templates, and KettuJKL's answer as well.

To anyone going through this post looking for the same answer:

In order to create a ListView with CheckBoxes, TextBlocks and whatnot in C# WPF, there's a few simple steps that you have to (could?) take:

Firstly, create a class in your .cs file with properties that get/set each of the controls' values that your ListView needs. An example of this usage as in my Media Player is shown below:

 public class Song //Class name - could be anything, so long as it suits you
 {
    public bool Favourite { get; set; } //Value for CheckBox #1 - whether it is a favourite
                                        //(true - checked) or not (false - unchecked)
    public bool Play { get; set; } //Value for CheckBox #2 - whether the song is played
                                   //when its turn is reached (true - play/false - skip)

    public string Name { get; set; } //A string value of the name of the song
 }

Secondly, add the ListView in question to your program with XAML. Create the ListView with the following code:

<ListView Grid.Row="2" HorizontalAlignment="Stretch" Name="MyListView"
Margin="5" SelectionChanged="SelectedSongChanged" Grid.RowSpan="2">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Favourite">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Margin="5, 0" IsChecked="{Binding Favourite}"/>
                                <!-- Your control type and value goes here. Bind the value
                                     to the name of the method that represents this value
                                     in your .cs file. In my case, this was 'Favourite' -->
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Play">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Margin="5, 0" IsChecked="{Binding Play}"/>
                                <!-- Repeat this for every control you need in your
                                     ListView's rows -->
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Name">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Margin="5, 0" Text="{Binding Name}"/>
                                <!-- You can add non-binded values too to each column.
                                     These values will simply be added to every row
                                     and be the same. -->
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

Lastly (and finally), instead of directly adding new entries to your ListView, you need to add items to a list that stores every row's values as a new entry. Whenever you need to update the ListView, you need to set the list as an ItemsSource to the ListView. As shown below:

private void AddSong()
{
    List<Song> playlistSongs = new List<Song>(); //Set a list that holds values of your
                                                 //class' type. If you made a class
                                                 //called 'MyClass', your list would
                                                 //be List<MyClass> instead.

    playlistSongs.Add(new Song() { Favourite = false, Play = true, Name = "Song 1");
    //Add a new song to the list of songs. Each value in the class is represented
    //as above. You can change these values to be different, or even calculated
    //depending on variables.

    MyListView.ItemsSource = playlistSongs; //Finally, set each row's values in your
                                            //ListView equivalent to each entry
                                            //in your list created earlier.

}

And finished!

That's all you need to create a ListView with columns representing different values and holding different controls.

Sign up to request clarification or add additional context in comments.

1 Comment

really important note for anyone translating this out to vb.net (or perhaps c# as well, not sure) - It's NOT ENOUGH to just declare "Public X As String" in your class; you MUST mark it as a property, i.e "Public Property X As String". Was racking my brain on this issue for a couple hours, very frustrated, until I started comparing to another project where I had this working and realized that was the difference.
1

There are multiple issues here in StackOverflow addressing ListView CheckBoxes. See some of them.

Plain example can be found from the MSDN.

In short:

  1. You need DataTemplate containing the checkbox.
  2. You need to bind that checkbox to a property to manipulate its value.

I hope you are using MVVM which would help binding checkbox properties.

Comments

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.