Is there anyway to only invalidate a single item in a ListBox
? There seems to be no method of getting the rectangle of an item, or even if a specific item is visible (aside from calling IndexFromPoint
for every pixel in the control / at least every pixel in one column).
This is for C# WinForms (not WPF).
More information about what I am trying to do:
I have a ListBox
with many items in it, and I want a set of "buttons" to appear on items that you hover over (such as a red X for remove). I have this working great, except that on lists with 10 or more items, each time you hover over a new item it causes a visible redraw since I invalidate the entire control. The data is not changed, only the display is changed.
Edit: More Information and Previous Attempts
I already subclass ListBox
and perform my drawing in OnDrawItem
so protected methods of ListBox
can be used.
I have tried the following with varying levels of success. The variable this
is the extended ListBox
, index
is the item to drawn over, old_index
is the item previously being drawn over.
// 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);
Yes, but you have to create your own version of the listbox by inheriting it and exposing the RefreshItem method that Microsoft is hiding from you:
public class ListBoxEx : ListBox
{
public new void RefreshItem(int index)
{
base.RefreshItem(index);
}
}
Okay, I was being silly. Thanks to @LarsTech I decided to look over the entire list of ListBox
functions again and found the appropriate one: GetItemRectangle
and it is even public! I don't know how I missed this for the last hour...
The working solution is:
if (old_index >= 0)
this.Invalidate(this.GetItemRectangle(old_index));
if (index >= 0)
this.Invalidate(this.GetItemRectangle(index));
Which still produces a little flickering but significantly less (only visible when I mouse over many very quickly where before moving a single item caused it).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With