我正在使用C#和.NET 3.5在Windows窗体中使用ListView控件。我有几个项目,我正在添加到这个ListView控件,我有适当的功能,应该允许用户选择不同的方式来分组列表中的项目。但是,有时项目会被转储到自动生成的“默认”组中,无可解释的原因。
代码太大而不能放在这里,但让我解释一下我在算法上做什么。假设我们从包含项目的ListView开始,可能已经或可能不包含组。
我已经完成了代码并观察了应有的一切。对于每个项目,它从ListView的Group集合中获取相应的组并设置项目的Group属性,但有时它们最终列在“Default”组下。
有没有其他人曾经观察到这一点,或者有任何关于它为何会发生的理论?
答案 0 :(得分:1)
听起来并不熟悉,我无法重现(见下文,按照你的方法)。您可以发布与“更新群组”代码相关的任何内容吗?
using System;
using System.Windows.Forms;
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
ListView lv;
Button btn;
Form form = new Form {
Controls = {
(lv = new ListView { Dock = DockStyle.Fill,
ShowGroups = true}),
(btn = new Button { Dock = DockStyle.Bottom,
Text = "Scramblle" })
}
};
Random rand = new Random();
for (int i = 0; i < 40; i++) {
lv.Items.Add("Item " + i);
}
btn.Click += delegate {
// 1: Cycle through every item and set it's Group
// property to null.
foreach (ListViewItem item in lv.Items) {
item.Group = null;
}
// 2: Empty the ListView's Groups collection.
lv.Groups.Clear();
// 3: Add new Groups to the ListView's Group collection.
int groupCount = rand.Next(lv.Items.Count) + 1;
for (int i = 0; i < groupCount; i++) {
lv.Groups.Add("grp" + i, "Group " + i);
}
// 4: Cycle through every item and set the Group property
// using a value obtained from the ListView's Group collection
// via index.
foreach (ListViewItem item in lv.Items) {
item.Group = lv.Groups[rand.Next(groupCount)];
}
};
Application.Run(form);
}
}
答案 1 :(得分:0)
这是在多个线程上发生的吗?
听起来你可能会在清除组之前添加一些ListViewItems和Groups。
答案 2 :(得分:0)
是的......它也发生在我身上。尝试在添加项目之前设置组。我的意思是当你初始化ListViewItem时,你将它所参与的组添加到构造函数中。这种方式会起作用。
答案 3 :(得分:0)
是的,我见过类似的行为。我遵循的解决方案基于代码here。
public partial class ListViewExtended : ListView
{
private Collection<Dictionary<string, ListViewGroup>> groupTables = new Collection<Dictionary<string,ListViewGroup>>();
public ListViewExtended()
{
InitializeComponent();
}
/// <summary>
/// Create groups for each column of the list view.
/// </summary>
public void CreateGroups()
{
CreateGroups(false);
}
/// <summary>
/// Create groups for each column of the list view.
/// </summary>
public void CreateGroups(bool reset)
{
if (OSFeature.Feature.IsPresent(OSFeature.Themes))
{
if (reset)
{
this.groupTables.Clear();
}
for (int column = 0; column < this.Columns.Count; column++)
{
Dictionary<string, ListViewGroup> groups = new Dictionary<string, ListViewGroup>();
foreach (ListViewItem item in this.Items)
{
string subItemText = item.SubItems[column].Text;
// Use the initial letter instead if it is the first column.
if (column == 0)
{
subItemText = subItemText.Substring(0, 1).ToUpperInvariant();
}
if (!groups.ContainsKey(subItemText))
{
groups.Add(subItemText, new ListViewGroup(subItemText) { Name = subItemText });
}
}
this.groupTables.Add(groups);
}
}
}
/// <summary>
/// Sets the list view to the groups created for the specified column.
/// </summary>
/// <param name="column"></param>
public void SetGroups(int column)
{
if (OSFeature.Feature.IsPresent(OSFeature.Themes))
{
try
{
this.BeginUpdate();
this.Groups.Clear();
if (column == -1)
{
this.ShowGroups = false;
}
else
{
this.ShowGroups = true;
Dictionary<string, ListViewGroup> groups = groupTables[column];
this.Groups.AddRange(groups.Values.OrderBy(g => g.Name).ToArray());
foreach (ListViewItem item in this.Items)
{
string subItemText = item.SubItems[column].Text;
// For the Title column, use only the first letter.
if (column == 0)
{
subItemText = subItemText.Substring(0, 1).ToUpperInvariant();
}
item.Group = groups[subItemText];
}
groups.Values.ForEach<ListViewGroup>(g => g.Header = String.Format(CultureInfo.CurrentUICulture, "{0} ({1})", g.Name, g.Items.Count));
}
}
finally
{
this.EndUpdate();
}
}
}
}
在实际将项目添加到列表视图的代码中,您希望执行以下操作:
this.itemsListView.Items.AddRange(items.ToArray());
this.itemsListView.CreateGroups(true);
this.itemsListView.SetGroups(0); // Group by the first column by default.