net item elementos agregar c# winforms listbox listboxitem

elementos - listbox c# selecteditem



Invalidar solo un elemento en ListBox (2)

¿Hay alguna forma de invalidar un solo elemento en un ListBox ? Parece que no hay un método para obtener el rectángulo de un elemento, o incluso si un elemento específico es visible (aparte de llamar a IndexFromPoint para cada píxel en el control / al menos cada píxel en una columna).

Esto es para C # WinForms (no para WPF).

Más información sobre lo que estoy tratando de hacer:

Tengo un ListBox con muchos elementos, y quiero que aparezca un conjunto de "botones" en los elementos sobre los que pasas el cursor (como una X roja para eliminar). Lo estoy haciendo muy bien, excepto que en las listas con 10 o más elementos, cada vez que pasa el mouse sobre un nuevo elemento provoca un redibujado visible ya que invalido todo el control. Los datos no se cambian, solo se cambia la pantalla.

Editar: más información e intentos previos

Ya subclass ListBox y realizar mi dibujo en OnDrawItem por lo que se pueden utilizar los métodos protegidos de ListBox .

He intentado lo siguiente con distintos niveles de éxito. La variable es el ListBox extendido, el index es el elemento sobre el que se dibujará, old_index es el elemento sobre el que se dibujó anteriormente.

// 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);


De acuerdo, estaba siendo tonto. Gracias a @LarsTech, decidí revisar la lista completa de las funciones de ListBox nuevamente y encontré la apropiada: GetItemRectangle e incluso es pública! No sé cómo me perdí esto durante la última hora ...

La solución de trabajo es:

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

Lo cual todavía produce un poco de parpadeo pero significativamente menos (solo visible cuando muevo el mouse sobre muchos muy rápidamente donde antes lo movía un solo elemento).


Sí, pero debe crear su propia versión del listbox heredándolo y exponiendo el método RefreshItem que Microsoft le oculta:

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