У меня есть TPopupMenu
, где один из элементов должен (после выполнения других действий) выбрать элемент TChecklistBox
(CategoryFilter), в котором находится курсор мыши. В настоящее время я делаю это с помощью следующего кода, но он неточный, поскольку он выбирает следующий или второй следующий элемент!
var
ClickedItem: Integer;
CategoryFilter: TChecklistBox;
begin
CategoryFilter.CheckAll(cbUnchecked, FALSE, FALSE);
ClickedItem := CategoryFilter.ItemAtPos(Mouse.CursorPos.Subtract(CategoryFilter.ClientOrigin), TRUE);
if ClickedItem > -1 then
CategoryFilter.Checked[ClickedItem] := TRUE;
end;
Как это исправить и получить правильный предмет, мышь закончилась?
Я этого не сделал и теперь чувствую себя очень глупо
Хорошо, иногда это может случиться со всеми нами!
Здесь важно то, что координаты экрана мыши (x', y') в момент щелчка правой кнопкой мыши по элементу списка обычно не совпадают с координатами экрана мыши (x', y') в момент щелчка (или иного вызова ) пункт меню. Я имею в виду, что часто вы подводите мышь к пункту меню, чтобы щелкнуть по нему. Поэтому вам необходимо сохранять координаты при выключении мыши.
К счастью, VCL делает это за вас. Свойство PopupPoint всплывающего меню содержит эти координаты.
Итак, вы можете сделать
procedure TForm1.MenuItem1Click(Sender: TObject);
begin
var LIdx := CheckListBox1.ItemAtPos
(
CheckListBox1.ScreenToClient(PopupMenu1.PopupPoint),
True
);
if LIdx <> -1 then
CheckListBox1.Checked[LIdx] := True;
end;
На самом деле, я делаю это сам:
Обратите внимание: вам также следует убедиться, что щелчок правой кнопкой мыши по элементу также выбирает (а не проверяет) его. В противном случае это плохой UX.
Если вы это сделаете, вы можете в качестве бонуса просто использовать свойство ItemIndex
, чтобы найти элемент, по которому щелкнули, поэтому вам вообще не понадобится PopupPoint
:
for var i := 0 to Count - 1 do
Checked[i] := i = ItemIndex; // check only this one
(Здесь Self
— поле контрольного списка, потому что я создал свой собственный потомок поля контрольного списка со всеми этими встроенными улучшениями. Очевидно, это правильный поступок.)
Я также делаю двойной щелчок по элементу, переключаю его флажок, делаю ^A проверять все, заставляю ^C копировать выбранный элемент в буфер обмена, добавляю удобные функции для получения массива проверенных строк и/или объектов и т.д.
«Я имею в виду, что часто вы подводите указатель мыши к пункту меню, чтобы щелкнуть по нему. Поэтому вам нужно сохранять координаты во время отпускания мыши». из-за этого я чувствую себя таким глупым.... :-( Спасибо!
Я немного удивлен, что вы не осознавали, что курсор перемещается, когда вы подводите его к пункту меню, чтобы щелкнуть по нему. Или, может быть, вы это сделали, но тогда вам следовало бы включить эту информацию в свой вопрос, потому что именно в этом суть вопроса!