点击事件被列表视图父项捕获

2023-12-29

我正在编写一个在 Firemonkey 中使用的自定义开关对象TListView每个项目的控制。除了一个奇怪的故障之外,一切都按预期进行。当用户单击其中一项而不是特定的开关对象时,它无论如何都会切换开关。我假设MouseDown当用户单击列表项时触发事件,而不一定是我在其上绘制的特定“控件”。

如何限制单击事件仅在用户单击实际开关时应用?

JD.ListView对象.pas

unit JD.ListViewObjects;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
  FMX.ListView;

type
  TLISwitchThumbStyle = (tsRect, tsRoundRect, tsElipse);

  TListItemSwitch = class(TListItemSimpleControl)
  private
    FIsChecked: Boolean;
    FOnSwitch: TNotifyEvent;
    FThumbStyle: TLISwitchThumbStyle;
    FThumbWidth: Single;
    FThumbHeight: Single;
    FThumbRound: Single;
    procedure SetIsChecked(const AValue: Boolean);
    procedure SetThumbStyle(const Value: TLISwitchThumbStyle);
    procedure SetThumbWidth(const Value: Single);
    procedure SetThumbHeight(const Value: Single);
    procedure SetThumbRound(const Value: Single);
  protected
    function MouseDown(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF): Boolean;
      override;
    procedure DoSwitch; virtual;
    procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates;
      const SubPassNo: Integer = 0); override;
  public
    constructor Create(const AOwner: TListItem); override;
    destructor Destroy; override;
  public
    property IsChecked: Boolean read FIsChecked write SetIsChecked;
    property ThumbWidth: Single read FThumbWidth write SetThumbWidth;
    property ThumbHeight: Single read FThumbHeight write SetThumbHeight;
    property ThumbStyle: TLISwitchThumbStyle read FThumbStyle write SetThumbStyle;
    property ThumbRound: Single read FThumbRound write SetThumbRound;
    property OnSwitch: TNotifyEvent read FOnSwitch write FOnSwitch;
  end;

implementation

{ TListItemSwitch }

constructor TListItemSwitch.Create(const AOwner: TListItem);
begin
  inherited;
  Width:= 50;
  Height:= 20;
  FIsChecked:= False;
  FThumbWidth:= 15;
  FThumbHeight:= 15;
  FThumbRound:= 3;
end;

destructor TListItemSwitch.Destroy;
begin

  inherited;
end;

function TListItemSwitch.MouseDown(const Button: TMouseButton;
  const Shift: TShiftState; const MousePos: TPointF): Boolean;
begin
  if (Button = TMouseButton.mbLeft) and Enabled then begin
    DoSwitch;
  end;
  inherited;
end;

procedure TListItemSwitch.DoSwitch;
begin
  FIsChecked:= not FIsChecked;
  if Assigned(OnSwitch) then
    OnSwitch(Self);
  Invalidate;
end;

procedure TListItemSwitch.SetIsChecked(const AValue: Boolean);
begin
  FIsChecked:= AValue;
  Invalidate;
end;

procedure TListItemSwitch.SetThumbWidth(const Value: Single);
begin
  FThumbWidth := Value;
  Invalidate;
end;

procedure TListItemSwitch.SetThumbHeight(const Value: Single);
begin
  FThumbHeight := Value;
  Invalidate;
end;

procedure TListItemSwitch.SetThumbRound(const Value: Single);
begin
  FThumbRound := Value;
  Invalidate;
end;

procedure TListItemSwitch.SetThumbStyle(const Value: TLISwitchThumbStyle);
begin
  FThumbStyle := Value;
  Invalidate;
end;

procedure TListItemSwitch.Render(const Canvas: TCanvas;
  const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates;
  const SubPassNo: Integer);
var
  R, R2: TRectF;
  D: Single;
begin
  inherited;
  R:= Self.LocalRect;
  R2:= R;
  Canvas.BeginScene;
  try
    Canvas.Stroke.Kind:= TBrushKind.None;
    Canvas.Fill.Kind:= TBrushKind.Solid;
    Canvas.Fill.Color:= TAlphaColorRec.Skyblue;
    Canvas.FillRect(R, FThumbRound, FThumbRound,
      [TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight],
      1.0, TCornerType.Round);
    R2.Top:= R.Top + (R.Height / 2) - (FThumbHeight / 2);
    R2.Height:= FThumbHeight;
    D:= R2.Top - R.Top;
    if IsChecked then begin
      R2.Left:= R.Right - FThumbWidth - D;
    end else begin
      R2.Left:= R.Left + D;
    end;
    R2.Width:= FThumbWidth;
    Canvas.Fill.Color:= TAlphaColorRec.Black;
    Canvas.FillRect(R2, FThumbRound, FThumbRound,
      [TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight],
      1.0, TCornerType.Round);
  finally
    Canvas.EndScene;
  end;
end;
end.

uListViewSwitchTest.pas

unit uListViewSwitchTest;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
  FMX.ListView, FMX.Controls.Presentation, FMX.StdCtrls,
  JD.ListViewObjects;

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure ListView1UpdateObjects(const Sender: TObject;
      const AItem: TListViewItem);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
var
  X: Integer;
  function A: TListViewItem;
  begin
    Result:= ListView1.Items.Add;
  end;
begin
  ListView1.Align:= TAlignLayout.Client;
  for X := 1 to 50 do
    A;
end;

procedure TForm1.ListView1UpdateObjects(const Sender: TObject;
  const AItem: TListViewItem);
var
  S: TListItemSwitch;
begin
  S:= AItem.Objects.FindObject('Switch') as TListItemSwitch;
  if S = nil then begin
    S:= TListItemSwitch.Create(AItem);
    S.Name:= 'Switch';
    S.Align:= TListItemAlign.Trailing;
    S.VertAlign:= TListItemAlign.Center;
  end;
end;

end.

它应该看起来像这样:


你的有错误MouseDown方法。它应该看起来像这样:

function TListItemSwitch.MouseDown(const Button: TMouseButton;
  const Shift: TShiftState; const MousePos: TPointF): Boolean;
begin
  Result := inherited;
  if Result then begin
    DoSwitch;
  end;
end;

当用户点击ListItem它遍历所有可见的子控件,调用它们的MouseDown方法来查看哪一个被按下。如果MouseDown方法返回true这意味着按下了特定的子控件。在你的情况下,逻辑是在TListItemSimpleControl你从中继承的。

你在做DoSwitch所有人的逻辑MouseDown即使鼠标未在控件范围内按下,也会发生事件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

点击事件被列表视图父项捕获 的相关文章

  • 如何在Delphi XE中通过名称获取类类型引用?

    我实际上正在尝试使用 Rtti 来实现通用方法调用程序 它应该像这样工作 我将提供类名 方法名和参数 调用者将通过调用此类的指定方法来完成其工作 因此 我需要类引用才能获取其 Rtti 信息并寻找我想要调用的方法 有没有办法在不实现我想要使
  • 获取 TransactSql 批处理中的语句数计数

    对于不使用 Delphi 的读者 虽然以下内容是根据 Delphi 编码来表达的 但我的实际技术问题不是特定于 Delphi 的 而是关于如何找出 Sql Server 如何 理解 TransactSql 批处理提交给它 TAdoQuery
  • 如何仅在调试模式下激活 ReportMemoryLeaksOnShutdown?

    我需要激活ReportMemoryLeaksOnShutdown报告应用程序内存泄漏的功能 但仅限于调试模式 当 Delphi IDE 运行时 我怎样才能做到这一点 如果您的意思是使用调试构建配置 D2007 编译的 调试模式 则您将定义
  • Delphi线程死锁

    我有时会在销毁某些线程时遇到死锁问题 我尝试过调试该问题 但在 IDE 中调试时似乎从未存在死锁 可能是因为 IDE 中的事件速度较低 问题 当应用程序启动时 主线程会创建多个线程 线程始终处于活动状态并与主线程同步 完全没有问题 当应用程
  • Delphi TImageList 位图更改

    我正在使用 Delphi XE2 Update 3 Update 4 与我们的一些第 3 方组件不兼容 因此我们尚未更新 我在我的应用程序中使用 TImageList 我注意到很多时候当它从源视图切换到表单视图 F12 时 突然之前未修改的
  • delphi 变量值在循环中的线程中发生变化

    我的代码正在运行一个 for 循环来处理一些数据 如下所示 procedure printValue Value Integer begin TThread Synchronize TThread Current procedure beg
  • Firemonkey 编辑/组合自动完成/打字时自动建议

    实施方式是什么Autocomplete or Autosuggest适用于 Windows Android 平台以及 MacOS 和 iOS 的 Delphi Firemonkey Example 当用户在 Google 搜索框中输入文本时
  • 当显示对话框时淡出应用程序的所有其他窗口?

    如何在 Delphi 2009 中调暗 淡出应用程序的所有其他窗口 Form 有一个 AlphaBlend 属性 但它仅控制透明度级别 但如果我们能有这样的东西那就太好了 集中窗口 http www anappaday com downlo
  • Async InputQuery 不处理“取消”按钮

    我正在使用一个简单的调用TDialogServiceAsync InputQuery 使用单个输入 它只是忽略了Cancel按钮和窗口的X关闭按钮 But the Ok按钮工作正常 这是我的代码 uses FMX DialogService
  • 德尔福数据结构

    我可能需要在 Delphi 中做一个项目 并且是该领域的初学者 目前 我正在网上搜索资源 但由于资源站点太少而感到困惑 首先 你能给我一些好的网站 其中包含我迄今为止错过的 Delphi 资源吗 我也在 Delphi 中搜索数据结构 想知道
  • 如何在Delphi中下载一个非常简单的HTTPS页面?

    我尝试了在这里看到的代码 但它不适用于 HTTPS 我需要将此页面作为字符串下载 并在其上添加一些换行符 以便将信息按顺序放入 TMemo 中 怎么做 我尝试使用 Indy 但由于 SSL 问题而失败 我尝试了此页面的解决方案 如何将网页下
  • Delphi 返回 TList 时出错

    我做了一个非常简单的应用程序 但我有一个我真的无法理解的问题 看一下这个基本代码 unit Unit1 interface uses Winapi Windows Winapi Messages System SysUtils System
  • delphi中如何实现多重继承?

    我正在对一个旧库进行完全重写 我不确定如何处理这种情况 为了便于理解 大家都欢呼自行车类比 我有以下课程 TBike 自行车本身 TBikeWheel 自行车的一个轮子 TBikeWheelFront and TBikeWheelBack
  • 将数据从一个数据集结构移动到另一个数据集结构的更快方法(在 TDatasetProvider 中)

    我有一个自定义的 TDatasetProvider 它允许为其提供的任何数据创建新字段 因此 假设您在原始数据集上获得了以下字段 客户ID Name Age 您需要使用显示位图在 DBGrid 上选择它 好吧 你可以 因为我的 DSP 可以
  • Delphi AES 库 (Rijndael) 使用 KAT Vectors 进行测试

    对于这两个库 Delphi 加密概要 v 5 2 http code google com p delphidec TurboPower 密码箱 v 2 07 http lockbox seanbdurkin id au tiki list
  • 如何从 VCL.Graphics 获取所有已注册的文件格式...但 64 位

    在我的 32 位应用程序中 我使用FindRegisteredPictureFileFormats 单元由 Cosmin Prund 提供 https stackoverflow com a 14677532 505088 gt 如何从图形
  • Delphi IDE导致CPU过热

    我正在使用 Delphi 7 但我已经尝试过 Delphi 2005 2010 版本 在所有这些新版本中 当 Delphi IDE 在屏幕上可见时 我的 CPU 利用率为 50 一个核心为 100 另一个核心为 宽松 当 IDE 最小化时
  • Mac 上的 Delphi - 可能吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我负责一个 Delphi Win32 项目管理应用程序 我刚刚完成了向 Delphi 2009 的迁移
  • Delphi - 获取和设置 ListView 的滚动条位置

    这似乎是一个愚蠢而简单的问题 然而 我一直无法找到令人满意的答案 基本上 我有一个列表视图 样式 vsReport 与数据 有时 我必须更新它 因此 我必须清除列表视图并用更新的数据再次填充它 但是 当我这样做时 滚动条位置将重置为 0 我
  • 读取存储在注册表中的 GUID 值

    我尝试读取存储为的 GUID 值binaryDelphi 注册表中的值 当我用BintoHex读取它时 但结果是相反的 看来我必须交换字节 但我认为 BinToHex 可以做到 我参考了这个线程 但找不到正确的解决方案 如何在 Delphi

随机推荐

  • JTable 单元格闪烁

    我正在使用 Java 中的 Swing 库编写一个应用程序 我有一个扩展的表格组件JTable 在这个组件中我重写了该方法getTableCellRendererComponent 因为我为表格的单元格着色 我有一个自定义表模型 从默认表模
  • 截击超时错误

    我正在尝试使用 Volley 拨打休息服务 public class AuthFunctions private static final String LOGIN URL http 10 0 2 2 8080 stewayservices
  • 如何防止PDF页面大小调整?

    我想要一个 pdf 文件 其中实际尺寸与打印时适合页面的尺寸之间没有差异 我尝试使用以下示例 但不起作用 仅锁定宽度 而不锁定高度 有什么解决办法吗 package etiq import java io FileOutputStream
  • Pip 在 AWS Lambda 中安装 Python 包?

    我正在尝试在 AWS Lambda 函数中 pip install 包 Amazon 推荐的方法是创建一个压缩的部署包 其中包含依赖项和 python 函数 如Python 中的 AWS Lambda 部署包 https docs aws
  • 调试 IE 崩溃

    我有一个 Web 应用程序在 Chrome 和 FireFox 中运行良好 但在 IE 中崩溃 请注意 这不是 JavaScript 错误 而是 iexplore exe 进程实际上崩溃了 代码发布在下面 这将在 IE9 中崩溃 当单击该按
  • Angular 1.6.0:“可能未处理的拒绝”错误[重复]

    这个问题在这里已经有答案了 我们在 Angular 应用程序中有一个解决承诺的模式 该模式在 Angular 1 6 0 之前一直为我们提供良好服务 resource get promise then function response d
  • Laravel sainttum 更改 csrf cookie 路由

    我怎样才能将 laravel sainttum csrf cookie 路由更改为 api sanctum csrf cookie 我尝试将其添加到 api php 路由中 use Laravel Sanctum Http Controll
  • 使用 Java 中的 Lambda 函数进行 AWS S3 事件通知

    我正在尝试使用 Lambda 函数进行 S3 Put 事件通知 当我在 S3 存储桶中放置 添加任何新的 JSON 文件时 应该调用我的 Lambda 函数 我面临的挑战是没有足够的文档来用 Java 实现这样的 Lambda 函数 我找到
  • Angular 2 - 获取 Observable 中已更改的 FormControl 的值

    我有一个简单的表单FormBuilder this contactForm formBuilder group name email phone 我想观察每个控件的更改 并在发生这种情况时使用更新后的值运行函数 getContacts va
  • 如何在 Visual Studio 2010 中添加 ASP.NET MVC 3 Web 应用程序?

    我的VS 2010如下 微软视觉工作室 2010 版本 10 0 30319 1 RTMRel Microsoft NET Framework 版本 4 0 30319 RTMRel 安装版本 旗舰版 ASP NET MVC 3 Web 应
  • 如何从 IntelliJ IDEA 内部重命名本地 Git 分支?

    您可以使用 IntelliJ IDEA 的 Git 插件做很多事情 但我还没有找到重命名分支的方法 有吗 我知道我总是可以打开终端并执行git branch m source target 但我也希望找到一个 GUI 解决方案 此功能有几个
  • Spring Boot计划任务不适用于docker容器

    我的 Spring Boot 项目在 docker 容器上运行时遇到问题 如果我以恶魔化方式运行容器 docker run d 当我在后台运行非图像时 一切正常 不幸的是 我必须将其作为妖魔化来运行 并且我不知道如何解决该问题 感谢您提供任
  • 使用“this->”的性能损失?

    考虑 C 类中两个类似的 C 成员函数的示例 void C function Foo new f f new f and void C function Foo new f this gt f new f 这些函数的编译方式是否相同 使用是
  • 释放内存的重要性? [复制]

    这个问题在这里已经有答案了 可能的重复 当 malloc 之后不释放时 到底会发生什么 https stackoverflow com questions 654754 what really happens when you dont f
  • MASM:在 .data 声明中使用当前位置计数器 ($)

    我遇到了有关 MASM 中当前位置计数器的问题 这是我的汇编代码 我使用 Visual Studio 2013 Express 进行汇编 386 model flat stdcall stack 8192 ExitProcess proto
  • 使用 JavaScript 读取 CSS 值

    这有效 div style width 100 div 这确实not work div div 我也尝试过将 css 样
  • 如何避免重复将大文件加载到Python脚本中?

    我编写了一个 python 脚本来获取一个大文件 一个矩阵 50k 行 X 500 列 并将其用作数据集来训练随机森林模型 我的脚本有两个函数 一个用于加载数据集 另一个用于使用所述数据训练随机森林模型 这些都工作得很好 但文件上传大约需要
  • 使用 Node.js 设置 SSL

    我在 GoDaddy 购买了 SSL 证书 并使用以下 node js 服务器尝试设置它 var https require https module for https fs require fs required to read cer
  • 使用 Oracle 客户端 64 位和 Visual Studio 2010 时出现 BadImageFormatException!

    我们的一名开发团队成员遇到了错误 尝试加载 Oracle 客户端库抛出 BadImageFormatException 它似乎 当在 64 位模式下运行并安装了 32 位 Oracle 客户端组件时 会出现此问题 但配置系统的是我 以下是规
  • 点击事件被列表视图父项捕获

    我正在编写一个在 Firemonkey 中使用的自定义开关对象TListView每个项目的控制 除了一个奇怪的故障之外 一切都按预期进行 当用户单击其中一项而不是特定的开关对象时 它无论如何都会切换开关 我假设MouseDown当用户单击列