gpt4 book ai didi

c# - 上下移动 ListViewItems

转载 作者:太空狗 更新时间:2023-10-29 18:15:08 26 4
gpt4 key购买 nike

我有一个 ListView (WinForms),我想通过单击按钮在其中上下移动项目。要移动的项目是已检查的项目。因此,如果选择项目 2、6 和 9,当我按下向上移动按钮时,它们将变为 1、5 和 8,并且在这些位置上的项目将向下移动一个台阶。

我觉得我已经把它变得不必要的复杂了,如下所示。每个 ListViewItem 的第二个 SubItem 是一个数字,表示它在列表中的位置(从 1 开始)。

我将以下代码归咎于缺乏 sleep 和咖啡,但如果您能想出一种更简单的方法来完成此任务,我将不胜感激。

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++;
}

但是现在,如果我选择最上面的两个项目(或类似项目),当我单击向上移动按钮时它们将切换位置。

第二次编辑
一切都适用于向上移动,如下所示:

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();
}

它适用于向下移动单个项目,但当我选择多个项目时,它不起作用。

最佳答案

尝试这样的事情:

foreach (ListViewItem lvi in sourceListView.SelectedItems)
{
if (lvi.Index > 0)
{
int index = lvi.Index - 1;
sourceListView.Items.RemoveAt(lvi.Index);
sourceListView.Items.Insert(index, lvi);
}
}

基本上只是删除项目然后将其插入到原来位置的上方。 ListView 会在插入后自动处理重新排列项目的顺序,所以不用担心。

编辑:两个最上面的项目交换的原因是最上面的项目永远不会移动(即我没有实现 wrap-around 移动。但是,第二个项目可以自由移动,因此转到名列前茅。

要解决此问题,您可以执行以下两项操作中的一项:

  1. Implement a wrap-around reshuffle (i.e top item goes to the bottom)
  2. Prevent any movement if the top item is selected (check listview.Items[0].Selected)

至于重做正文,在原来的循环里做就可以了。

环绕式实现:

foreach (ListViewItem lvi in sourceListView.SelectedItems)
{
int index = lvi.Index > 0 ? lvi.Index - 1 : sourceListView.Items.Count - 1;
sourceListView.Items.RemoveAt(lvi.Index);
sourceListView.Items.Insert(index, lvi);

if (index != sourceListView.Items.Count - 1) //not a wraparound:
{
//just swap the indices over.
sourceListView.Items[index + 1].SubItems[1].Text = (index + 1).ToString();
lvi.SubItems[1].Text = index.ToString();
}
else //item wrapped around, have to manually update all items.
{
foreach (ListViewItem lvi2 in sourceListView.Items)
lvi2.SubItems[1].Text = lvi2.Index.ToString();
}
}

编辑 2:

静态助手实现,无环绕:

private enum MoveDirection { Up = -1, Down = 1 };

private static void MoveListViewItems(ListView sender, MoveDirection direction)
{
int dir = (int)direction;
int opp = dir * -1;

bool valid = sender.SelectedItems.Count > 0 &&
((direction == MoveDirection.Down && (sender.SelectedItems[sender.SelectedItems.Count - 1].Index < sender.Items.Count - 1))
|| (direction == MoveDirection.Up && (sender.SelectedItems[0].Index > 0)));

if (valid)
{
foreach (ListViewItem item in sender.SelectedItems)
{
int index = item.Index + dir;
sender.Items.RemoveAt(item.Index);
sender.Items.Insert(index, item);

sender.Items[index + opp].SubItems[1].Text = (index + opp).ToString();
item.SubItems[1].Text = (index).ToString();
}
}
}

例子:

MoveListViewItems(sourceListView, MoveDirection.Up);
MoveListviewItems(sourceListview, MoveDirection.Down);

关于c# - 上下移动 ListViewItems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11623893/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com