Inserting items at specific index in listviews (c# .net 2.0)  
Author Message
Christian Genne





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

I'm having some problems inserting items at specific indices in listviews. ShowGroups is enabled. When running

ListViewItem c = new ListViewItem("test");
c.Group = lvStacks.Groups[0];
lvStacks.Items.Insert( 0, c );

the items just appears at the bottom of the list. Though, if i turn off the visualization of groups the order gets correct.

I'm not sure how the items in the group and the items in the listview are syncronized. For example, after running the code above, lvStacks.Items contains the item c at the correct index 0, but lvStacks.Groups[0].Items contains the item c at the end of the list. Also, i can't use lvStacks.Groups[0].Items.Insert( 0, c ) because then it will never be added to lvStacks.Items and thus not drawn to the screen.

How do i solv this problem

/Christian


Windows Forms30  
 
 
Peter Ritchie





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

You could try using Insert with ListView.Groups[x].Items to insert it at a specific position in that array before adding the item to the ListView.Items property--then not set c.Group.

Let us know if that works.



 
 
Christian Genne





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

The lists (ListView.Items and ListView.Groups[x].Items) got updated in the correct order, but they still appear in the wrong order when drawn to the screen. Seems like the group items always are drawn in the order they are inserted into the list, independent on the requested position. Any ideas

/Christian

 
 
Peter Ritchie





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

It appears there's a bug there. If, in the Designer, I add a ListView with two groups and and three items to a group in a specific order those items remain in that order regardless of their text. If I go and try and reorder then in the Items collection with the designer, it just ignores me.

If I then enable sorting, the items are sorted by text in each group and I can unable to change their order in the Items collection in the designer. If I then toggle the Sorting flag they seem to back to their original order and cannot manually reorder them.

There must be some sort of ordering occurring when Sorting is set to None.



 
 
Peter Ritchie





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

I'm unable to figure out what sort of sorting occurs when the Sorting flag is disabled.  But, a known sorting can be obtained by setting the ListViewComparer property.  I whipped together a little class to handle the four basic sort types: none, by index, by text ascending, by text descending:


/// <summary>
/// A class to
/// </summary>
/// <example>
/// form1_Load(object sender, EventArgs e)
/// {
///  listView1.ListViewItemSorter =
///   new ListViewItemComparer(
///    ListViewItemComparer.SortType.TextAscending);
/// }
/// </example>
/// <licence>May freely be used if author note is retained.</licence>
/// <revision author="Peter Ritchie" date="21-Jun-2006">Initial version.</revision>
class ListViewItemComparer : IComparer
{
 public enum SortType
 {
  None = 0,
  Index = 1,
  TextAscending = 2,
  TextDescending = 3
 };
 private SortType sortType;

 public ListViewItemComparer(SortType sortType)
 {
  this.sortType = sortType;
 }

 public int Compare(object x, object y)
 {
  ListViewItem itemLeft = x as ListViewItem;
  ListviewItem itemRight = y as ListViewItem;
  Debug.Assert(itemLeft != null && itemRight != null);
  Debug.Assert(itemLeft.ListView == itemRight.ListView);
  ListView listView = itemLeft.ListView;
  if (listView != null && itemLeft != null && itemRight != null)
  {
   switch (sortType)
   {
    case SortType.Index:
     return listView.Items.IndexOf(itemLeft) - listView.Items.IndexOf(itemRight);
    case SortType.TextAscending:
     return String.Compare(itemLeft.Text, itemRight.Text);
    case SortType.TextDescending:
     return String.Compare(itemRight.Text, itemLeft.Text);
    default:
     return 0; // equal
   }
  }
 }
}

 
See the XML comment tags for an example.  This class is immutable, so if you want to change sorting you'll have to create a new object and force the ListView to re-sort by calling ListView.Sort().

Let me know if that works around the problem.



 
 
Christian Genne





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

Hi again, and sorry for the late reply.

I tried the implementation you wrote above but couldn't get it to work. The result is as before, ListView.Items gets ordered correctly but ListView.Groups[x].Items does not. Should it work I tried to enable/disable Sorting, setting the Group property of an item before and after inserting it to the list, disabling suspend/resume layout, but nothing seems to work. Perhaps the only solution for this is to remove all items and then readd them in the correct order

/Christian

 
 
Brennon





PostPosted: Windows Forms General, Inserting items at specific index in listviews (c# .net 2.0) Top

Howdy there,

You can use either of the following to insert either an item or a group item where you want:

//Item
this.listView.Items.Insert(INDEX, ITEM);

//Groups
this.listView.Groups[0].Items.Insert(INDEX, ITEM);


Just remember to begin and end the update as well as to remove the old item.... The following is a quick little example that will move an item up in the list.... no error coding for 0 in this sample though... just a ****..



this.listView.BeginUpdate();

int CurrentIndex = this.listView.SelectedIndices[0];
int NewIndex = CurrentIndex - 1;

ListViewItem TempItem = this.listView.SelectedItems[0];

//Remove it from where it is
this.listView.Items.RemoveAt(CurrentIndex);

//Put it back in the new place
this.listView.Items.Insert(NewIndex, TempItem);

this.listView.EndUpdate();



Thats all there is too it...

Hope this helped... remember to have fun!