C# 仅使列表框中的单个项无效
是否仍然只能使C# 仅使列表框中的单个项无效,c#,winforms,listbox,listboxitem,C#,Winforms,Listbox,Listboxitem,是否仍然只能使列表框中的单个项目无效?似乎没有方法获取项目的矩形,或者即使特定项目可见(除了为控件中的每个像素/至少一列中的每个像素调用IndexFromPoint) 这是针对C#WinForms(不是WPF)的 关于我正在尝试做什么的更多信息: 我有一个包含许多项目的列表框,我希望在您悬停的项目上显示一组“按钮”(例如红色的X表示删除)。我有一个很好的工作方式,除了在包含10个或更多项的列表上,每次你将鼠标悬停在一个新项上,它都会导致一个可见的重画,因为我使整个控件无效。数据没有改变,只是显示
列表框中的单个项目无效?似乎没有方法获取项目的矩形,或者即使特定项目可见(除了为控件中的每个像素/至少一列中的每个像素调用IndexFromPoint
)
这是针对C#WinForms(不是WPF)的
关于我正在尝试做什么的更多信息:
我有一个包含许多项目的列表框
,我希望在您悬停的项目上显示一组“按钮”(例如红色的X表示删除)。我有一个很好的工作方式,除了在包含10个或更多项的列表上,每次你将鼠标悬停在一个新项上,它都会导致一个可见的重画,因为我使整个控件无效。数据没有改变,只是显示改变了
编辑:更多信息和以前的尝试
我已经子类化了ListBox
,并在OnDrawItem
中执行了我的绘图,因此可以使用ListBox
的受保护方法
我尝试了以下方法,取得了不同程度的成功。变量this
是扩展的列表框
,索引
是要提取的项目,旧索引
是以前提取的项目
// 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);
可以,但您必须通过继承列表框并公开Microsoft对您隐藏的RefreshItem方法来创建自己的列表框版本:
public class ListBoxEx : ListBox
{
public new void RefreshItem(int index)
{
base.RefreshItem(index);
}
}
好吧,我很傻。多亏了@LarsTech,我决定再次查看整个ListBox
函数列表,找到了合适的一个:GetItemRectangle
,它甚至是公共的!我不知道我怎么会在最后一个小时错过这个
工作解决办法是:
if (old_index >= 0)
this.Invalidate(this.GetItemRectangle(old_index));
if (index >= 0)
this.Invalidate(this.GetItemRectangle(index));
这仍然会产生一些闪烁,但明显减少(只有在移动单个项目之前,我非常快地将鼠标移到多个项目上时才可见)。这不起作用。我相信这是因为基础数据没有更改和/或列表没有使用DisplayMember。此外,我已经从ListBox继承,因为我在DrawItem中绘制了我的图形。我会用更多的信息更新我的问题。嘿,谢谢你的回答,这对我的闪烁列表框很有帮助。我还使用了:this.SetStyle(ControlStyles.OptimizedDoubleBuffer,true);也有助于减少闪烁。