ListViewGroups не работает правильно - PullRequest
2 голосов
/ 10 мая 2009

Я работаю с элементом управления ListView в Windows Forms, используя C # и .NET 3.5. У меня есть несколько элементов, которые я добавляю в этот элемент управления ListView, и у меня есть функциональность, которая должна позволять пользователю выбирать различные способы группировки элементов в списке. Однако иногда элементы сбрасываются в автоматически сгенерированную группу «По умолчанию» без объяснимой причины.

Код слишком велик, чтобы просто поместить его здесь, но позвольте мне объяснить, что я делаю алгоритмически. Предположим, мы начинаем с ListView, который содержит элементы и может или не может уже содержать группы.

  1. Цикл каждого элемента и набор это свойство группы, равное нулю.
  2. Очистить группы ListView коллекция.
  3. Добавление новых групп в ListView Групповая коллекция.
  4. Перебирайте все элементы и устанавливайте Группировать свойство, используя значение полученный из группы ListView сбор по индексу.

Я прошелся по коду и все наблюдал, как должно быть. С каждым элементом он получает соответствующую группу из коллекции Group в ListView и устанавливает свойство Group этого элемента, но иногда они оказываются в списке в группе «По умолчанию».

Кто-нибудь еще наблюдал это или имел какие-то теории относительно того, почему это может происходить?

Ответы [ 4 ]

1 голос
/ 10 мая 2009

Это не звучит знакомо, и я не могу воспроизвести (см. Ниже, который следует вашему подходу). Можете ли вы опубликовать что-нибудь, связанное с вашим кодом "обновить группы"?

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);
    }
}
0 голосов
/ 15 сентября 2009

Да, я видел подобное поведение. Решение, которое я использовал, основано на коде здесь .

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.
0 голосов
/ 19 июня 2009

Да ... Это тоже случилось со мной. Попробуйте установить группу, прежде чем добавить элемент. Я имею в виду, когда вы инициализируете ListViewItem, вы добавляете в конструктор группу, в которую он входит. Этот способ сработает.

0 голосов
/ 13 мая 2009

Это происходит в нескольких потоках?

Похоже, вы могли бы добавить некоторые элементы ListViewItem с группами, взятыми до того, как группы были очищены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...