Сделать недействительным только один элемент в ListBox - PullRequest
4 голосов
/ 06 августа 2011

Есть ли способ аннулировать только один элемент в 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);

Ответы [ 2 ]

6 голосов
/ 06 августа 2011

Хорошо, я был глупым. Благодаря @LarsTech я решил снова просмотреть весь список ListBox функций и нашел подходящий: GetItemRectangle, и он даже публичный! Я не знаю, как я пропустил это за последний час ...

Рабочий раствор:

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

Который все еще производит небольшое мерцание, но значительно меньше (виден только тогда, когда я очень быстро наведу курсор мыши на множество, где перед тем, как переместить какой-либо элемент, это вызвало).

1 голос
/ 06 августа 2011

Да, но вы должны создать свою собственную версию списка, унаследовав его и предоставив метод RefreshItem, который Microsoft скрывает от вас:

public class ListBoxEx : ListBox
{
  public new void RefreshItem(int index)
  {
    base.RefreshItem(index);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...