我在C#2008系统Windows窗体的LargeIcon视图中有一个 ListView 。 现在我想在同一个ListView中移动一个ListView项目在另一个位置 - 让我们称它为“拖放”或“项目重新排序”或其他什么。 VB 6能够做到这一点,并在任何listView中自动执行此操作。
C#似乎没有此功能,或者需要先编码。为了编码,我没有经验,我在互联网上的研究中找不到任何答案。我发现只有“覆盖程序”没有用。
我不需要任何其他ListView控件(如ObjectListView或其他),我不需要覆盖过程或制作新的ListView控件。我想在Microsoft提供的ListView控件中处理它。对此有任何想法。我相信代码会受到高度赞赏 我不能自己做,除非它是一个非常简单的单行。
PS:如果需要移动项目,我需要移动项目的所有属性(text,tag,imagekey,background-color,foreground-color,name,tooltiptext等)。我不知道如何实现这一目标。 我发现了一个提示:存在删除项目(称为 .Remove ())并插入名为 .Insert ()的项目。但是有了这些信息,我仍然无法通过鼠标“移动”物品。 我认为listView的所有 DragEvents 都在这里发挥作用,但我不知道如何使用它们以及如何将所选项目( listView1.SelectedItems )复制到右侧首先获得这个职位的位置和需要。
答案 0 :(得分: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;
}
注意:正如您所看到的,如果您想要listView1.AutoArrange
而不是更改reorder
位置,我会在其中添加2个已注释的代码行ListViewItem
可以取消注释这些行。我可以在这里注意到一些闪烁(当你处理winforms ListView时这是正常的),所以你应该使用这段代码(可以放在表单构造函数中)来启用DoubleBuffered
:
typeof(Control).GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.SetValue(listView1, true, null);
答案 1 :(得分:1)
我们可以使用以下代码来获取按位置排序的项目
type=submit
答案 2 :(得分:1)
在 this article 或相同的 here 中有拖放重新排序的工作示例。提供的代码也支持插入标记。下面是文章中的代码:
using System;
using System.Drawing;
using System.Windows.Forms;
public class ListViewInsertionMarkExample : Form
{
private ListView myListView;
public ListViewInsertionMarkExample()
{
// Initialize myListView.
myListView = new ListView();
myListView.Dock = DockStyle.Fill;
myListView.View = View.LargeIcon;
myListView.MultiSelect = false;
myListView.ListViewItemSorter = new ListViewIndexComparer();
// Initialize the insertion mark.
myListView.InsertionMark.Color = Color.Green;
// Add items to myListView.
myListView.Items.Add("zero");
myListView.Items.Add("one");
myListView.Items.Add("two");
myListView.Items.Add("three");
myListView.Items.Add("four");
myListView.Items.Add("five");
// Initialize the drag-and-drop operation when running
// under Windows XP or a later operating system.
if (OSFeature.Feature.IsPresent(OSFeature.Themes))
{
myListView.AllowDrop = true;
myListView.ItemDrag += new ItemDragEventHandler(myListView_ItemDrag);
myListView.DragEnter += new DragEventHandler(myListView_DragEnter);
myListView.DragOver += new DragEventHandler(myListView_DragOver);
myListView.DragLeave += new EventHandler(myListView_DragLeave);
myListView.DragDrop += new DragEventHandler(myListView_DragDrop);
}
// Initialize the form.
this.Text = "ListView Insertion Mark Example";
this.Controls.Add(myListView);
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new ListViewInsertionMarkExample());
}
// Starts the drag-and-drop operation when an item is dragged.
private void myListView_ItemDrag(object sender, ItemDragEventArgs e)
{
myListView.DoDragDrop(e.Item, DragDropEffects.Move);
}
// Sets the target drop effect.
private void myListView_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
}
// Moves the insertion mark as the item is dragged.
private void myListView_DragOver(object sender, DragEventArgs e)
{
// Retrieve the client coordinates of the mouse pointer.
Point targetPoint =
myListView.PointToClient(new Point(e.X, e.Y));
// Retrieve the index of the item closest to the mouse pointer.
int targetIndex = myListView.InsertionMark.NearestIndex(targetPoint);
// Confirm that the mouse pointer is not over the dragged item.
if (targetIndex > -1)
{
// Determine whether the mouse pointer is to the left or
// the right of the midpoint of the closest item and set
// the InsertionMark.AppearsAfterItem property accordingly.
Rectangle itemBounds = myListView.GetItemRect(targetIndex);
if ( targetPoint.X > itemBounds.Left + (itemBounds.Width / 2) )
{
myListView.InsertionMark.AppearsAfterItem = true;
}
else
{
myListView.InsertionMark.AppearsAfterItem = false;
}
}
// Set the location of the insertion mark. If the mouse is
// over the dragged item, the targetIndex value is -1 and
// the insertion mark disappears.
myListView.InsertionMark.Index = targetIndex;
}
// Removes the insertion mark when the mouse leaves the control.
private void myListView_DragLeave(object sender, EventArgs e)
{
myListView.InsertionMark.Index = -1;
}
// Moves the item to the location of the insertion mark.
private void myListView_DragDrop(object sender, DragEventArgs e)
{
// Retrieve the index of the insertion mark;
int targetIndex = myListView.InsertionMark.Index;
// If the insertion mark is not visible, exit the method.
if (targetIndex == -1)
{
return;
}
// If the insertion mark is to the right of the item with
// the corresponding index, increment the target index.
if (myListView.InsertionMark.AppearsAfterItem)
{
targetIndex++;
}
// Retrieve the dragged item.
ListViewItem draggedItem =
(ListViewItem)e.Data.GetData(typeof(ListViewItem));
// Insert a copy of the dragged item at the target index.
// A copy must be inserted before the original item is removed
// to preserve item index values.
myListView.Items.Insert(
targetIndex, (ListViewItem)draggedItem.Clone());
// Remove the original copy of the dragged item.
myListView.Items.Remove(draggedItem);
}
// Sorts ListViewItem objects by index.
private class ListViewIndexComparer : System.Collections.IComparer
{
public int Compare(object x, object y)
{
return ((ListViewItem)x).Index - ((ListViewItem)y).Index;
}
}
}
注意添加 myListView.ListViewItemSorter = new ListViewIndexComparer();
的位置,我遇到了大列表的性能问题。为了解决这个问题,在添加 ListView 项后添加 Comparer。