Delphi RIO 10.3.1 FMX TListView和#x27;ItemClickEx';单击一次即可触发2

Delphi RIO 10.3.1 FMX TListView和#x27;ItemClickEx';单击一次即可触发2,delphi,firemonkey,mouseclick-event,tlistview,Delphi,Firemonkey,Mouseclick Event,Tlistview,我试图在单击tlistview项目时实现“切换”功能。但是在测试时,我注意到单击事件get被触发了两次,一次单击/点击的参数相同。。 我现在正在windows上测试这个。 这是“按设计工作”吗? 我只向空表单添加了一个listview,并实现了“ItemClickEx”事件。 我找不到切换的解决方法..除了实现一个计时器,该计时器将跟踪点击并忽略第二次点击以尽快。。。 (在查看堆栈跟踪时,FMX框架似乎也适用于延迟事件) 我还测试了Onite McClick事件,这个事件只触发一次。。所以我可以

我试图在单击tlistview项目时实现“切换”功能。但是在测试时,我注意到单击事件get被触发了两次,一次单击/点击的参数相同。。 我现在正在windows上测试这个。 这是“按设计工作”吗?

我只向空表单添加了一个listview,并实现了“ItemClickEx”事件。
我找不到切换的解决方法..除了实现一个计时器,该计时器将跟踪点击并忽略第二次点击以尽快。。。 (在查看堆栈跟踪时,FMX框架似乎也适用于延迟事件)

我还测试了Onite McClick事件,这个事件只触发一次。。所以我可以用它来实现简单的变通方法。但不太好,我需要“ex”版本,最终,我需要从我的列表中添加/删除项目,根据文档,这是仅从“ex”版本推荐的项目

问候
德克

更新请参见下面的更新部分,该部分基于OP在其自己的答案中的观察结果

下面的最小项目不显示您描述的行为

如果我单击ListView1中的任何项目,
ItemClickedCount
变量只增加一个, 通过表单标题上的显示确认(如果我双击表单,
ItemClickedCount
按预期增加2)

要实现切换,只需切换布尔值就足够了,或者您可以 根据
ItemClickedCount
是奇数还是偶数派生切换状态

因此,我认为您描述的行为一定来自soe部分 你的q中没有提到的代码。显然,找出原因的方法 是迭代地简化表单及其代码。祝你好运

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行调用(案例条目.事件…TDelayedIncident.ClickEvent:) 过程TListViewBase.ProcessIncident中(const条目:tdelayedincidentry)

显然,要调用两次,每次单击必须有两个这样的
事件
,因此我接着研究了如何将这些事件添加到正在处理的任何列表/队列中。然后我看了
过程TListViewBase.StartIncident(const事件:TDelayedIncident;const触发:Boolean;
常数时间等待:单个;常数自定义数据:NativeInt);
第1949行

在每次鼠标单击后,称为两次:

  • 第一次查看调用堆栈时,调用在第4083行的
    过程TListViewBase.SetNewItemIndex(const NewIndex:Integer)
    中发起

  • 第二次是从内部
    过程TListViewBase.MouseUp(按钮: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;

我想知道如何将这个重复数据消除处理连接到一个可以包含在源单元中的插入器类中。如果我能想出一个干净的方法,我以后可能会在这里添加它。

更新请参阅下面的更新部分,该部分基于OP在自己的答案中的观察结果

下面的最小项目不显示您描述的行为

如果我单击ListView1中的任何项目,
ItemClickedCount
变量只增加一个, 通过表单标题上的显示确认(如果我双击表单,
ItemClickedCount
按预期增加2)

要实现切换,只需切换布尔值就足够了,或者您可以 根据
ItemClickedCount
是奇数还是偶数派生切换状态

因此,我认为您描述的行为一定来自soe部分 你的q中没有提到的代码。显然,找出原因的方法 是迭代地简化表单及其代码。祝你好运

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行调用(案例条目.事件…TDelayedIncident.ClickEvent:) 过程TListViewBase.ProcessIncident中(const条目:tdelayedincidentry)

显然,要调用两次,每次单击必须有两个这样的
事件
,因此我接着研究了如何将这些事件添加到正在处理的任何列表/队列中。然后我看了
过程TListViewBase.StartIncident(const事件:TDelayedIncident;const触发:Boolean;
常数时间等待:单个;常数自定义数据:NativeInt);
第1949行

在每次鼠标单击后,称为两次:

  • 第一次查看调用堆栈时,调用在第4083行的
    过程TListViewBase.SetNewItemIndex(const NewIndex:Integer)
    中发起

  • 第二次是从内部
    过程TListViewBase.MouseUp(按钮:TMouseButton;Shift:TShiftState;X,Y:Single)

我不清楚如何通过TListView的属性设置来避免这种情况,但可能是这样。但是,