仅使ListBox中的单个项无效

时间:2011-08-05 21:36:42

标签: c# winforms listbox listboxitem

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

这适用于C#WinForms(不是WPF)。

有关我要做的事情的更多信息:

我有一个ListBox,其中包含很多项目,我希望在您悬停的项目上显示一组“按钮”(例如红色X以便删除)。我有这个工作很好,除了在10个或更多项目的列表上,每次你将鼠标悬停在一个新项目上它会导致可见的重绘,因为我使整个控件无效。数据不会更改,只会更改显示。

修改:更多信息和以前的尝试

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

我尝试了以下不同程度的成功。变量this是扩展的ListBoxindex是要绘制的项目,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);

2 个答案:

答案 0 :(得分:6)

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

工作解决方案是:

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

它仍会产生一点点闪烁,但显着减少(只有当我在移动单个物品之前非常快速地鼠标移动时才能看到它)。

答案 1 :(得分:1)

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

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