当我调用TSynEdit.Lines的方法LoadFromFile时,不会触发事件OnChange

时间:2014-09-23 09:13:13

标签: delphi lazarus

我有一个使用TSynEdit的项目。我发现当我致电SynEdit1.Lines.LoadFromFile()时,事件OnChange并未被解雇。

例如:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    SynEdit1: TSynEdit;
    procedure Button1Click(Sender: TObject);
    procedure SynEdit1Change(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  SynEdit1.Lines.LoadFromFile('unit1.pas');
end;

procedure TForm1.SynEdit1Change(Sender: TObject);
begin
  Caption:=Caption + '!';
end;

end.

在上面的示例中,我创建了一个具有按钮和SynEdit的表单。

如何在调用OnChange时触发事件SynEdit1.Lines.LoadFromFile()

1 个答案:

答案 0 :(得分:1)

如果您尝试分配synedit的所有事件处理程序,那么您可以获得的最佳结果是清除编辑器时的通知。例如,如果您测试以下代码,则在按钮单击事件后,表单标题将设置为“已清除”:

uses
  Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
  StdCtrls, LazSynEditText;

type
  TSynEditEx = class helper for TSynEdit
    function getTextBuffer: TSynEditStrings;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    SynEdit1: TSynEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure textCleared(sender: TObject);
    procedure textHistoryModified(sender: TObject);
    procedure textBuffChanged(sender: TObject);
    procedure textLineChanged(sender: TObject);
    procedure textEditAction(sender: TObject);
    procedure textModdChanged(sender: TObject);
  end;

var
  Form1: TForm1;

implementation
{$R *.lfm}

function TSynEditEx.getTextBuffer: TSynEditStrings;
begin
  exit(TextBuffer);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SynEdit1.getTextBuffer.AddNotifyHandler(senrCleared, @textCleared);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrUndoRedoAdded, @textHistoryModified);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrTextBufferChanged, @textBuffChanged);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrLineChange, @textLineChanged);
  SynEdit1.getTextBuffer.AddNotifyHandler(senrModifiedChanged, @textModdChanged);
end;

procedure TForm1.textModdChanged(sender: TObject);
begin
  Caption := Caption + ' ModdChanged';
end;

procedure TForm1.textEditAction(sender: TObject);
begin
  Caption := Caption + ' EditAction';
end;

procedure TForm1.textLineChanged(sender: TObject);
begin
  Caption := Caption + ' LineChanged';
end;

procedure TForm1.textBuffChanged(sender: TObject);
begin
  Caption := Caption + ' BuffChanged';
end;

procedure TForm1.textCleared(sender: TObject);
begin
  Caption := Caption + ' Cleared';
end;

procedure TForm1.textHistoryModified(sender: TObject);
begin
  Caption := Caption + ' HistoryModified';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SynEdit1.Lines.LoadFromFile('unit1.pas');
end;

所以唯一的解决方案是子类化TSynEdit并引入自定义LoadFromFile方法,然后在其中触发onChange事件。 AFAIK,基于简短的调查,这是唯一的方式,有点像这样:

uses
  Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
  StdCtrls, LazSynEditText;

type
  TSynEditEx = class helper for TSynEdit
    procedure LoadFromFile(const aFilename: string);
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    SynEdit1: TSynEdit;
    procedure Button1Click(Sender: TObject);
    procedure SynEdit1Change(Sender: TObject);
  private
  end;

var
  Form1: TForm1;

implementation
{$R *.lfm}

procedure TSynEditEx.LoadFromFile(const aFilename: string);
begin
  Lines.LoadFromFile('unit1.pas');
  if assigned(onChange) then
    onChange(self);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SynEdit1.LoadFromFile('unit1.pas');
end;

procedure TForm1.SynEdit1Change(Sender: TObject);
begin
  caption := caption + '!';
end;

在现实世界中,你不会使用类助手,但你更喜欢子类,但我认为你应该明白这一点。