如何知道用户何时更改了TMemo/TEdit中的文本?

3
我一直被TMemo(和其他类似控件)只有OnChange事件困扰着。我想知道用户何时更改了文本,而不是在程序中更改文本时。 我知道两种方法来区分用户更改的文本和由程序更改的文本:
  1. 在以编程方式更改文本之前将OnChange:= NIL。然后恢复OnChange。这很容易出错,因为您需要记住每次从代码更改文本时都要这样做(以及需要对哪些备忘录/编辑应用此特殊处理)。现在我们知道每次调用OnChange时,控件都是由用户编辑的。
  2. 捕获OnKeyPress,MouseDown等事件。确定实际上是否更改了文本,并手动调用需要在用户编辑文本时调用的代码。 这可能会向已经很大的文件中添加大量过程。
还有更优雅的方法吗?

1
如果更改来自于粘贴呢?或者是来自自动化?有很多可以改变内容的方式,不仅仅是打字或您的应用程序代码。 - David Heffernan
5
为什么这很重要呢?这可能意味着你试图解决错误的问题。 - J...
2个回答

5
你可以编写一个帮助程序来实现你的第一种选项,并在需要确保在设置文本时不触发任何OnChange事件的情况下,在你的框架中使用它。例如:
type
  TCustomEditAccess = class(TCustomEdit);

procedure SetEditTextNoEvent(Edit: TCustomEdit; const AText: string);
var
  OldOnChange: TNotifyEvent;
begin
  with TCustomEditAccess(Edit) do
  begin
    OldOnChange := OnChange;
    try
      OnChange := nil;
      Text := AText;
    finally
      OnChange := OldOnChange;
    end;
  end;
end;

TMemo 还有一个 Lines 属性,它也会触发 OnChange 事件,因此您可以编写另一个类似的过程,接受 Lines: TStrings 参数。


3

How about using the Modified property?

procedure TForm1.MyEditChange(Sender: TObject);
begin
    if MyEdit.Modified then
    begin
        // The user changed the text since it was last reset (i.e. set programmatically)

        // If you want/need to indicate you've "taken care" of the 
        // current modification, you can reset Modified to false manually here.
        // Otherwise it will be reset the next time you assign something to the 
        // Text property programmatically.
        MyEdit.Modified := false;
    end;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接