Обновление См. раздел «Обновление» ниже, который основан на наблюдениях OP в его собственном ответе.
Минимальный проект ниже не демонстрирует поведение, которое вы описываете.
Если я щелкну любой элемент в ListView1, переменная ItemClickedCount
увеличится только на единицу, что подтверждается отображением в заголовке формы (если я дважды щелкну форму, ItemClickedCount
увеличится на 2, как и ожидалось).
Чтобы реализовать ваш переключатель, должно быть достаточно простого переключения логического значения, или вы можете просто получить состояние переключения из того, является ли ItemClickedCount
нечетным или четным.
Итак, я думаю, что описанное вами поведение должно исходить из части вашего кода, не упомянутой в вашем вопросе. Очевидно, что способ определить причину — многократно упростить вашу форму и ее код. Удачи!
procedure TForm1.BuildList;
var
LItem : TListViewItem;
ListItemText : TListItemText;
Index : Integer;
begin
ListView1.BeginUpdate;
try
ListView1.Items.Clear;
ListView1.ItemAppearanceObjects.ItemEditObjects.Text.TextVertAlign := TTextAlign.Leading;
for Index := 0 to 19 do begin
LItem := ListView1.Items.Add;
LItem.ButtonText := 'Hello';
LItem.Text := 'Row: ' + IntToStr(Index);
LItem.Height := 25;
ListItemText := TListItemText.Create(LItem);
ListItemText.PlaceOffset.X := 100;
ListItemText.PlaceOffset.Y := 25 * (Index - 1);
ListItemText.Name := 'Name' + IntToStr(Index);
end;
finally
ListView1.EndUpdate;
end;
end;
procedure TForm1.ListView1ItemClickEx(const Sender: TObject; ItemIndex: Integer;
const LocalClickPos: TPointF; const ItemObject: TListItemDrawable);
begin
Inc(ItemClickedCount);
Caption := IntToStr(ItemClickedCount);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
BuildList;
end;
Обновление Отвечая на ваш комментарий + ответ, да, я вижу, что ListView1ItemClickEx
вызывается дважды для каждого щелчка мыши. Я изучил, почему это происходит, и, похоже, это сделано преднамеренно, хотя почему так должно быть, для меня не очевидно.
Глядя на источник FMX.ListView (я делаю это в Сиэтле, поэтому ваши номера строк могут отличаться), ListView1ItemClickEx
вызывается по строке 2003 (Case Entry.Incident of ... TDelayedIncident.ClickEvent:) в процедуре TListViewBase.ProcessIncident(const Запись: TDelayedIncidentEntry);
Очевидно, чтобы вызываться дважды, таких Incidents
должно быть два на клик, поэтому я посмотрел, как эти Инциденты добавляются в любой обрабатываемый список/очередь. Затем я посмотрел на procedure TListViewBase.StartIncident(const Incident: TDelayedIncident; const Triggered: Boolean;
const TimeToWait: Single; const CustomData: NativeInt);
в строке 1949.
После каждого щелчка мыши это вызывается дважды:
В первый раз, глядя на стек вызовов, вызов исходит из procedure TListViewBase.SetNewItemIndex(const NewIndex: Integer)
в строке 4083.
Второй раз изнутри procedure TListViewBase.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single)
.
Для меня не очевидно, как избежать этого с помощью настроек свойств TListView, но это может быть. Однако есть простой обходной путь, который можно включить в обработчик ListView1ItemClickEx
:
procedure TForm1.ListView1ItemClickEx(const Sender: TObject; ItemIndex: Integer;
const LocalClickPos: TPointF; const ItemObject: TListItemDrawable);
var
LItem : TListViewITem ;
begin
Inc(ItemClickedCount);
if not Odd(ItemClickedCount) then
Exit;
Caption := IntToStr(ItemClickedCount);
LITem := ListView1.Items[ItemIndex];
LItem.Tag := LItem.Tag + 1 ;
LItem.Text := LItem.Text + ' ' + LItem.Tag.ToString + 'clicks';
end;
Мне интересно, как связать эту обработку дедупликации с классом интерпозера, который вы могли бы включить в свой исходный модуль. Если я смогу придумать чистый способ, я, возможно, добавлю его сюда позже.
person
MartynA
schedule
03.05.2020