用于自定义组件中控件的OnClick事件处理程序不起作用(Lazarus) [英] OnClick event handler for control in custom component not working (Lazarus)

查看:104
本文介绍了用于自定义组件中控件的OnClick事件处理程序不起作用(Lazarus)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用:拉撒路1.2.0; Windows 32位应用程序

Using: Lazarus 1.2.0; Windows 32-bit application

我编写了一个自TPanel派生的自定义组件,它包含4个TEdit控件.我已经为TEdits编写了OnClick事件处理程序代码.但是,它在运行时不起作用,即事件未触发.我不确定我错过了什么.请您告诉我我做错了什么吗?

I have written a custom component derived from TPanel and it conains 4 TEdit controls. I've written the OnClick event handler code for the TEdits. However its not working at runtime ie the events are not firing. I'm not sure what I missed. Please can you tell me what I'm doing wrong?

组件代码如下:

unit uEditPanel;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;

type

  { TEditPanel }

  TEditPanel = class(TCustomPanel)
    Edit0: TEdit;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;

    procedure SetEdit1OnClick(const AEvent: TNotifyEvent);
    procedure SetEdit2OnClick(const AEvent: TNotifyEvent);
    procedure SetEdit3OnClick(const AEvent: TNotifyEvent);
    procedure SetEdit4OnClick(const AEvent: TNotifyEvent);

  private
    { Private declarations }
    FEdit1OnClick: TNotifyEvent;
    FEdit2OnClick: TNotifyEvent;
    FEdit3OnClick: TNotifyEvent;
    FEdit4OnClick: TNotifyEvent;

    function GetEdit0Text: string;
    procedure SetEdit0Text(AText: string);
    function GetEdit1Text: string;
    procedure SetEdit1Text(AText: string);
    function GetEdit2Text: string;
    procedure SetEdit2Text(AText: string);
    function GetEdit3Text: string;
    procedure SetEdit3Text(AText: string);
    function GetEdit4Text: string;
    procedure SetEdit4Text(AText: string);

  protected
    { Protected declarations }
    procedure DoEdit1Click;
    procedure DoEdit2Click;
    procedure DoEdit3Click;
    procedure DoEdit4Click;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  published
    { Published declarations }
    property Edit0Text: string read GetEdit0Text write SetEdit0Text;
    property Edit1Text: string read GetEdit1Text write SetEdit1Text;
    property Edit2Text: string read GetEdit2Text write SetEdit2Text;
    property Edit3Text: string read GetEdit3Text write SetEdit3Text;
    property Edit4Text: string read GetEdit4Text write SetEdit4Text;

    property OnEdit1Click: TNotifyEvent read FEdit1OnClick write SetEdit1OnClick;
    property OnEdit2Click: TNotifyEvent read FEdit2OnClick write SetEdit2OnClick;
    property OnEdit3Click: TNotifyEvent read FEdit3OnClick write SetEdit3OnClick;
    property OnEdit4Click: TNotifyEvent read FEdit4OnClick write SetEdit4OnClick;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Standard', [TEditPanel]);
end;

{ TEditPanel }

procedure TEditPanel.SetEdit1OnClick(const AEvent: TNotifyEvent);
begin
  FEdit1OnClick := AEvent;
end;

procedure TEditPanel.SetEdit2OnClick(const AEvent: TNotifyEvent);
begin
  FEdit2OnClick := AEvent;
end;


procedure TEditPanel.SetEdit3OnClick(const AEvent: TNotifyEvent);
begin
  FEdit3OnClick := AEvent;
end;


procedure TEditPanel.SetEdit4OnClick(const AEvent: TNotifyEvent);
begin
  FEdit4OnClick := AEvent;
end;

function TEditPanel.GetEdit0Text: string;
begin
  Result := Edit0.Text;
end;

procedure TEditPanel.SetEdit0Text(AText: string);
begin
  Edit0.Text := AText;
end;

function TEditPanel.GetEdit1Text: string;
begin
  Result := Edit1.Text;
end;

procedure TEditPanel.SetEdit1Text(AText: string);
begin
  Edit1.Text := AText;
end;

function TEditPanel.GetEdit2Text: string;
begin
  Result := Edit2.Text;
end;

procedure TEditPanel.SetEdit2Text(AText: string);
begin
  Edit2.Text := AText;
end;

function TEditPanel.GetEdit3Text: string;
begin
  Result := Edit3.Text;
end;

procedure TEditPanel.SetEdit3Text(AText: string);
begin
  Edit3.Text := AText;
end;

function TEditPanel.GetEdit4Text: string;
begin
  Result := Edit4.Text;
end;

procedure TEditPanel.SetEdit4Text(AText: string);
begin
  Edit4.Text := AText;
end;

procedure TEditPanel.DoEdit1Click;
begin
  if Assigned(FEdit1OnClick) then
    FEdit1OnClick(Self);
end;

procedure TEditPanel.DoEdit2Click;
begin
  if Assigned(FEdit2OnClick) then
    FEdit2OnClick(Self);
end;

procedure TEditPanel.DoEdit3Click;
begin
  if Assigned(FEdit3OnClick) then
    FEdit3OnClick(Self);
end;

procedure TEditPanel.DoEdit4Click;
begin
  if Assigned(FEdit4OnClick) then
    FEdit4OnClick(Self);
end;

constructor TEditPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  Edit0 := TEdit.Create(Self);
  Edit1 := TEdit.Create(Self);
  Edit2 := TEdit.Create(Self);
  Edit3 := TEdit.Create(Self);
  Edit4 := TEdit.Create(Self);

  Edit0.Parent := Self;
  Edit1.Parent := Self;
  Edit2.Parent := Self;
  Edit3.Parent := Self;
  Edit4.Parent := Self;

  Edit0.SetSubComponent(True);
  Edit1.SetSubComponent(True);
  Edit2.SetSubComponent(True);
  Edit3.SetSubComponent(True);
  Edit4.SetSubComponent(True);

  Edit1.ReadOnly := True;
  Edit2.ReadOnly := True;
  Edit3.ReadOnly := True;
  Edit4.ReadOnly := True;

  Edit1.OnClick := FEdit1OnClick;
  Edit2.OnClick := FEdit2OnClick;
  Edit3.OnClick := FEdit3OnClick;
  Edit4.OnClick := FEdit4OnClick;

  Caption := EmptyStr;
  Height := 117;
  Width := 289;
  BevelOuter := bvNone;
  ClientHeight := 117;
  ClientWidth := 289;

  Edit0.Left := 0;
  Edit0.Height := 21;
  Edit0.Top := 0;
  Edit0.Width := 288;
  Edit0.BorderStyle := bsNone;
  Edit0.TabOrder := 0;

  Edit1.Left := 0;
  Edit1.Height := 21;
  Edit1.Top := 24;
  Edit1.Width := 288;
  Edit1.BorderStyle := bsNone;
  Edit1.TabOrder := 1;
  Edit1.Font.Color := clGray;

  Edit2.Left := 0;
  Edit2.Height := 21;
  Edit2.Top := 48;
  Edit2.Width := 288;
  Edit2.BorderStyle := bsNone;
  Edit2.TabOrder := 2;
  Edit2.Font.Color := clGray;

  Edit3.Left := 0;
  Edit3.Height := 21;
  Edit3.Top := 72;
  Edit3.Width := 288;
  Edit3.BorderStyle := bsNone;
  Edit3.TabOrder := 3;
  Edit3.Font.Color := clGray;

  Edit4.Left := 0;
  Edit4.Height := 21;
  Edit4.Top := 96;
  Edit4.Width := 288;
  Edit4.BorderStyle := bsNone;
  Edit4.TabOrder := 4;
  Edit4.Font.Color := clGray;

end;



end.

在运行时,我的组件如下所示:

At runtime my component looks like this:

推荐答案

您将事件存储在字段中,但未设置控件事件.

You store the events into a field but you do not set the controls event.

constructor TEditPanel.Create(AOwner: TComponent);
begin
  ...
  // Assign the current value, but is nil at this moment
  Edit1.OnClick := FEdit1OnClick;
  ...
end;

procedure TEditPanel.SetEdit1OnClick(const AEvent: TNotifyEvent);
begin
  // set a new value only to the field
  FEdit1OnClick := AEvent;
end;

没有来自字段和编辑控件事件处理程序的魔术值传输.您还必须设置该值以及控制事件.

There is no magic value transport from the field and the edit control event handler. You have to set the value also the the control event.

但是您可以像使用Text属性一样直接从控件访问事件属性.

But you can access the event properties direct from the controls as you do with the Text properties.

您应该查看重复代码以简化/缩短代码.

And you should have a look at repeating code to simplify/shorten it.

unit uEditPanel;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;

type

  { TEditPanel }

  TEditPanel = class( TCustomPanel )
  private
    Edit0 : TEdit;
    Edit1 : TEdit;
    Edit2 : TEdit;
    Edit3 : TEdit;
    Edit4 : TEdit;
    { Private declarations }
    function GetEditOnClick( const Index : Integer ) : TNotifyEvent;
    function GetEditText( const Index : Integer ) : string;
    procedure SetEditOnClick( const Index : Integer; const Value : TNotifyEvent );
    procedure SetEditText( const Index : Integer; const Value : string );
    procedure InitEdit( AEdit : TEdit; ATop, ATabOrder : Integer; AReadOnly : Boolean );
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create( AOwner : TComponent ); override;
  published
    { Published declarations }
    property Edit0Text : string index 0 read GetEditText write SetEditText;
    property Edit1Text : string index 1 read GetEditText write SetEditText;
    property Edit2Text : string index 2 read GetEditText write SetEditText;
    property Edit3Text : string index 3 read GetEditText write SetEditText;
    property Edit4Text : string index 4 read GetEditText write SetEditText;

    property OnEdit1Click : TNotifyEvent index 1 read GetEditOnClick write SetEditOnClick;
    property OnEdit2Click : TNotifyEvent index 2 read GetEditOnClick write SetEditOnClick;
    property OnEdit3Click : TNotifyEvent index 3 read GetEditOnClick write SetEditOnClick;
    property OnEdit4Click : TNotifyEvent index 4 read GetEditOnClick write SetEditOnClick;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents( 'Standard', [TEditPanel] );
end;

{ TEditPanel }

function TEditPanel.GetEditOnClick( const Index : Integer ) : TNotifyEvent;
begin
  case index of
    0 :
      Result := Edit0.OnClick;
    1 :
      Result := Edit1.OnClick;
    2 :
      Result := Edit2.OnClick;
    3 :
      Result := Edit3.OnClick;
    4 :
      Result := Edit4.OnClick;
  end;
end;

function TEditPanel.GetEditText( const Index : Integer ) : string;
begin
  case index of
    0 :
      Result := Edit0.Text;
    1 :
      Result := Edit1.Text;
    2 :
      Result := Edit2.Text;
    3 :
      Result := Edit3.Text;
    4 :
      Result := Edit4.Text;
  end;
end;

procedure TEditPanel.SetEditOnClick( const Index : Integer; const Value : TNotifyEvent );
begin
  case index of
    0 :
      Edit0.OnClick := Value;
    1 :
      Edit1.OnClick := Value;
    2 :
      Edit2.OnClick := Value;
    3 :
      Edit3.OnClick := Value;
    4 :
      Edit4.OnClick := Value;
  end;
end;

procedure TEditPanel.SetEditText( const Index : Integer; const Value : string );
begin
  case index of
    0 :
      Edit0.Text := Value;
    1 :
      Edit1.Text := Value;
    2 :
      Edit2.Text := Value;
    3 :
      Edit3.Text := Value;
    4 :
      Edit4.Text := Value;
  end;
end;

procedure TEditPanel.InitEdit( AEdit : TEdit; ATop, ATabOrder : Integer; AReadOnly : Boolean );
begin
  AEdit.Parent := Self;
  AEdit.SetSubComponent( True );
  AEdit.ReadOnly := AReadOnly;
  AEdit.Left := 0;
  AEdit.Top := ATop;
  AEdit.Height := 21;
  AEdit.Width := 288;
  AEdit.BorderStyle := bsNone;
  AEdit.TabOrder := ATabOrder;
  if AReadOnly
  then
    AEdit.Color := clGray;
end;

constructor TEditPanel.Create( AOwner : TComponent );
begin
  inherited Create( AOwner );

  Caption := EmptyStr;
  Height := 117;
  Width := 289;
  BevelOuter := bvNone;
  ClientHeight := 117;
  ClientWidth := 289;

  Edit0 := TEdit.Create( Self );
  Edit1 := TEdit.Create( Self );
  Edit2 := TEdit.Create( Self );
  Edit3 := TEdit.Create( Self );
  Edit4 := TEdit.Create( Self );

  InitEdit( Edit0, 0, 0, False );
  InitEdit( Edit1, 24, 1, True );
  InitEdit( Edit2, 48, 2, True );
  InitEdit( Edit3, 72, 3, True );
  InitEdit( Edit4, 96, 4, True );
end;

end.

如果您使用数组管理编辑控件,您的代码可以写得很短,甚至会变得更短.

Your code can be written very short and will even become shorter if you manage the edit controls with an array.

这篇关于用于自定义组件中控件的OnClick事件处理程序不起作用(Lazarus)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆