C# ListViewGroups工作不正常
我正在使用C和.NET3.5在Windows窗体中使用ListView控件。我有几个要添加到此ListView控件的项,我有一些功能,允许用户选择不同的方式来对列表中的项进行分组。但是,有时项目会由于无法解释的原因而转储到自动生成的默认组中 代码太大,不能放在这里,但让我解释一下我在用算法做什么。假设我们从一个包含项的ListView开始,它可能包含组,也可能不包含组 循环浏览每个项目和设置 它的组属性为null。 清空ListView的组 收集 将新组添加到ListView的 组集合。 循环浏览每个项目并设置 使用值对属性进行分组 从ListView的组中获取 通过索引收集。 我已经仔细阅读了代码,并按照它应该的样子观察了一切。对于每个项目,它从ListView的组集合中获得适当的组,并设置项目的组属性,但有时它们最终会列在默认组下C# ListViewGroups工作不正常,c#,.net,winforms,C#,.net,Winforms,我正在使用C和.NET3.5在Windows窗体中使用ListView控件。我有几个要添加到此ListView控件的项,我有一些功能,允许用户选择不同的方式来对列表中的项进行分组。但是,有时项目会由于无法解释的原因而转储到自动生成的默认组中 代码太大,不能放在这里,但让我解释一下我在用算法做什么。假设我们从一个包含项的ListView开始,它可能包含组,也可能不包含组 循环浏览每个项目和设置 它的组属性为null。 清空ListView的组 收集 将新组添加到ListView的 组集合。 循环浏
有没有其他人观察到过这一点,或者有任何理论来解释它为什么会发生?这听起来不太熟悉,我无法复制下面的内容,这是按照您的方法进行的。你能发布任何与你的团队代码更新相关的信息吗
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);
}
}
这是在多个线程上发生的吗
听起来您可能正在添加一些ListViewItems,其中的组是在清除组之前创建的 是的。。。这也发生在我身上。在添加项目之前,请尝试设置组。我的意思是,当您初始化ListViewItem时,您会将它所属的组添加到构造函数中。这种方法会奏效。是的,我见过类似的行为。我遵循的解决方案是基于代码的
这是以可预测的方式发生的吗?具体来说,给定一组特定的测试项,是否总是在默认组中转储相同的项?如果您逐步从该测试集中删除项目,那么仍然存在的项目中的相同项目在默认情况下还是不同的项目被转储?是的。一旦你得到了模式,就很容易复制。我意识到代码太大了,无法复制,但是如果行为是可复制的,你能把它带回到测试集中有两个项目,其中一个正确分组,另一个不正确分组的情况吗?如果是这样,您能否发布这两个项目,以及添加组并为每个项目设置组属性的代码?或者,你说一旦你得到了一个模式,它很容易复制——这是否意味着你已经识别了一个错误分组的模式?你能描述一下这种模式吗?当我需要改变它们的分组时,我完全可以通过转储和重新创建所有项目来避免这个问题。这让我相信,要改变已经有一个项目的组,需要某种技巧。我不太明白。我想知道你是不是给了它一个旧的团体-也许是一些时间的东西?如果没有步骤1-4的示例代码,很难说。请参阅我的回复,以了解执行相同1-4的代码,但我无法打破这些代码。
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.