C# 删除组时,ListView顶部会出现空白
“我的音乐播放器”在“详细信息”模式下使用ListView显示曲目,并使用ListViewGroup将相册曲目分组在一起 我创建了一个事件,当相册的ListViewGroup中键单击时,该事件将删除一个相册中的所有曲目。如果删除曲目时未向下滚动ListView,则可以正常工作。如果向下滚动ListView,相册将被删除,但在ListView顶部标题和第一组之间会出现不可单击的空白区域 第一张图片,ListView中的3个相册(向上滚动)C# 删除组时,ListView顶部会出现空白,c#,winforms,listview,listviewgroup,C#,Winforms,Listview,Listviewgroup,“我的音乐播放器”在“详细信息”模式下使用ListView显示曲目,并使用ListViewGroup将相册曲目分组在一起 我创建了一个事件,当相册的ListViewGroup中键单击时,该事件将删除一个相册中的所有曲目。如果删除曲目时未向下滚动ListView,则可以正常工作。如果向下滚动ListView,相册将被删除,但在ListView顶部标题和第一组之间会出现不可单击的空白区域 第一张图片,ListView中的3个相册(向上滚动) 第二张图片,最后一张专辑被删除,一切都很好 确定,
第二张图片,最后一张专辑被删除,一切都很好
确定,然后在删除一组项目时向下滚动ListView 第三张图片,ListView中的3个相册(向下滚动)
第四张图片,最后一张专辑被删除,顶部出现空白,如果ListView根本不显示,则显示最后一首曲目
我认为这与我的代码无关,而是ListView中的一个bug?有人注意到同样的行为吗?有什么办法可以防止这种情况发生吗
编辑:添加删除项目的代码(根据用户请求)
List delItems=new List();//正在创建要删除的项目列表
foreach(listView1.Groups中的ListViewGroup组)
{
if(Convert.ToInt32(group.Tag)==groupNumber)//所有组在标记字段中都有单独的编号
{
foreach(组中的ListViewItem项。项)
{
删除项目。添加(项目);
}
}
}
foreach(delItems中的ListViewItem)
{
项。删除();
}
EDIT2:添加了代码以检查是否单击了组
因为并没有真正的方法来处理群点击,我把它变成了丑陋的方式。但它是有效的。
首先,我在ListView中使用了MouseDown事件。然后我检查是否有用户单击的项目。若用户单击组,那个么该项为空,for循环增加i并检查现在是否可以找到该项。当最终找到该项目时,我们知道该项目属于我们单击的组。所以我们得到了items组标签,我记录了它是什么组
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
ListViewItem item;
for (int i = 0; i < 25; i++) // group height is not more that 25 pixels.
{
item = listView1.GetItemAt(e.X, e.Y + i);
if (item != null)
{
if (i > 1) // bigger than 1, because there is 1 pixel gap between listviewitems when using groups
{
if (e.Button == MouseButtons.Middle) removePlaylistGroup(Convert.ToInt32(item.Group.Tag));
}
else
{
if (e.Button == MouseButtons.Middle) removePlaylistItem(item.Index);
}
break;
}
}
}
private void listView1\u MouseDown(对象发送方,MouseEventArgs e)
{
ListViewItem项目;
对于(int i=0;i<25;i++)//组高度不超过25像素。
{
item=listView1.GetItemAt(e.X,e.Y+i);
如果(项!=null)
{
if(i>1)//大于1,因为使用组时listviewitems之间有1个像素的间距
{
如果(e.Button==MouseButtons.Middle)移除playligroup(Convert.ToInt32(item.Group.Tag));
}
其他的
{
如果(e.Button==MouseButtons.Middle)移除播放项(item.Index);
}
打破
}
}
}
之所以发生这一切,是因为从列表视图中删除项目显然会触发表单布局事件。在这里,如果表单布局发生更改,我将使用listView1.BeginUpdate()…
调整listView1的大小。不知怎么搞的,这弄乱了我的列表视图。在不同的机器上运行时,你能重现它吗?我同意您的评估,即这可能与您的代码无关,但我以前从未见过这种情况发生。是的,它发生在另一个Win7和Win8.1中。@darx:您能向我们展示删除项目的代码吗?@TaW:原始问题中添加了代码。我建议使用listView1.SuspendLayout()来构建删除循环-listView1.ResumeLayout()
pair。顺便问一句,你是如何捕捉群点击的?我知道我可以将ListView子类化并覆盖WndProc以捕获它;但是,我不知道如何识别被单击的组。。!?与挂起/恢复布局()无关。此处的诊断是缺少对ListView.EndUpdate()的调用。但实际上,不要在布局事件处理程序中调用BeginUpdate()。仅当对Items集合进行批量更改时,才应使用它。如果您有闪烁问题,请通过从ListView派生您自己的类并在构造函数中将其Double Buffered属性设置为true来修复这些问题。@TaW:我添加了代码来演示如何确定组单击。请随时询问您是否不反对我的解释:P@HansPassant:我从布局中删除了beginupdate。我通过过滤掉WM_橡皮擦BKGND消息来处理闪烁问题,所以当listview中发生某些事情时,不会一次又一次地绘制背景。工作完美。双重缓冲也被启用了。呃,我希望很快会看到你回来抱怨listview中的文本外观不好。
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
ListViewItem item;
for (int i = 0; i < 25; i++) // group height is not more that 25 pixels.
{
item = listView1.GetItemAt(e.X, e.Y + i);
if (item != null)
{
if (i > 1) // bigger than 1, because there is 1 pixel gap between listviewitems when using groups
{
if (e.Button == MouseButtons.Middle) removePlaylistGroup(Convert.ToInt32(item.Group.Tag));
}
else
{
if (e.Button == MouseButtons.Middle) removePlaylistItem(item.Index);
}
break;
}
}
}