在Foobar2000中,将文件拖放到播放列表中时,ListView会显示放置轨道的位置:

我正在寻找一种实现此功能的方法。它是由图形库绘制的,还是有实现的方法在ListView上显示水平线?
发布于 2017-09-11 08:01:17
至少有一个ListView控件,有一些有限的内置支持提供的方式 property,但这只工作在图标视图,小图标视图,和平铺视图。当对项进行排序或打开组时,它无法工作,并且需要comctrl32.dll版本6(因此意味着启用了Visual的Windows或更高版本)。
如果您想要一个更通用的解决方案,您可以轻松地在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事件中绘制!
https://stackoverflow.com/questions/46147070
复制相似问题