PDA

Ver la Versión Completa : Perder El Foco


raquel
03-07-2007, 11:10:17
He estado mirando y quiero comprobar que cuando paso de un campo a otro el otro campo es correcto.
Esto lo hacia en basic con la propiedad lostfocus, aqui he leido algo de CM_LOSTFOCUS pero no me aclaro como implementar eso ni donde he de declarar el procedimiento.

Podrian echarme una mano?

Lepe
03-07-2007, 11:55:11
Los controles dbedit, edit, etc, tiene el evento OnEnter y OnExit, es lo que buscas.

Incluso en los campos, tienes el evento Onchange.

Saludos

ArdiIIa
03-07-2007, 12:09:00
Hola raquel:

Te propongo un método adaptando una rutina de Zarko Gajic en la que podrás ver a modo de ejemplo, como es posible el cambio de colores entre diferentes TEdit, que supongo que en tu caso serán TDBedit.

Adaptando este procedimiento podrías realizar el control que pretendes, sin embargo, he de comentarte, que a mi juicio esto coarta el modo de comportamiento de un programa, dado que si el objetivo es que el usuario vaya a un control específico, sin pasar por otro, o tras haber pasado por otro... ¿Que ocurre si desea volver al anterior ? En fin es tu programa el que ha de discernir cual es el control correcto en un momento determinado, aunque tal como comenta Lepe, creo que lo mejor es usar unas reglas de validación en cada control, y dejar el usuario que determine en que parte de la ventana quiere estar....:)

El código:




type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ScreenActiveControlChange(Sender: TObject) ;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
lastFocused : TWinControl;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Screen.OnActiveControlChange := ScreenActiveControlChange;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
Edit1.SetFocus;
Application.ProcessMessages;
TEdit(Screen.ActiveControl).Color := clBlue;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
Screen.OnActiveControlChange := Nil;
end;

procedure TForm1.ScreenActiveControlChange(Sender: TObject) ;
var
previousActiveControl : TWinControl;
Begin
if (Screen.ActiveControl = nil) and (Screen.ActiveControl is TEdit) then
begin
lastFocused := nil;
Exit;
end;

if lastFocused <> NIL then
Begin
previousActiveControl := lastFocused;
TEdit(Screen.ActiveControl).Color := clBlue;
TEdit(previousActiveControl).Color := clWindow;
End;

lastFocused := Screen.ActiveControl;

End;



Espero que te resulte útil.

Lepe
03-07-2007, 14:28:56
aunque tal como comenta Lepe, creo que lo mejor es usar unas reglas de validación en cada control,
¡Eh! ¡ a mí no me metas en líos ehhh! :D :D que yo solo he respondido a la pregunta concreta ;) ;).

Ya en serio, estamos en el foro Varios y se habla de Bases de datos, pero no sabemos cual, tampoco sabemos mucho acerca del programa en cuestión, si son muchas las validaciones o es una sola, si estamos en Cliente/Servidor o no.... Así que solo respondí a la pregunta.

Normalmente este tipo de validaciones es mejor hacerlo en la Base de datos:
- Que un campo se necesita, poner NOT NULL en su definición, que sea el motor de Bases de datos quien haga saltar el error, y después manipulamos el mensaje a mostrar al usuario (para traducirlo a español).

- Que un valor no debe repetirse, añadir un índice único sobre ese campo, ya no tendremos que hacer búsquedas para saber si el nuevo dato se repite o no.

- Que debe restringirse el rango de datos, (porcentajes entre 1-100, que no permita números negativos), usar los Checks (si se puede)
- etc.

Ahora que recuerdo, con los eventos OnExit y OnEnter, existe un problemilla: el usuario puede modificar un campo pero no salir de ese DBEdit (porque usemos un SpeedButton para guardar los cambios; un control que no adquiere el foco y por tanto, al pulsarlo, no hará saltar el OnExit del DBEdit), así que el mensaje de error que programemos nunca se verá, y lo más grabe ¡¡ a saber qué guarda en la Base de Datos!! (incoherencias, inconsistencia de datos...).

Es cierto que quizás sean conceptos nuevos, o incluso más engorroso de implementar por primera vez, pero sin duda, más fiable que el método "rápido y poco limpio" de usar OnExit y OnEnter.

Como siempre, dependerá de qué y cómo quiere hacerlo.

Saludos

ArdiIIa
03-07-2007, 15:47:18
Mmmm! No se Lepe.
Parece que el mensaje de raquel, puede dar a distintas interpretaciones.

Yo he entendido y citando lo que ella comenta sobre CM_LOSTFOCUS , que el control lo realiza sobre cuando el usuario cambia de un DbEdit a otro... y esta interpretación la hago, porque buscando CM_LOSTFOCUS en estos foros solamente sale un hilo, en el que por cierto participaste tú, y se habla de cambios y control de foco...

En todo caso, y a falta de que raquel no de mas detalles del asunto, esperaremos a ver si la hemos solucionado algo, o por contra, lo que hacemos es liarnos todos....:D :D

roman
03-07-2007, 17:30:07
Si se va a validar por campo, creo que entonces, más que el evento OnExit del DBEdit, lo adecuado sería el evento OnValidate del TField correspondiente. Pero, yo también considero que este tipo de validaciones lo único que hacen es irritar al usuario. Eran muy típicas de Clipper pero en entornos gráficos no son tan necesarias y es más cómodo hacer la validación en el BeforePost.

// Saludos

Lepe
03-07-2007, 18:45:07
Mucho me temo que me quedaré con la intriga; mañana cambio de domicilio por periodo estival y me quedo sin internet un par de meses.

...Prometo acordarme de vosotros en mi butaca bajo la sombrilla... :cool:

ArdiIIa
03-07-2007, 19:07:32
Mucho me temo que me quedaré con la intriga; mañana cambio de domicilio por periodo estival y me quedo sin internet un par de meses.

...Prometo acordarme de vosotros en mi butaca bajo la sombrilla... :cool:

Vaya forma de decirnos que hace calor y que vas a refrescar....:D :D

Mucho refresco me parecen dos meses... será mejor que toques algún ciber..:D

Que te diviertas..;)

david_uh
03-07-2007, 19:19:13
He estado mirando y quiero comprobar que cuando paso de un campo a otro el otro campo es correcto.
Esto lo hacia en basic con la propiedad lostfocus, aqui he leido algo de CM_LOSTFOCUS pero no me aclaro como implementar eso ni donde he de declarar el procedimiento.

Podrian echarme una mano?
el evento es OnExit en delphi

Lepe
03-07-2007, 20:56:13
...esto, bueno...., es que.... en realidad me ingresan en un centro de desintoxicación de internet :D :D :p

Saludos veraniegos

raquel
04-07-2007, 09:35:38
Hola a todos, gracias por responder:

Lo que yo queria era que al salir del campo comprobara en la bd el codigo introducido para dependiendo del codigo rellenar otro campo automaticamente.

Lo he echo con OnExit. Pero lo que habeis dicho me ha interesado mucho.
Es decir, si yo lo que quiero es asegurarme por ejemplo de que mete un numero del 1-100 o que la cadena que meta tiene cierto nº de caracteres, todo eso es mejor hacerlo en la BD?

El evento OnValidate cuando se activa?

El error que salta en la BD lo capturas mediante el try catch no?

Lamento molestar tanto pero es que soy muy nueva en lo que es todo delphi y me pilla todo un poco verde. Como muchas de las cosas que me ha puesto ardilla en el codigo, que no sabian ni que existian.

Un beso.

Lepe
23-09-2007, 13:02:54
Arriba este tema perdido ;).

Si quieres que una cadena tenga 4 caracteres como máximo, es más comodo asignar la propiedad MaxLength del control (solución rápida y efectiva).

Si quieres comprobar el contenido que ha escrito, es más cómodo que lo haga la BD.

El error que salte en la BD puedes capturarlo como dices, aunque también puedes programar el evento OnPostError del Dataset.

Saludos