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

坚强是说给别人听的谎言 提交于 2020-01-21 09:00:06

问题


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 position - let's call it "drag-and-drop" or an "item reorder" or whatever. VB 6 is capable of this and does this automatically in any listView.

C# seems not to have this feature or it needed to be coded first. For coding this I have no experience and I have found no answer in my research in the internet. I found only an "override procedure" which didn't worked.

I do not need any other ListView Controls (like ObjectListView or whatever) and I do not need override procedures or crafting a new ListView Control. I want to handle it within the ListView control given by Microsoft as it is. Any ideas on this. Code would be highly appreciated I believe I can't do it on my own unless it's a very simple one-liner.

PS: If the item needs to be moved I need all properties of the item to be moved (text, tag, imagekey, background-color, foreground-color, name, tooltiptext etc.). I have no idea how this can be accomplished. One hint on this I found: It exists to remove an item (called .Remove()) and insert called .Insert(). But with this information I still can't make the "moving" of items done by mouse. I think that all the DragEvents of the listView play a role here, but I dunno how to use them and how to copy the selected items (listView1.SelectedItems) to the right position and need of gaining this position first.


回答1:


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



回答2:


we can use the following code to get item ordered by position

    SortedDictionary<Tuple<int, int>, string> points = new SortedDictionary<Tuple<int, int>, string>();
    string debug1 = "", debug2 = "";
    foreach (ListViewItem item in listView1.Items)
    {
        Tuple<int, int> tp = new Tuple<int,int>(item.Position.Y, item.Position.X);
        points.Add(tp, item.Text);
        debug1 += item.Text;
    }

    foreach (KeyValuePair<Tuple<int, int>, string> kvp in points)
    {
        debug2 += kvp.Value;
    }
    MessageBox.Show(debug1); //orignal order
    MessageBox.Show(debug2); //sort by position


来源:https://stackoverflow.com/questions/19405328/reorder-move-dragdrop-listviewitems-within-the-same-listview-control-in-c-sh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!