当我在Foobar2000中将文件拖放到播放列表中时,ListView会显示删除曲目的位置:
我正在寻找实现此功能的方法。它只是由Graphics库绘制,还是我有一些实现的方法在ListView上显示水平线?
答案 0 :(得分:4)
至少使用ListView
控件,通过InsertionMark
property提供了一些有限的内置支持,但这仅适用于图标视图,小图标视图和平铺视图。当项目被排序或打开组时,它不起作用,它需要comctrl32.dll版本6(因此意味着Windows XP或更高版本,启用了视觉样式)。
如果您想要更通用的解决方案,可以在DragOver
事件中自行绘制一条线:
为了避免闪烁,我们记得最后一个索引:
int prevItem = -1;
事件使用HitTest
来确定光标下的项目..:
private void listView1_DragOver(object sender, DragEventArgs e)
{
Point mLoc = listView1.PointToClient(Cursor.Position);
var hitt = listView1.HitTest(mLoc);
if (hitt.Item == null) return;
int idx = hitt.Item.Index;
if (idx == prevItem) return;
listView2.Refresh();
using (Graphics g = listView1.CreateGraphics())
{
Rectangle rect = listView1.GetItemRect(idx);
g.DrawLine(Pens.Red, rect.Left, rect.Top, rect.Right, rect.Top);
}
prevItem = idx;
}
如果您想使用ListBox
,代码几乎相同:
private void listBox1_DragOver(object sender, DragEventArgs e)
{
Point mLoc = listBox1.PointToClient(Cursor.Position);
int idx = listBox1.IndexFromPoint(mLoc);
if (idx < 0) return;
if (idx == prevItem) return;
listBox1.Refresh();
using (Graphics g = listBox1.CreateGraphics())
{
Rectangle rect = listBox1.GetItemRectangle(idx);
g.DrawLine(Pens.Red, rect.Left, rect.Top, rect.Right, rect.Top);
}
prevItem = idx;
}
同时执行Refresh
清除DragLeave
事件以及DragDrop
事件中的行!
请注意,这是您想要使用control.CreateGraphics
的罕见情况之一,因为绘图是非持久性的!通常,应使用e.Graphics
事件中的Paint
对象绘制所有图形!