我想要的只是类似于 Linq Distinct 的东西,可用于显示或不显示重复项,具体取决于复选框的状态。
这是 XAML(删除了名称等所有属性,以及与布局相关的所有内容,以避免分散注意力):
<ScrollViewer>
<ListView SelectionMode="Single"/>
</ScrollViewer>
<CheckBox Content="group duplicates" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
我的 ListView 中的每个项目都是一个带有超链接的标签,因为它的内容会在点击时使用默认的互联网浏览器打开超链接的 NavigateUri 属性中设置的 Uri。
一些链接在应用程序运行时出现不止一次,这是相关的,因为它显示了这些 uri 的出现次数。我在构建列表时也无法去除重复项,因为它是按每个 uri 出现的时间排序的,这也是相关的。
因为人眼很难区分每个 uri,因为它们看起来很相似,所以能够做两件事会很实用:
- 在链接中注释 uri 在 ListView 中出现的次数,即使它显示重复项也是如此
- 将重复项合并为一个链接(正确注释出现的次数)
我希望达到的结果是这样的:
(显示重复项)
- uri1 (2)
- uri2 (3)
- uri1 (2)
- uri3 (1)
- uri2 (3)
- uri2 (3)
(分组重复)
- uri1 (2)
- uri2 (3)
- uri3 (1)
这就是我目前在后面的代码中填充 listvew 的方式(不显示不相关的部分以避免分散注意力)
foreach (string uriStr in uriStrCollection)
{
Uri uri = new Uri(uriStr);
Label lbl = new Label();
Hyperlink link = new Hyperlink();
link.Inlines.Add(uriStr);
link.NavigateUri = uri;
link.RequestNavigate += link_RequestNavigate;
lbl.Content = link;
listView.Items.Add(lbl);
}
存储 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);
}
现在我们开始考虑在 UI 中显示这些 URI,并创建一个可以列出 UriWithOccurrence
的 ListView
。请注意指向 UriWithOccurrence 中的属性的 DisplayMemberBinding
:
<ListView x:Name="_list" >
<ListView.View>
<GridView>
<GridViewColumn Header="Link" DisplayMemberBinding="{Binding UriString}" />
<GridViewColumn Header="#" DisplayMemberBinding="{Binding Occurrences}" />
</GridView>
</ListView.View>
</ListView>
为了连接点并查看一些 URI,我们将 ListView 的 ItemsSource
设置为我们的 URI 集合:
_list.ItemsSource = _allUris;
这篇文章更深入地解释了这一切:http://tech.pro/tutorial/742/wpf-tutorial-using-the-listview-part-1
要获得可点击的 URI,这个 MSDN 问题可能会有所帮助:WPF ListView "hyperlink url" column
最后,要使“Group duplicates”复选框起作用,一个快速但肮脏的解决方案可能是:
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
中。
关于c# - 我有一个 WPF Listview,我想根据复选框的值显示重复值或不显示重复值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22120283/