PDA

Ver la Versión Completa : Campo.Visible := False; ¿Porque no esconde los controles?


xander
05-10-2007, 02:21:26
Siempre habia tenido la idea de que si en una forma donde se muestra un control asociado a un campo, si yo pongo ese campo en Visible := False, el control asociado desaparecería, pero no fue así hoy que lo probé...

Por lo menos no es así de directo... he visto que en cada campo hay un método FocusControl, no hay modo de obtener un puntero a dicho control como para poder hacerlo Invisible??... lo que no quiero es tener que recorrer todos los controles de la forma para ver cual esta asociado con el susodicho campo, quiero algo un poco más automatizado y no chapucero.

Igual y me estoy liando y nomas es llamar a algún metodillo que ya lo hace, pero yo no lo he encontrado, y con esta ayuda que trae el Delphi 2007 no hay quien le entienda. Lo que quisiera es que si el control asociado es una columna de un grid pues que tambien esa columna desapareciera (osea no siembre es un customedit el control asociado) porque el FocusControl si lo hace.

Gracias de antemano carnalitos.

xander
05-10-2007, 17:39:20
Por lo que he visto en mis investigaciones el control viene asociado por algun objeto de la clase TDataLink pero no encuentro donde puedo acceder a el desde el campo.

xander
05-10-2007, 18:33:26
Esto es lo que no quería hacer pero es lo único que me ha funcionado hasta ahorita:


procedure TForm4.Button1Click (Sender: TObject);
var
i: integer;
Liga: TFieldDataLink;
begin
for i := 0 to ControlCount - 1 do
begin
Liga := EnlacCampObje (Controls[i]);
if Assigned (Liga) then
begin
if Liga.FieldName = 'SIZE' then
begin
TWinControl (Liga.Control).Hide;
end;
end;
end;
end;


Pero como ven tengo que recorrer todos los controles de la forma para saber si estan asociados con el campo que quiero esconder, en todo caso quisiera mejor poder acceder a una lista de controles que dependen del campo para ir directo a esos controles... además este código asi tal cual no funciona para las columnas de un DBGrid, tendría que modificarlo todavia para que soporte eso. ¿alguna idea?

maeyanes
05-10-2007, 19:03:47
Hola...

Según la ayuda.. la propiedad Visible de un TField solo sirve para indicar si este se muestra o no en un data grid...

En tu código no necesitas del TDataLink para saber si un campo está o no asociado a un control... Podrías intentar con lo siguiente:


procedure HideFieldControls(AForm: TForm; AField: TField);
var
I: Integer;
PropInfo: PPropInfo;
FieldName: string;

begin
for I := 0 to Pred(AForm.ControlCount) do
begin
PropInfo := GetPropInfo(AForm.Controls[I].ClassInfo, 'DataField');
// Si existe la propiedad DataField en el componente
if Assigned(PropInfo) then
begin
//Obtenemos el nombre del campo y lo comparamos con el que enviamos al procedimiento
FieldName := GetStrProp(AForm.Controls[I], PropInfo);
if (AField.FieldName = FieldName) and (AForm.Controls[I] is TWinControl) then
TWinControl(AForm.Controls[I].Hide
end
end
end;


Esto lo hice de memoria y sin probarlo, espero te sirva...



Saludos...

xander
06-10-2007, 02:17:59
Según la ayuda.. la propiedad Visible de un TField solo sirve para indicar si este se muestra o no en un data grid...


Sip pero ya no funciona si le has agregado las columnas como persistentes al DataGrid...:( por eso busco otra forma


En tu código no necesitas del TDataLink para saber si un campo está o no asociado a un control... Podrías intentar con lo siguiente:


Lo habia pensado inicialmente así, pero es preferible hacerlo con el objeto TDataLink porque no en todos los controles DBAware la propiedad se llama DataField, en algunas librerías solo es Field, en otras FieldName y en otras ni siquiera existe como propiedad sino que es parte de una propiedad compleja que se guarda locamente en los recursos del formulario:)

Todavia no puedo creer que no exista modo de hacerlo directamente desde el campo... :mad: :mad: :mad: Como algo tan sencillo tiene que ser tan chapucero.

PD. ya estoy pensando en ponerselos como un hilo de esos clásicos que luego surgen de: "A ver quien puede con esto... a ver si muy salsas..." para que aunque sea me la mienten :D

Lepe
06-10-2007, 14:01:55
Tú mismo has dicho la solución:

"en todo caso quisiera mejor poder acceder a una lista de controles que dependen del campo para ir directo a esos controles."

Podrías usar un TStringList donde guardas el nombre del campo. El objeto asociado a ese elemento sería un TObjectList que guarda la lista de controles asociados al campo. Aunque me parece tedioso.

¿Por qué quieres ocultar ese control y/o columna del Grid?
¿Es acaso temas de privilegios de usuarios?
¿Es solo el campo llamado "SIZE" o son muchos otros?

Otra solución: Se podría tener una propiedad en la ventana llamada HideSIZE:Boolean , al establecer dicha propiedad, oculta o no los controles específicos de ese Form.

Edito: Un campo puede tener 4 DBEdits asociados a él, y solo tiene una propiedad FocusControl por lo que, a priori, no puedes saber qué controles tiene asociado.

Saludos

xander
06-10-2007, 18:35:57
Podrías usar un TStringList donde guardas el nombre del campo. El objeto asociado a ese elemento sería un TObjectList que guarda la lista de controles asociados al campo. Aunque me parece tedioso.


Para hacer eso tendría que hacer lo mismo que en el código que puse, y que es lo que no quería hacer, recorrer todos los controles de la forma y ver cual esta asociado con el campo que quiero


¿Por qué quieres ocultar ese control y/o columna del Grid?
¿Es acaso temas de privilegios de usuarios?
¿Es solo el campo llamado "SIZE" o son muchos otros?


La idea es hacerlo para cualquier campo... El que puse como SIZE es un ejemplo bien burdo, en cualquier caso es solo parametrizar el campo que me interesa si lo decidiera hacer así... y si, es para que se pueda indicar para cada grupo de usuarios quienes si pueden ver y quienes no ciertos campos... quiero hacerlo a este nivel porque deseo que cualquier hijo de vecino pueda asignar los permisos estos... por eso no me quiero meter con los privilegios de cada usuario en la BD... solo que se puedan mostrar o no ciertos controles... ya tengo bien digerida la idea de como va a ser esto, lo único es que no quería hacer lo que aqui les puse, por eso mi pregunta era como obtengo el puntero a ese control a partir del campo.


Edito: Un campo puede tener 4 DBEdits asociados a él, y solo tiene una propiedad FocusControl por lo que, a priori, no puedes saber qué controles tiene asociado.


Eso no me preocupa porque en el caso en el que pienso aplicar esto solo hay un control por cada campo, pero algunos son Columnas de un Grid otros estan en controles DBAware derivados de TCustomEdit... etc...

Me sorprende que personas que lleven tantos programas de BD a cuestas nunca se hayan topado con esto o no lo hayan resuelto de alguna manera elegante.:p

xander
08-10-2007, 22:11:14
Ok... un gran maestro me ayudo y me ha resuelto el problema de una manera muy elegante... aqui les pongo lo que he hecho para que vean y juzguen:

Lo que yo queria inicialmente es que no se vea el contenido de unos campos en los controles ok?? ocultarselo solo a ciertos usuarios... ok, estaba el caso que me comentaron aqui de que tambien podian haber muchos controles asociados al campo y desaparecerlos uno a uno era un problema pues habia que recorrer todos los controles de la forma solo para hacer eso... entonces mi amigo me dijo: "ok, tu focalizate en el campo, no en los controles; al final de cuentas eso es lo que tu quieres que no se vea: el contenido del campo"

Asi que me dijo que hiciera este método en mi forma:

procedure T_Prototipo.GetTextVacio (Sender: TField; var Text: string;
DisplayText: boolean);
begin
Text := '';
Sender.ReadOnly := True;
end;


Y para cada campo que deseas esconder del usuario hazle esto:

DataSet.FieldByName ('tu_campo').OnGetText :=
GetTextVacio;


Funciona de las mil maravillas, todos los controles que se asocien no importa de que tipo sean, su contenido siempre va a estar oculto, pero la información original no se pierde...

No cabe duda, el que sabe, sabe!!!

maeyanes
09-10-2007, 07:56:07
Pero ahí escondes el valor del campo, no el control, no? :p

Por lo que veo solo estás usando un evento de TField (que no conocía :p)...

Que bueno que encontraste la solución a tu problema... :)



Saludos...