Reorder / move / dragdrop ListViewItems within the same ListView Control in C# Windows Forms

前端 未结 3 951
清歌不尽
清歌不尽 2021-01-15 04:53

I have a ListView in LargeIcon View in C# 2008 System Windows Forms. Now I would like to move an item of this ListView within the same ListView on another p

3条回答
  •  走了就别回头了
    2021-01-15 05:37

    In fact the feature you talk about is not supported by Winforms not C#. C# has nothing to do with such a feature; it's a UI technology feature not a language feature. However, to solve this, we have little code here. It supports the Position property for each ListViewItem to use for that purpose (in LargeIcon view). Another important property is AutoArrange, this should be set to false to allow the Position to take effect. Here is the code:

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

    NOTE: as you can see, I let 2 commented code lines listView1.AutoArrange there, if you want to reorder instead of changing the ListViewItem position you can uncomment those lines. I can notice some flicker here (this is normal when you deal with a winforms ListView), so you should use this code (can be placed in the form constructor) to enable DoubleBuffered:

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

提交回复
热议问题