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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41317363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:58:22  来源:igfitidea点击:

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

c#wpflistviewcheckbox

提问by A T

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:

我目前正在用 C# WPF 创建 MP3 播放器。我的 MP3 播放器侧面有一个 ListView,它显示完整的当前播放列表,允许用户选择歌曲,或让 MP3 播放器滚动浏览歌曲。我目前正在尝试实现以下功能:

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.

由于歌曲是从 openFileDialog 加载的,我找不到以编程方式将 CheckBoxes 添加到 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.

此外,我曾尝试使用 Wpf Extended Toolkit 的 CheckListBox 控件,但是这并不合适,因为该控件的许多事件和/或属性与 ListView 的不同,导致该程序的某些功能无法使用,例如作为“还原歌曲更改”(将上一首歌曲播放到用户更改它的时间)或加载与程序关闭时相同歌曲的功能。

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.

谢谢您的帮助。

回答by A T

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

你好!正如我在帖子的评论中所说,我实际上找到了解决方案,这要感谢Rufo 爵士给我提供的有关项目模板的信息,以及KettuJKL的回答。

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

对于任何通过这篇文章寻找相同答案的人:

In order to create a ListViewwith CheckBoxes, TextBlocksand whatnot in C# WPF, there's a few simplesteps that you have to (could?) take:

为了在C# WPF 中创建一个带有CheckBoxesTextBlocks和诸如此类的ListView,您必须(可以?)采取一些简单的步骤:

Firstly,create a classin your .cs filewith propertiesthat get/seteach of the controls' valuesthat your ListView needs. An example of this usage as in my Media Player is shown below:

首先,创建一个在你的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
 }

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

其次,使用 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>

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:

最后(也是最后),不是直接向 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.

}

And finished!

并完成了!

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

这就是创建一个 ListView 所需的全部内容,其中的列代表不同的值并持有不同的控件。

回答by KettuJKL

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

StackOverflow 中存在多个解决 ListView CheckBoxes 的问题。看看其中的一些

Plain example can be found from the MSDN.

可以从 MSDN找到简单的示例。

In short:

简而言之:

  1. You need DataTemplate containing the checkbox.
  2. You need to bind that checkbox to a property to manipulate its value.
  1. 您需要包含复选框的 DataTemplate。
  2. 您需要将该复选框绑定到一个属性以操作其值。

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

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