问题
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