Delphi 如何为TcxGrid共享OneNet事件?

Delphi 如何为TcxGrid共享OneNet事件?,delphi,events,delphi-2007,Delphi,Events,Delphi 2007,我想标准化Devexpress TcxGrid上的行为。因此,我有一个带有事件的单元ClientData: procedure TClientData.grdOnEnter(Sender: TObject); begin mnuCxGridStandardMenu.Grid := TcxGrid(Sender); end; 如果我试图在另一个单元中使用TcxGrid.oneter事件中的事件,它将拒绝工作。 如果我粘贴到ClientData.grdOnEnter中,则会出现一个对话框,说明

我想标准化Devexpress TcxGrid上的行为。因此,我有一个带有事件的单元ClientData:

procedure TClientData.grdOnEnter(Sender: TObject);
begin
  mnuCxGridStandardMenu.Grid := TcxGrid(Sender);
end;
如果我试图在另一个单元中使用TcxGrid.oneter事件中的事件,它将拒绝工作。 如果我粘贴到ClientData.grdOnEnter中,则会出现一个对话框,说明它不是有效的标识符

是否可以在Delphi 2007中为多个单元共享一个事件


编辑:ClientData是一个数据模块,在启动时创建,在应用程序退出时释放。该引用位于全局变量ClientData中。因此,我认为从另一个单元引用它应该是可行的。

您可以这样做,只要表单单元的uses子句中有ClientData单元,并且存在正确实例化的TClientData对象并且可以访问。(不要混淆类定义和该类类型的对象)。然后,例如,您可以向OnCreate处理程序中添加如下内容:

// Optional - ClientData may be a 'global' object so won't need creating.
// FClientData could be a form member ora more globally accessible variable.
//FClientData := TClientData.Create(Self); 
// or
//FClientData := TClientData.Create(Application);
cxGrid1.OnEnter := FClientData.grdOnEnter;

如果[F]ClientData对象在表单之前被销毁,那么当有东西试图进入OneNet方法时,您将遇到访问冲突。

是的,如果您通过代码分配事件处理程序,它应该可以工作
如果您的事件处理程序不使用ClientData实例中的任何内容(推荐),您甚至不需要创建实例。
TClientData类型的nil变量就足够了

在下面的示例应用程序中,ClientData模块不是由dpr自动创建的,而是保持为零。 这不会阻止事件处理程序正常工作

朝鲜民主主义人民共和国

program Project2;

uses
  Forms,
  Unit10 in 'Unit10.pas' {Form10},
  Unit11 in 'Unit11.pas' {ClientData: TDataModule};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm10, Form10);
  Application.Run;
end.
dfm格式

object Form10: TForm10
  Left = 0
  Top = 0
  Caption = 'Form10'
  ClientHeight = 282
  ClientWidth = 418
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 168
    Top = 168
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
end
pas表格

unit Unit10;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit11, StdCtrls;

type
  TForm10 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form10: TForm10;

implementation

{$R *.dfm}

procedure TForm10.Button1Click(Sender: TObject);
begin
  if ClientData = nil then
    ShowMessage('ClientData is nil')
  else
    ShowMessage('ClientData is NOT nil');
end;

procedure TForm10.FormCreate(Sender: TObject);
begin
  OnClick := ClientData.WhateverEvent;
end;

end.
数据模块dfm

object ClientData: TClientData
  OldCreateOrder = False
  Height = 150
  Width = 215
end
数据模块pas

unit Unit11;

interface

uses
  SysUtils, Classes, Windows;

type
  TClientData = class(TDataModule)
    procedure WhateverEvent(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  ClientData: TClientData;

implementation

{$R *.dfm}

procedure TClientData.WhateverEvent(Sender: TObject);
begin
  MessageBox(0, PChar('Sender is ' + Sender.ClassName), 'Test', MB_ICONINFORMATION or MB_OK);
end;

end.

Se我的编辑插件。ClientData是对singleton类的全局引用。它应该可以工作,但仍然需要。您是否尝试过在运行时而不是设计时分配事件处理程序?例如在表单的一次创建中。我想知道设计时间问题是否是由于cxGrid的设计有些“不寻常”。这都是TcxGridSite和网格视图等的组合,因此可能OneNet方法没有按照表单的预期看到。但这可能是错误的……看来这毕竟与cxGrid的古怪之处无关。在D2010中,可以使用对象检查器从其他模块分配组件引用,但不能在设计时(仅在运行时)分配它们的方法/事件处理程序。据我所知。