Как я могу предотвратить выбор последнего элемента ListBox при нажатии на пустую область - PullRequest
1 голос
/ 09 марта 2011

У меня есть список, который не заполнен предметами до конца, и имеет некоторую пустую область после последнего предмета. Когда я щелкаю эту пустую область, последний элемент автоматически выбирается. И этот выбор происходит до события MouseDown. И я хочу предотвратить это.

Я могу сохранить текущий выбранный индекс (можно выбрать только один элемент) в переменной в SelectedIndexChanged и сбросить его в MouseDown, но между MouseDown и MouseUp выбран последний элемент - и он не не выглядит хорошо.

Как предотвратить выбор последнего элемента при нажатии на пустую область?


P.S. Это нарисованный владельцем ListBox, но я не уверен, что это как-то связано с этой проблемой.

private void listBox_DrawItem(object sender, DrawItemEventArgs e)
{
    if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
    {
        e.Graphics.FillRectangle(Brushes.LightSteelBlue, e.Bounds);
    }
    else
    {
        e.Graphics.FillRectangle(Brushes.White, e.Bounds);
    }

    if (_commands.Count > 0)
    {
        KeyValuePair<string, string> cmd = (KeyValuePair<string, string>)_commands[e.Index];

        // FIRST ROW
        e.Graphics.DrawString(cmd.Key, _cmdNameFont, Brushes.Black, e.Bounds.X, e.Bounds.Y + _cellPadding);

        // SECOND ROW
        e.Graphics.DrawString(cmd.Value,
            _cmdCommandFont, Brushes.Black, e.Bounds.X + 5, e.Bounds.Y + _cmdNameFont.Height + _cellPadding);
    }

    e.DrawFocusRectangle();
}

private void listBox_MeasureItem(object sender, MeasureItemEventArgs e)
{
    e.ItemHeight = _cmdNameFont.Height + _cmdCommandFont.Height + _cellPadding * 2 ;
}

Ответы [ 3 ]

1 голос
/ 14 июля 2013

У меня есть работа вокруг. Вы можете разместить панель и динамически изменять ее высоту в зависимости от высоты экрана, высоты списка. В этом случае, когда вы нажимаете пустую область, новая панель принимает щелчок.

0 голосов
/ 23 января 2018

Вы можете сделать это, проверив сообщение мыши и не позволяя ему обработать сообщение, если пользователь не нажимает на элемент:

public class ListBoxEx : ListBox {
  private const int WM_LBUTTONDOWN = 0x201;

  protected override void WndProc(ref Message m) {
    int lParam = m.LParam.ToInt32();
    int wParam = m.WParam.ToInt32();
    if (m.Msg == WM_LBUTTONDOWN) {
      Point clickedPt = new Point();
      clickedPt.X = lParam & 0x0000FFFF;
      clickedPt.Y = lParam >> 16;
      bool lineOK = false;
      for (int i = 0; i < Items.Count; i++) {
        if (GetItemRectangle(i).Contains(clickedPt)) {
          lineOK = true;
        }
      }
      if (!lineOK) {
        return;
      }        
    }
    base.WndProc(ref m);
  }
}

Опубликовал это из моего ответа на OwnerDrawVariable ListBox выбирает последний элемент при нажатии на элемент управления ниже элементов

0 голосов
/ 09 марта 2011

Убедитесь, что вы возвращаете правильное значение из OnMeasureItem.


РЕДАКТИРОВАТЬ: похоже, разница в том, как работает OwnerDrawVariable.
Обычно IndexFromPoint (тест попадания) возвращает -1, еслипустое место нажата.С OwnerDrawVariable он возвращает нижний элемент.

У вас есть два варианта.

1) Все ваши предметы имеют одинаковую высоту, поэтому вы можете использовать OwnerDrawFixed, и ваша проблема исчезнет.

base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.ItemHeight = this.Font.Height + this.Font.Height + _cellPadding * 2;

2) Удерживайте нажатой кнопку мыши на более низком уровне и выбрасывайте пустые-пространство один.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...