C# WPF - How to Have CheckBoxes in a ListView?

13,511

Solution 1

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.

Solution 2

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.

Share:
13,511

Related videos on Youtube

A T
Author by

A T

Updated on June 27, 2022

Comments

  • A T
    A T almost 2 years

    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.

  • schizoid04
    schizoid04 over 4 years
    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.