C# 我有一个WPF列表视图,我想根据复选框的值显示重复的值或不重复的值

C# 我有一个WPF列表视图,我想根据复选框的值显示重复的值或不重复的值,c#,wpf,linq,listview,C#,Wpf,Linq,Listview,我想要的只是像Linq Distinct这样的东西,根据复选框的状态,可以显示重复项,也可以不显示重复项 这是XAML(删除了所有属性,如名称,以及与布局相关的所有内容,以避免分心): 存储uriStrCollection不是一个好的解决方案,因为它太大了,基本上需要将相同的数据存储两次 再次生成uriStrCollection是一个更糟糕的想法,因为这个过程需要更多的内存和计算 我尝试在ListView.Items和ListView.Items.SourceCollection上使用Linq扩

我想要的只是像Linq Distinct这样的东西,根据复选框的状态,可以显示重复项,也可以不显示重复项

这是XAML(删除了所有属性,如名称,以及与布局相关的所有内容,以避免分心):

存储uriStrCollection不是一个好的解决方案,因为它太大了,基本上需要将相同的数据存储两次

再次生成uriStrCollection是一个更糟糕的想法,因为这个过程需要更多的内存和计算

我尝试在ListView.Items和ListView.Items.SourceCollection上使用Linq扩展方法,但我做不到:Linq方法甚至不会在自动完成上显示,这对我来说非常奇怪,特别是因为SourceCollection的编译时类型是IEnumerable


有什么想法吗?

既然您正在使用WPF,让我们从WPF的方式开始——将数据与UI分离;UI应用于显示数据,而不是存储数据

暂时忘记UI。首先,创建您需要的类和数据结构,以在代码中存储URI及其出现的列表,例如:

public class UriWithOccurrence
{
    public string UriString { get; set; }
    public int Occurrences { get; set; }
}

...

//Keep a global collection of URIs:
_allUris = new List<UriWithOccurrence>();

foreach (string uriStr in uriStrCollection)
{
    var item = new UriWithOccurrence()
               {
                   UriString = uriStr,
                   Occurrences = uriStrCollection.Count(s => (s == uriStr))
               };

    _allUris.Add(item);
}
为了连接点并查看一些URI,我们将ListView的
ItemsSource
设置为我们的URI集合:

_list.ItemsSource = _allUris;
本文将更深入地解释这一切:

要获取可点击的URI,此MSDN问题可能会有所帮助:

最后,要使“组重复项”复选框正常工作,一个快速而肮脏的解决方案可以是:

private void CheckBox_Checked(object sender, EventArgs e)
{
    _list.ItemsSource = _allUris;
}

private void CheckBox_UnChecked(object sender, EventArgs e)
{
    _list.ItemsSource = _allUris.GroupBy(u => u.UriString)
                                .Select(gr => gr.First());
}
最后一个提示:


要以WPF的方式真正做到这一点,请阅读MVVM模式,并将大部分代码放在
ViewModel中

使用Hashset而不是ListView。我希望能够在窗口上显示这一点。据我所知,Hashset不是一个控件。此外,我想保留订单和副本。我只是希望能够在显示重复项和不显示重复项之间进行选择。确切地说,哈希集不是UI控件。使用集合作为集合,使用UI控件作为UI。可以将项目同时添加到列表和哈希集,或者使用GroupBy将linq用于distinct from List。哈希集是数据集合。要创建唯一的集合,请使用itemssource将其绑定到所需的集合。也是的,您可以在列表中使用distinct()。@BARM然后我会将列表绑定到Listview,对吗?但是我该怎么做呢?我不想获取列表中对象的属性。我想要这些东西本身。有一个绑定表达式吗?谢谢,它解决了这个问题。我想我只是想避开WPF的方式。我不愿意仅仅为此创建一个新类型和一个单独的列表,例如,希望我可以使用内置的Listview。我喜欢简短的解决方案,但我想这并不总是可能的,有时我们必须向代码中添加更多的内容,不仅是为了让它工作,而且是为了让其他人更容易理解它。再次感谢。是的,这需要一种不同的心态。但是一旦你的项目增长了一点点,我发现它实际上减少了所需的代码量。正如你所指出的那样,它更容易理解。
<ListView x:Name="_list" >
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Link" DisplayMemberBinding="{Binding UriString}" />
            <GridViewColumn Header="#" DisplayMemberBinding="{Binding Occurrences}" />
        </GridView>
    </ListView.View>
</ListView>
_list.ItemsSource = _allUris;
private void CheckBox_Checked(object sender, EventArgs e)
{
    _list.ItemsSource = _allUris;
}

private void CheckBox_UnChecked(object sender, EventArgs e)
{
    _list.ItemsSource = _allUris.GroupBy(u => u.UriString)
                                .Select(gr => gr.First());
}