Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 28-01-2009
noob noob is offline
Miembro
 
Registrado: sep 2008
Posts: 212
Poder: 16
noob Va por buen camino
Crear un evento propio

Hola, me gustaría saber si es posible realizar un evento propio en Delphi, es decir, yo tengo un código que quiero que se ejecute cada vez que una variable cambia de valor, por ejemplo:

Código Delphi [-]
Cadena: string;
...
Cadena := 'azul'; // Se ejecuta el evento OnCambiaCadena
Cadena := 'verde' // Se ejecuta el evento OnCambiaCadena
...

procedure MiClase.OnCambiaCadena;
begin
  ShowMessage('Salté');
end;

No se si me explico.

Saludos.
Responder Con Cita
  #2  
Antiguo 29-01-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Hola!

Existen varias formas de implementar lo que deseas, una de ellas es convertir a Cadena en una propiedad de una clase. Pero creo que lo mejor ahora sería que ahondaras un poco sobre lo que quieres conseguir.

¿Cuál es la motivación? ¿Por dónde va esa idea?

Saludos.

Al González.
Responder Con Cita
  #3  
Antiguo 29-01-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Hola noob,
Como dice Al, sería oportuno que nos dieras más detalle.
Formalmente un evento se hace aplicando punteros a métodos. Por ejemplo:

Código Delphi [-]
type
  TCambiaCadenaEvent = procedure (Cadena: string) of object;

Luego tu clase debe definir un atributo de dicho de evento:

Código Delphi [-]
TMiClase = class
...
  private
    FCadena: string; 
    FOnCambiaCadenaEvent: TCambiaCadenaEvent;
...
end;

Ahora viene lo interesante. Tenemos el tipo, más no cuando salta. Dices que se produce al cambiar una cadena. Formalmente, un método hace disparar el evento.

Pero he aquí que en realidad el evento está incompleto. Necesitamos darle una respuesta, en otro caso no debería suceder. Lo de esperar es que uno pueda implementar su rutina, pero tranquilamente uno puede definir un método que tenga la misma declaración que el tipo del evento como respuesta al mismo.

Supongamos que hacemos uso de propiedades para cambiar el texto de la cadena:
Código Delphi [-]
property Cadena: string read FCadena write SetCadena;

SetCadena es un método privado, y en el hacemos que se dispare el evento:

Código Delphi [-]
procedure TMiClase.SetCadena(Value: string);
begin
  if Value <> FCadena
     then  begin
               FCadena := Value;
               if Assigned(FOnCambiaCadenaEvent) // comprobamos que haya Rta
                  then FCambiaCadenaEvent(Value); // disparamos evento
             end;
end;

Ahora si estamos en condiciones de darte Rta al evento y asociarlo.

1) Disparará un método propio de la clase:

Para ello se necesita definir un método que tenga la misma declaración del puntero a método en la clase:

Código Delphi [-]
TMiClase = class
  private
  ...
  procedure EventoCambiarCadena(Cadena: string);
...

procedure TMiClase.EventoCambiarCadena(Cadena: string);
begin
  ShowMeesage(Cadena); // o lo que quieras que haga.
end;


Asociamos el evento a la clase, (tal vez en el constructor):

Código Delphi [-]
FOnCambiaCadenaEvent := EventoCambiarCadena;


2) Y como dije, lo normal es que la clase no sea la "dueña" de la respuesta. Por tanto el método formalmente se define fuera. Necesitamos asignarle el método de alguna manera. Por ejemplo, propiedades:

Código Delphi [-]
property OnCambiaCadenaEvent: TCambiaCadenaEvent read FOnCambiaCadenaEvent ....

Y en base a eso, podemos hacer esto:

Código Delphi [-]
MiClase.OnCambiaCadenaEvent := MiRutina;
MiClase.Cadena := 'Hola, mira como cambio';

En este caso,

La clase solita dispará el evento y aplicará las sentencias definidas en MiRutina.

MiRutina puede ser un método ajeno a la clase TMiClase, necesita ser un método, con la misma declaración más puede ser declarado en otro lado. Por ejemplo:

Código Delphi [-]
procedure TForm1.MiRutina(Cadena: string);
begin
  Label1.Caption := Cadena;
end;

En este caso, es un método definido en el Form1, y lo que hace es visualizar la cadena que cambió en un label.

Espero que se entienda,

Sugiero una leída al capítulo dedicado a los eventos del libro La Cara Oculta de Delphi 4.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #4  
Antiguo 30-01-2009
noob noob is offline
Miembro
 
Registrado: sep 2008
Posts: 212
Poder: 16
noob Va por buen camino
Hola Delphius, he seguido tus indicaciones pero creo que algo me falla.

Tengo esto:

Unit1.pas (mi formulario)

Código Delphi [-]
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    MiClase: cMiClase;
    procedure MiRutina(Cadena: string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  MiClase := cMiClase.Create;
  MiClase.OnCambiaCadenaEvent := MiRutina;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MiClase.Cadena := 'Hola, mira como cambio';
end;

procedure TForm1.MiRutina(Cadena: string);
begin
  Edit1.Text := Cadena;
end;

end.

MiUnit.pas

Código Delphi [-]
unit MiUnit;

interface

type

  TCambiaCadenaEvent = procedure (Cadena: string) of object;

  cMiClase = class
               private
                 FCadena: string;
                 FOnCambiaCadenaEvent: TCambiaCadenaEvent;
                 procedure SetCadena(Value: string);
                 procedure SetOnCambiaCadenaEvent(Value: TCambiaCadenaEvent);
                 procedure EventoCambiarCadena(Cadena: string);
               public
                 constructor Create;
                 property Cadena: string read FCadena
                                         write SetCadena;
                 property OnCambiaCadenaEvent: TCambiaCadenaEvent read FOnCambiaCadenaEvent
                                                                  write SetOnCambiaCadenaEvent;
             end;

implementation

uses Dialogs;

constructor cMiClase.Create;
begin
  FOnCambiaCadenaEvent := EventoCambiarCadena;
end;

procedure cMiClase.SetCadena(Value: string);
begin
  if Value <> FCadena then
    begin
      FCadena := Value;
      if Assigned(FOnCambiaCadenaEvent) then // comprobamos que haya Rta
        FOnCambiaCadenaEvent(Value); // disparamos evento
    end;
end;

procedure cMiClase.SetOnCambiaCadenaEvent(Value: TCambiaCadenaEvent);
begin
  FOnCambiaCadenaEvent := Value;
end;

procedure cMiClase.EventoCambiarCadena(Cadena: string);
begin
  ShowMessage(Cadena); // o lo que quieras que haga.
end;

end.

Saludos.

Última edición por noob fecha: 30-01-2009 a las 18:36:17.
Responder Con Cita
  #5  
Antiguo 30-01-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Pues debería funcionar. A vista rápida no veo error. Prueba este código, verás que funciona apropiadadamente:

Unidad donde está la clase
Código Delphi [-]
unit UMiClase;

interface

type

  // Mi tipo de evento
  TCambiaCadenaEvent = procedure(Cadena: string) of object;

  TMiClase = class
    private
      FCadena: string;
      // nuestro campo de tipo evento
      FOnCambiaCadenaEvent: TCambiaCadenaEvent;

      // métodos privados
      procedure SetCadena(Value: string);
      procedure SetOnCambiaCadenaEvent(Value: TCambiaCadenaEvent);
    public
      constructor Create;
      destructor Destroy; override;
      property Cadena: string read FCadena write SetCadena;
      property OnCambiaCadenaEvent: TCambiaCadenaEvent read FOnCambiaCadenaEvent write SetOnCambiaCadenaEvent;
   end;



implementation

{ TMiClase }

constructor TMiClase.Create;
begin
  inherited Create;
  FOnCambiaCadenaEvent := nil;
end;

destructor TMiClase.Destroy;
begin
  FOnCambiaCadenaEvent := nil;
  inherited Destroy;
end;

procedure TMiClase.SetCadena(Value: string);
begin
  if FCadena <> Value
     then begin
            if Assigned(FOnCambiaCadenaEvent)
               then FOnCambiaCadenaEvent(Value);
          end;
end;

procedure TMiClase.SetOnCambiaCadenaEvent(Value: TCambiaCadenaEvent);
begin
  FOnCambiaCadenaEvent := Value;
end;

end.


Unidad del form:
Código Delphi [-]
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FMiClase: TMiClase;
    procedure MiRutina(Value: string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FMiClase := TMiClase.Create;
  FMiClase.OnCambiaCadenaEvent := MiRutina;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FMiClase.Free;
  Action := CaFree;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FMiClase.Cadena := Edit1.Text;
end;

procedure TForm1.MiRutina(Value: string);
begin
  // esta es la respuesta al evento
  Label1.Caption := 'Hey mira... a cambiado el texto, ahora es: ' + Value;
end;

end.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #6  
Antiguo 30-01-2009
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Hasta, incluso funciona si se define dentro de la propia clase la rutina:

Código Delphi [-]
unit UMiClase;

interface

uses Dialogs;

type

  // Mi tipo de evento
  TCambiaCadenaEvent = procedure(Cadena: string) of object;

  TMiClase = class
    private
      FCadena: string;
      // nuestro campo de tipo evento
      FOnCambiaCadenaEvent: TCambiaCadenaEvent;

      // métodos privados
      procedure SetCadena(Value: string);
      procedure SetOnCambiaCadenaEvent(Value: TCambiaCadenaEvent);

      procedure CambiaCadenaRespuesta(Cadena: string);
    public
      constructor Create;
      destructor Destroy; override;
      property Cadena: string read FCadena write SetCadena;
      property OnCambiaCadenaEvent: TCambiaCadenaEvent read FOnCambiaCadenaEvent write SetOnCambiaCadenaEvent;
   end;



implementation

{ TMiClase }

procedure TMiClase.CambiaCadenaRespuesta(Cadena: string);
begin
  ShowMessage(Cadena);
end;

constructor TMiClase.Create;
begin
  inherited Create;
  FOnCambiaCadenaEvent := CambiaCadenaRespuesta;
end;

destructor TMiClase.Destroy;
begin
  FOnCambiaCadenaEvent := nil;
  inherited Destroy;
end;

procedure TMiClase.SetCadena(Value: string);
begin
  if FCadena <> Value
     then begin
            if Assigned(FOnCambiaCadenaEvent)
               then FOnCambiaCadenaEvent(Value);
          end;
end;

procedure TMiClase.SetOnCambiaCadenaEvent(Value: TCambiaCadenaEvent);
begin
  FOnCambiaCadenaEvent := Value;
end;

end.

Y ahora en el create del form no hacemos la asignación:
Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
begin
  FMiClase := TMiClase.Create;
  //FMiClase.OnCambiaCadenaEvent := MiRutina;
end;

Y si no le comentamos la acción notarás que realiza la rutina que defines en tu form.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Quiero crear mi propio Script! PiornoCKA&G Varios 4 02-01-2007 17:39:19
Crear mi propio tipo de archivo. JuanErasmo C++ Builder 3 18-08-2005 14:53:05
Crear tabla con mi propio tipo.. dmariscal Conexión con bases de datos 6 20-04-2004 19:05:37
Crear mi propio export filter rfernandez Impresión 1 05-02-2004 15:52:52
Ayuda para crear mi propio IDE antonio Varios 2 03-06-2003 13:07:32


La franja horaria es GMT +2. Ahora son las 13:40:07.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi