ListViewGroups无法正常工作

时间:2009-05-10 04:03:37

标签: c# .net winforms

我正在使用C#和.NET 3.5在Windows窗体中使用ListView控件。我有几个项目,我正在添加到这个ListView控件,我有适当的功能,应该允许用户选择不同的方式来分组列表中的项目。但是,有时项目会被转储到自动生成的“默认”组中,无可解释的原因。

代码太大而不能放在这里,但让我解释一下我在算法上做什么。假设我们从包含项目的ListView开始,可能已经或可能不包含组。

  1. 遍历每个项目并设置 它的Group属性为null。
  2. 清空ListView的组 集合。
  3. 将新组添加到ListView中 集合。
  4. 遍历每个项目并设置 使用值的组属性 从ListView的小组获得 通过索引收集。
  5. 我已经完成了代码并观察了应有的一切。对于每个项目,它从ListView的Group集合中获取相应的组并设置项目的Group属性,但有时它们最终列在“Default”组下。

    有没有其他人曾经观察到这一点,或者有任何关于它为何会发生的理论?

4 个答案:

答案 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.