程序定义了一个全局变量,当值发生变化的时候响应一些事件。因此想自己给这个变量写一个OnChange事件,请问应该如何自定义这么一个事件?有例子参考最好。谢谢!

解决方案 »

  1.   

    封装此变量为不可直接访问
    提供2个函数进行读、写,提供一个Onchange事件
    在写的函数里判断Onchange事件响应函数是否有效,有效则执行该响应函数
      

  2.   

    同意,也就是说对变量的操作通过函数来实现,客户代码不能直接修改,例如用类实现如下
    class ci{
      static private int i;
      static public int get();
      static public void set();
    }
    i为全局变量,对他的修改只能通过get和set函数实现,在get和set中添加对onchange函数的调用
      

  3.   


    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      TMyEvent = procedure(sender : TObject) of object;
    type
      TForm1 = class(TForm)
        edt1: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure edt1Change(Sender: TObject);
      private
        FChange : TMyEvent;
        { Private declarations }
        procedure _Change(sender : TObject);
      public
        property On_Change : TMyEvent read FChange write FChange;
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    procedure TForm1._Change(sender: TObject);
    begin
      ShowMessage('大于10');
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       FChange := _Change;
    end;procedure TForm1.edt1Change(Sender: TObject);
    begin
      if StrToInt(edt1.Text) > 10 then On_Change(sender);
    end;end.
      

  4.   

    楼上正解。
    楼主自己应该可以想到,仿Property的写法。
      

  5.   

    CDSoftwareWj 的头像又恶心到我了。靠!
      

  6.   

    我想了想,貌似3楼的回答有点不对。他是通过Edit1change来触发的On_change事件,他把Edit1做为要进行操作的全局变量。
    可是,关键的是,如果你用Edit1change来触发另一个事件,你不如自己在Edit1change里面把你要做的事做完。
    貌似再去执行On_change事件有点多余。
      

  7.   


    procedure TForm1.FormCreate(Sender: TObject);
    begin
       FChange := _Change;      //应该是on_change
    end;procedure TForm1.edt1Change(Sender: TObject);
    begin
      if StrToInt(edt1.Text) > 10 then On_Change(sender); //这个不能这样用啊,肯定会报错的。
    end;
    我下午没什么事,觉得这个问题有点意思,于是拿兄弟代码看看,貌似不对,有些错误。呵呵。当然,这无伤大雅,关键是思想嘛

    关键问题
    :楼主是想给一个变量写on_change事件?我发现很难啊。可能是我下午比较晕。反正我是写不出。你的想法是不是这样?假如你设置了一个x:integer的全局变量,这个变量在程序运行的过程中,可能由于函数调用什么给改变了值,可能改成了1,或者改成2,那么你想要的是,一旦这个x被改了,那么就触发了一个事件。
    总结:很难,不知道哪位高手也指导一下我。很有意思的问题啊,顶一顶。
      

  8.   


      unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    type
      TMyEvent = procedure(sender : TObject) of object;
    type
      TForm1 = class(TForm)
        edt1: TEdit;
        procedure FormCreate(Sender: TObject);
        procedure edt1Change(Sender: TObject);
      private
        FChange : TMyEvent;
        { Private declarations }
        procedure _Change(sender : TObject);
      public
        property On_Change : TMyEvent read FChange write FChange;
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    procedure TForm1._Change(sender: TObject);
    begin
      ShowMessage('大于10');
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       FChange := _Change;                                 //FChange应该是On_Change 
    end;procedure TForm1.edt1Change(Sender: TObject);
    begin
      if StrToInt(edt1.Text) > 10 then On_Change(sender);  //不能这样写On_Change(sender)
    end;end.
    弱弱的问一句,代码里的颜色怎么设置的?
      

  9.   

    定义一个简单的类,继承自TObject,然后类里有那个变量,在它的属性里设置write, read 方法
    楼上已有属性的代码的然后把这个类弄成全局变量嘿嘿
      

  10.   

    兄弟,我也是这样想,可是我觉得写不了啊,触发怎么写啊?像edit控件的on_change貌似不好写啊。
    你教教我吧,呵呵。
      

  11.   

    哥啊,我是说真的,你自己亲自写一下玩玩咯。教我啊。我觉得写不出。
    像edit控件的on_change事件,这个事件触发是通过WM_TEXTCHANGE消息的,接着触发change()事件。
    以下是我从IDE里拷出来的部分代码TEdit = class(TCustomEdit)
    TCustomEdit = class(TWinControl)
      private
        FOnChange: TNotifyEvent;
      procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
      protected
        procedure Change; dynamic;procedure TCustomEdit.CMTextChanged(var Message: TMessage);
    begin
      inherited;
      if not HandleAllocated or (GetWindowLong(Handle, GWL_STYLE) and
        ES_MULTILINE <> 0) then Change;
    end;procedure TCustomEdit.Change;
    begin
      inherited Changed;
      if Assigned(FOnChange) then FOnChange(Self);
    end;
    我很想知道你怎么弄啊。
      

  12.   


    type
      TForm1 = class(TForm)
      private
        FValue: string;
        FOnChange: TNotifyEvent;
        function getValue: string;
        procedure setValue(const Value: string);
      public  published
        //导出一个属性
        property Value: string read getValue write setValue;
        //导出一个值变化事件
        property OnChange: TNotifyEvent read FOnChange write FOnChange;
      end;var
      Form1: TForm1;implementation{$R *.dfm}function TForm1.getValue: string;
    begin
      Result := FValue;
    end;procedure TForm1.setValue(const Value: string);
    begin
      //属性发生变法时,执行OnChange事件
      if Value <> FValue then
      begin
        if Assigned(FOnChange) then FOnChange(Self);
        FValue := Value;
      end;
    end;
      

  13.   

    小白,我在你的代码后面加了一点,为什么我改变了FValue的值,但是不会触犯ONCHANGE事件啊。
    你帮我看看。谢谢procedure TForm1.FormCreate(Sender: TObject);
    begin
      OnChange:=yes;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
       form1.FValue:='sdfdsf';
       form1.FValue:='j';
    end;procedure TForm1.yes(Sender: TObject);
    begin
     showmessage('yes');
    end;
      

  14.   


    procedure TForm1.Button1Click(Sender: TObject);
    begin
       form1.FValue:='sdfdsf';
       form1.FValue:='j';
    end;
    不能直接访问私有变量FValue,访问Value
    修改成procedure TForm1.Button1Click(Sender: TObject);
    begin
       form1.Value:='sdfdsf';
       form1.Value:='j';
    end;
      

  15.   

    直接改Fvalue,当然没有用了
    要Value:='xxx';才能触发
      

  16.   

    非常感谢各位帮助!只恨囊中羞涩,不能一一给分啊,望见谅!
    另外还有一问题没有解决,请各位兄弟帮忙看看。
    http://topic.csdn.net/u/20100610/19/5bd8ad0f-69af-441a-97fa-5574e3fcaa2b.html