C# WPF - 如何在ListView中添加复选框?

4
我正在使用C# WPF创建MP3播放器。我的MP3播放器有一个ListView,显示完整的当前播放列表,允许用户选择一首歌曲,或者让MP3播放器滚动播放歌曲。我目前正在尝试实现以下功能:
在每个项目旁边加上一个复选框。当当前歌曲播放完成后,如果下一首歌曲被选中,则播放它,否则跳过。
我已经广泛搜索了适合我的答案,但似乎找到的答案都不能理解,因此无法将其实现为适合我的程序。
我甚至不知道如何实现这个功能。由于歌曲是从打开文件对话框中加载的,我找不到在ListView中编程添加复选框的方法。
此外,我曾尝试使用Wpf Extended Toolkit的CheckListBox控件,但这不适用,因为该控件的许多事件和/或属性与ListView的不同,导致某些程序功能无法使用,例如“恢复歌曲更改”(回放上一首歌曲到用户更改的时间)或在关闭程序时重新加载相同的歌曲。
如果有人能帮助我找到答案,或以简单的方式向我解释这个问题,将不胜感激。
谢谢您的帮助。

你可以使用复选框、各种花哨的装饰来设计物品展示。留意ItemTemplate。 - Sir Rufo
可能是WPF Listview Checkboxcolumn Binding的重复问题。 - Sir Rufo
非常感谢Rufo先生!我正在做一些事情,我成功地获取了复选框。如果这个方法有效,我会在未来的帖子中发布解决方案,以供其他人参考。 - A T
2个回答

11

你好!如我在帖子评论中所说,我实际上通过Sir Rufo给我的关于项目模板的建议以及KettuJKL的回答找到了解决方案。

对于任何查找相同答案的人:

为了在C# WPF中创建一个包含复选框文本块和其他控件的ListView,您需要采取几个简单的步骤:

首先,在.cs文件中创建一个,其中属性可以获取/设置每个控件的值,这些值是您的 ListView 需要的。下面以我的媒体播放器为例展示了此用法:

 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
 }

其次,使用XAML将要使用的ListView添加到您的程序中。使用以下代码创建ListView:

<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>

最后,不要直接向您的ListView中添加新条目,而是需要将每一行的值作为新条目存储到一个列表中。每当您需要更新ListView时,您都需要将该列表设置为ListView的ItemsSource。如下所示:

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.

}

完成了!

这就是你需要创建一个ListView的全部内容,它表示不同值和控件的列。


对于任何将此内容翻译为VB.NET(或可能是C#)的人来说,这是一个非常重要的提示 - 在你的类中仅仅声明"Public X As String"是不够的;你必须将其标记为属性,即"Public Property X As String"。我在这个问题上纠结了几个小时,非常沮丧,直到我开始与另一个项目进行比较,发现这就是区别所在。 - schizoid04

0

在StackOverflow中有多篇关于ListView复选框的问题。可以看一些

可以在MSDN上找到一个简单的例子

简而言之:

  1. 您需要包含复选框的DataTemplate。
  2. 您需要将该复选框绑定到属性以操纵其值。

我希望您正在使用MVVM,这将有助于绑定复选框属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接