在C#Windows窗体中的同一ListView控件中重新排序/移动/拖放ListViewItems

fee*_*all 2 c# listview drag-and-drop listviewitem winforms

在C#2008系统Windows窗体的LargeIcon视图中有一个ListView.现在我想在同一个ListView中移动一个ListView项目在另一个位置 - 让我们称它为"拖放"或"项目重新排序"或其他什么.VB 6能够做到这一点,并在任何listView中自动执行此操作.

C#似乎没有此功能,或者需要先编码.为了编码,我没有经验,我在互联网上的研究中找不到任何答案.我发现只有一个"覆盖程序"没有用.

我不需要任何其他ListView控件(如ObjectListView或其他),我不需要覆盖过程或制作新的ListView控件.我想在Microsoft提供的ListView控件中处理它.对此有任何想法.代码将受到高度赞赏我相信我不能自己做,除非它是一个非常简单的单行.

PS:如果需要移动项目,我需要移动项目的所有属性(文本,标签,图像键,背景颜色,前景色,名称,工具文本等).我不知道如何实现这一目标.我发现了一个提示:它存在删除一个项目(称为.Remove())并插入一个名为.Insert()的插入.但是有了这些信息,我仍然无法通过鼠标"移动"物品.我认为listView的所有DragEvents都在这里发挥作用,但我不知道如何使用它们以及如何将所选项目(listView1.SelectedItems)复制到正确的位置并且需要首先获得此位置.

Kin*_*ing 7

事实上,Winforms而不是C#不支持您所谈论的功能.C#与这样的功能无关; 它是一种UI技术功能,而不是语言功能.但是,要解决这个问题,我们这里的代码很少.它支持Position每个ListViewItem用于此目的的属性(在LargeIcon视图中).另一个重要的属性是AutoArrange,应该设置false为允许Position生效.这是代码:

ListViewItem heldDownItem;
Point heldDownPoint;
//MouseDown event handler for your listView1
private void listView1_MouseDown(object sender, MouseEventArgs e)
{            
    //listView1.AutoArrange = false;
    heldDownItem = listView1.GetItemAt(e.X,e.Y);
    if (heldDownItem != null) {
      heldDownPoint = new Point(e.X - heldDownItem.Position.X, 
                                e.Y - heldDownItem.Position.Y);
    }
}
//MouseMove event handler for your listView1
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
    if (heldDownItem != null){
        heldDownItem.Position = new Point(e.Location.X - heldDownPoint.X, 
                                          e.Location.Y - heldDownPoint.Y);
    }
}
//MouseUp event handler for your listView1
private void listView1_MouseUp(object sender, MouseEventArgs e)
{
    heldDownItem = null;
    //listView1.AutoArrange = true;         
}
Run Code Online (Sandbox Code Playgroud)

注意:正如您所看到的,我listView1.AutoArrange在那里放了2个注释的代码行,如果您想要reorder而不是更改ListViewItem位置,您可以取消注释这些行.我在这里可以注意到一些闪烁(当你处理winforms ListView时这是正常的),所以你应该使用这个代码(可以放在表单构造函数中)来启用DoubleBuffered:

typeof(Control).GetProperty("DoubleBuffered", 
                             System.Reflection.BindingFlags.NonPublic |
                             System.Reflection.BindingFlags.Instance)
               .SetValue(listView1, true, null);
Run Code Online (Sandbox Code Playgroud)