【问题标题】:How to catch scrolling event in DBGrid in Delphi如何在 Delphi 的 DBGrid 中捕获滚动事件
【发布时间】:2009-11-12 16:40:49
【问题描述】:

我有一个 DBGrid,每次使用水平滚动条时,我都需要运行一些代码。我在 DBGrid 中找不到这样的事件。能给点建议吗?

【问题讨论】:

    标签: delphi events scrollbar dbgrid


    【解决方案1】:

    TCustomGrid 中有一个 WMHScroll 过程,但它是私有的。您不能在 DBGrid 中使用它。
    您必须创建自己的 TDBGrid 后代并自己做

    procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
    

    或者做一些非常糟糕的黑客行为......

    更新:欺骗/破解您的代码...

    [...]
        uses
          Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
          Dialogs, DB, ADODB, Grids, DBGrids;
    
        type
          // Hack to redeclare your TDBGrid here whitout the the form designer going mad
          TDBGrid = class(DBGrids.TDBGrid)
            procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL;
          end;
    
          TForm8 = class(TForm)
            DBGrid1: TDBGrid;
            DataSource1: TDataSource;
            ADODataSet1: TADODataSet;
            ADOConnection1: TADOConnection;
          private
            { Private declarations }
          public
            { Public declarations }
          end;
    
        var
          Form8: TForm8;
    
        implementation
    
        {$R *.dfm}
    
        { TDBGrid }
    
        procedure TDBGrid.WMHScroll(var Msg: TWMHScroll);
        begin
          case Msg.ScrollCode of
            SB_ENDSCROLL: OutputDebugString('SB_ENDSCROLL') ;
            SB_LEFT:OutputDebugString('SB_LEFT');
            SB_RIGHT:OutputDebugString('SB_RIGHT');
            SB_LINELEFT:OutputDebugString('SB_LINELEFT');
            SB_LINERIGHT:OutputDebugString('SB_LINERIGHT');
            SB_PAGELEFT:OutputDebugString('SB_PAGELEFT');
            SB_PAGERIGHT:OutputDebugString('SB_PAGERIGHT');
            SB_THUMBPOSITION:OutputDebugString('SB_THUMBPOSITION');
          end;
          inherited; // to keep the expected behavior
        end;
    [...]
    

    Update2:请注意,您可以将您的特殊 TDBGrid 代码移动到单独的单元(推荐),只需确保将此 单元名称 AFTER DBGrids 放在 Form 的 uses 子句中.

    【讨论】:

    • 是的,这正是 yozey 的文章所暗示的。我已经创建了这样的组件。现在的问题是 - 如何从旧的迁移到新的,而不删除并重新创建?
    • 谢谢,我不知道这样的黑客行为是可能的:)
    • Tofig,请参阅我的 Update2。您可以避免更改现有代码。
    【解决方案2】:

    也许这会有所帮助。它显示了一个捕获常规 TStringGrid 的滚动事件的示例。 Synchronize the Scrolling of two TStringgrids?

    【讨论】:

    • 这行得通,但我这里有一点缺乏知识,你能帮忙吗?我创建了一个新组件 TScrDBGrid,但是我已经将一个 DBGrid 放置在一个已经声明了许多属性和事件的表单上,所以我不想删除并创建一个新组件。有没有办法可以将此 DBGrid “迁移”到新类?
    • 您可以将新组件安装到一个包中,然后将该包安装到 IDE 中,以便编译器知道它。关闭带有您要替换的 DBGrid 的单元,这样它就不会在 IDE 中打开。 首先复制 .DFM 和 PAS 文件! 在记事本中打开文本 .DFM 并将 TDBGrid 替换为新网格的类名。对匹配的 .PAS 文件的 interface 部分执行相同操作,并确保将新单元的名称添加到 interface uses 子句。保存文件,然后在 IDE 中重新打开它。如果你做对了,一切都会好起来的。如果没有,请恢复备份副本。
    • 最后一个问题。虽然此事件现在有效,但滚动条停止工作,似乎在捕获此事件时,它阻止了它进一步进入窗口以进行实际滚动操作。我应该如何解决这个问题?
    • @Tofig:你的 WMHScroll 过程中是否继承了调用?如果不是,您必须自己提供预期的行为
    • @Tofig:有一个技巧可以用来避免重新声明所有组件。如果您创建一个具有确切名称的后代组件,但引用了包括单元名称在内的父组件,您应该只需添加该单元就可以继续,而无需更改组件。因此,您将声明一个 TDBGrid = class(DBGrids.TDBGrid) 并在一个新单元(如“MyGrid.pas”)中添加您的功能,通过将其添加到使用 DBGrid 的那些区域,您应该没问题。我正在尝试找到我从中挑选的文章。
    【解决方案3】:

    编辑:显然是错误的答案。它捕获 vertical 滚动条,但不捕获 horizo​​ntal 滚动条。

    您不会在 DBGrid 级别捕获它。您在附加的 TDataSet 的 BeforeScroll 或 AfterScroll 处捕获它。它使用滚动条、向上和向下箭头键、向上翻页触发 以及出现在 DBGrid 中的向下翻页键等。

    【讨论】:

    • 它适用于垂直滚动,但不适用于水平滚动。你如何让它触发水平滚动?
    • 我认为这对 OP 没有多大好处。他想捕获水平滚动,即当可见列发生变化时。
    • 啊,你当然是对的。我错过了“水平”。感谢您的指正。 @Tofig:我不认为你可以抓住水平滚动;至少我写的一个快速测试应用程序不能。左右箭头键在 OnColEnter 和 OnColExit 事件中起作用,但不会通过滚动条触发,因为所选列未更改。
    • yozey 的回答实际上可以提供帮助,但我对此有疑问(请参阅对他回答的评论),也许您可​​以帮忙?
    • @Tofig:查看我对 yozey 的回答的评论。
    【解决方案4】:

    我目前无法检查,但如果我没记错的话,该事件就在那里,但没有发布。尝试创建一个源自 TDBGrid 并发布滚动条事件的控件。

    【讨论】:

    • 我检查了这个,但仍然找不到这样的事件。有一个名为 ScrollBars 的元素,但没有与之相关的事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多