ボタンをクリックしてアイテムを上下に移動したい ListView (WinForms) があります。移動する項目は、チェックされている項目です。アイテム 2、6、9 が選択されている場合、上に移動するボタンを押すと 1、5、8 になり、それらの場所にあったアイテムが 1 ステップ下に移動します。
以下に示すように、これを不必要に複雑にしたと感じています。各 ListViewItem の 2 番目の SubItem は、リスト内の位置を表す番号です (1 から始まります)。
次のコードは睡眠不足とコーヒー不足のせいですが、このタスクを完了するためのより簡単な方法を見つけていただければ幸いです。
private void sourceMoveUpButton_Click(object sender, EventArgs e)
{
List<Int32> affectedNumbers = new List<Int32>();
bool foundNonChecked = false;
List<KeyValuePair<int, ListViewItem>> newList = new List<KeyValuePair<int, ListViewItem>>();
foreach (ListViewItem item in this.sourceListView.CheckedItems)
{
int newNum = int.Parse(item.SubItems[1].Text) - 1;
if (newNum >= 1)
{
foreach (ListViewItem testItem in this.sourceListView.Items)
{
if (int.Parse(testItem.SubItems[1].Text) == newNum && !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) && !item.Checked)
{
item.SubItems[1].Text = (num + affectedNumbers.Count).ToString();
}
newList.Add(new KeyValuePair<int, ListViewItem>(int.Parse(item.SubItems[1].Text), item));
item.Remove();
}
newList.Sort((firstPair, secondPair) =>
{
return firstPair.Key.CompareTo(secondPair.Key);
}
);
foreach (KeyValuePair<int, ListViewItem> pair in newList)
{
this.sourceListView.Items.Add(pair.Value);
}
}
編集 私はそれを次のように短縮しました:
foreach (ListViewItem item in this.sourceListView.CheckedItems)
{
if (item.Index > 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++;
}
しかし今、一番上の 2 つのアイテム (または同様のもの) を選択すると、上に移動するボタンをクリックすると、それらの場所が切り替わります。
2番目の編集
次のようにすると、上向きの動きに対してすべて正常に機能します。
if (this.sourceListView.CheckedItems[0].Index != 0)
{
this.sourceListView.BeginUpdate();
foreach (ListViewItem item in this.sourceListView.CheckedItems)
{
if (item.Index > 0)
{
int newIndex = item.Index - 1;
this.sourceListView.Items.RemoveAt(item.Index);
this.sourceListView.Items.Insert(newIndex, item);
}
}
this.updateListIndexText();
this.sourceListView.EndUpdate();
}
しかし、下向きの動きについては、私はそれを正しく理解できないようです:
if (this.sourceListView.CheckedItems[this.sourceListView.CheckedItems.Count - 1].Index < this.sourceListView.Items.Count - 1)
{
this.sourceListView.BeginUpdate();
foreach (ListViewItem item in this.sourceListView.CheckedItems)
{
if (item.Index < 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();
}
単一のアイテムを下に移動する場合は機能しますが、複数を選択すると機能しません。