无论如何只能使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);
答案 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);
}
}