仅使列表框中的单个项无效

本文关键字:单个项 无效 列表 | 更新日期: 2023-09-27 18:04:44

无论如何只能使ListBox中的单个项目无效?似乎没有办法获得一个项目的矩形,甚至一个特定的项目是可见的(除了调用IndexFromPoint在控件中的每个像素/至少在一个列中的每个像素)。

这是为c# WinForms(不是WPF)。

关于我正在尝试做什么的更多信息:

我有一个ListBox与许多项目在它,我想要一组"按钮"出现在项目,你悬停(如红色X为删除)。我的工作很好,除了在有10个或更多项目的列表上,每次你把鼠标悬停在一个新项目上,它会导致一个可见的重绘,因为我使整个控件无效。数据不改变,只改变显示。

编辑:更多信息和以前的尝试

我已经子类化ListBox并在OnDrawItem中执行我的绘图,因此可以使用ListBox的保护方法。

我尝试了以下方法,取得了不同程度的成功。变量this是扩展的ListBox, index是要绘制的项,old_index是之前绘制的项。

// Causes flicker of entire list, but works
this.Invalidate();
// Causes flicker of selected item, but works
int sel_index = this.SelectedIndex;
this.SelectedIndex = old_index;
this.SelectedIndex = index;
this.SelectedIndex = sel_index;
// Does not work
if (old_index >= 0)
  this.RefreshItem(old_index);
if (index >= 0)
  this.RefreshItem(index);

仅使列表框中的单个项无效

好吧,我很傻。感谢@LarsTech,我决定再次查看ListBox函数的整个列表,并找到合适的GetItemRectangle,它甚至是公开的!我不知道我怎么错过了这个最后一个小时…

工作解决方案为:

if (old_index >= 0)
  this.Invalidate(this.GetItemRectangle(old_index));
if (index >= 0)
  this.Invalidate(this.GetItemRectangle(index));

这仍然会产生一点闪烁,但明显更少(只有当我在移动单个项目之前快速移动多个项目时才能看到)。

可以,但是您必须通过继承列表框并公开Microsoft对您隐藏的RefreshItem方法来创建您自己的列表框版本:

public class ListBoxEx : ListBox
{
  public new void RefreshItem(int index)
  {
    base.RefreshItem(index);
  }
}