title: Moving ListViewItems Up & Down
body: <p>I have a ListView (WinForms) in which i want to move items up and down with the click of a button. The items to be moved are the ones who are checked. So if item 2, 6 and 9 are selected, they will become 1, 5 and 8 when I press the button for movement upwards and the items that were on those places are moved down a step.</p>
  <p>I feel that I have made this unnecessarily complicated, as you can see below. The second SubItem of each ListViewItem is a number which represents its place in the list (starts on 1).</p>
  <p>I blame lack of sleep and coffee for the following code, but if you could figure out a simpler way to complete this task I would be thankful.</p>
  <pre><code>private void sourceMoveUpButton_Click(object sender, EventArgs e)
      {
          List&lt;Int32&gt; affectedNumbers = new List&lt;Int32&gt;();
          bool foundNonChecked = false;
  
          List&lt;KeyValuePair&lt;int, ListViewItem&gt;&gt; newList = new List&lt;KeyValuePair&lt;int, ListViewItem&gt;&gt;();
  
          foreach (ListViewItem item in this.sourceListView.CheckedItems)
          {
              int newNum = int.Parse(item.SubItems[1].Text) - 1;
  
              if (newNum &gt;= 1)
              {
                  foreach (ListViewItem testItem in this.sourceListView.Items)
                  {
                      if (int.Parse(testItem.SubItems[1].Text) == newNum &amp;&amp; !testItem.Checked)
                      {
                          foundNonChecked = true;
                      }
                  }
  
                  if (foundNonChecked)
                  {
                      item.SubItems[1].Text = newNum.ToString();
                      affectedNumbers.Add(newNum);
                  }
              }
          }
  
          foreach (ListViewItem item in this.sourceListView.Items)
          {
              int num = int.Parse(item.SubItems[1].Text);
  
              if (affectedNumbers.Contains(num) &amp;&amp; !item.Checked)
              {
                  item.SubItems[1].Text = (num + affectedNumbers.Count).ToString();
              }
  
              newList.Add(new KeyValuePair&lt;int, ListViewItem&gt;(int.Parse(item.SubItems[1].Text), item));
              item.Remove();
          }
  
          newList.Sort((firstPair, secondPair) =&gt;
              {
                  return firstPair.Key.CompareTo(secondPair.Key);
              }
          );
  
          foreach (KeyValuePair&lt;int, ListViewItem&gt; pair in newList)
          {
              this.sourceListView.Items.Add(pair.Value);
          }
      }
  </code></pre>
  <p><strong>EDIT</strong>
  I have shorted it down to the following:</p>
  <pre><code>foreach (ListViewItem item in this.sourceListView.CheckedItems)
          {
              if (item.Index &gt; 0)
              {
                  int newIndex = item.Index - 1;
                  this.sourceListView.Items.RemoveAt(item.Index);
                  this.sourceListView.Items.Insert(newIndex, item);
              }
          }
  
          int index = 1;
          foreach (ListViewItem item in this.sourceListView.Items)
          {
              item.SubItems[1].Text = index.ToString();
  
              index++;
          }
  </code></pre>
  <p>But now, if I select the two topmost items (or similar) they will switch place when I click the button for upwards movement.</p>
  <p><strong>SECOND EDIT</strong><br />
  Everything works fine for upwards movement with the following:</p>
  <pre><code>if (this.sourceListView.CheckedItems[0].Index != 0)
          {
              this.sourceListView.BeginUpdate();
  
              foreach (ListViewItem item in this.sourceListView.CheckedItems)
              {
                  if (item.Index &gt; 0)
                  {
                      int newIndex = item.Index - 1;
                      this.sourceListView.Items.RemoveAt(item.Index);
                      this.sourceListView.Items.Insert(newIndex, item);
                  }
              }
  
              this.updateListIndexText();
  
              this.sourceListView.EndUpdate();
          }
  </code></pre>
  <p>But for downward movement I can't seem to get it right:</p>
  <pre><code>if (this.sourceListView.CheckedItems[this.sourceListView.CheckedItems.Count - 1].Index &lt; this.sourceListView.Items.Count - 1)
          {
              this.sourceListView.BeginUpdate();
  
              foreach (ListViewItem item in this.sourceListView.CheckedItems)
              {
                  if (item.Index &lt; this.sourceListView.Items.Count - 1)
                  {
                      int newIndex = item.Index + 1;
                      this.sourceListView.Items.RemoveAt(item.Index);
                      this.sourceListView.Items.Insert(newIndex, item);
                  }
              }
  
              this.updateListIndexText();
  
              this.sourceListView.EndUpdate();
          }
  </code></pre>
  <p>It works for moving single items down, but when I select more than one, it doesn't.</p>