PDA

Ver la Versión Completa : Parpadeo al llenar 30 ListBox


MartinHV
03-04-2019, 18:41:23
Hola estimados amigos.
Estoy realizando la carga de 30 ListBox de manera simultanea cada segundo.
El problema es que parpadean al terminar la carga, he intentado con la propiedad ListBox.Items.BeginUpdate/EndUpdate, pero
aún así el problema persiste.

He adicionado la instrucción LockWindowUpdate.

¿Alguna recomendación?, se los agradeceria mucho.

Saludos.

el-mono
03-04-2019, 20:24:25
La solucion profesional y mas adecuada para estos casos es implementar Hilos. aunque no comentas como lo estas haciendo ni de que manera.

MartinHV
03-04-2019, 20:43:57
La solucion profesional y mas adecuada para estos casos es implementar Hilos. aunque no comentas como lo estas haciendo ni de que manera.

Gracias por contestar "el-mono", aquí una descripción del problema.

Realizo el proceso en un timer que se ejecuta cada Segundo.
Se carga una consulta con N Cantidad de registros, los cuales son
acomodados en los 30 ListBox ( cada ListBox esta contenido dentro de un Panel, tanto como los ListBox y los Panel forman
parte de un arreglo)
Al finalizar el acomodo, habilito el "EndUpdate de los listBox afectados."

Bosquejo del Código

procedure TFExpo.Timer1Timer(Sender: TObject);
var
Tiempo:Double;
begin
try
Timer1.Enabled:=False;
//Query donde se obtienen los registro para llenar los ListBox
qExpo.Close;
qExpo.Params.ParamByName('FECHA').AsInteger:=gFecha;
qExpo.Params.ParamByName('IDLOCAL').AsInteger:=gIdlocal;
qExpo.Params.ParamByName('IDEXPO').AsInteger:=1;
qExpo.Open();

Gen.LockControl(Self,True);
Gen.BeginUpdate;
while not qExpo.Eof do
begin
//Código donde se llenan los ListBox
end;

finally
Gen.EndUpdate;
Gen.LockControl(Self,False);
Timer1.Enabled:=True;
end;
end;
//Clase donde se anexan rutinas
procedure TGenerico.LockControl(c: TWinControl; lock: boolean);
begin
if (c=nil) or (c.Handle=0) then exit;
if lock then
SendMessage(c.Handle,WM_SETREDRAW,0,0)
else
begin
SendMessage(c.Handle,WM_SETREDRAW,1,0);
RedrawWindow(c.Handle,nil,0,RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN);
end;
end;

procedure TGenerico.EndUpdate;
var M:Integer;
begin
for M := 1 to Limite-1 do
begin
LOrdenes[M].Items.EndUpdate;
LockControl(aPanel[M],False);
end;
end;

procedure TGenerico.BeginUpdate;
var M:Integer;
begin
for M := 1 to Limite-1 do
begin
LockControl(LOrdenes[M],True);
LockControl(aPanel[M],True);
LOrdenes[M].Items.BeginUpdate;
end;
end;

look
03-04-2019, 22:00:19
Hola, pon la propiedad del componente DoubleBuffered = True;

Saludos!

WHILENOTEOF
04-04-2019, 12:22:52
Hola, veo que paras el timer antes de rellenar, por lo que el proceso no se dispara antes de que se rellenen los listbox. Yo te propongo dos sugerencias:

- si puedes filtrar la información que recuperas cada segundo, para actualizar solo los cambios (no se si es el caso).
- pones todos los listbox en un panel, y antes de llenarlos pones panel.visible:= false y al terminar panel.visible:= true.


No se el código a nivel interno como funcina, pero el BeginUpdate y EndUpdate de la propiedad Items debe afectar a como se cargan las cadenas, pero no al dibujado del control. Podrías ver en el dibujado del control si puedes poner un flag para que no pinte con cada nueva adición y hacerlo todo al final, que sería lo esperado en un BeginUpdate - EndUpdate.

MartinHV
04-04-2019, 15:37:46
Hola, veo que paras el timer antes de rellenar, por lo que el proceso no se dispara antes de que se rellenen los listbox. Yo te propongo dos sugerencias:

- si puedes filtrar la información que recuperas cada segundo, para actualizar solo los cambios (no se si es el caso).
- pones todos los listbox en un panel, y antes de llenarlos pones panel.visible:= false y al terminar panel.visible:= true.


No se el código a nivel interno como funcina, pero el BeginUpdate y EndUpdate de la propiedad Items debe afectar a como se cargan las cadenas, pero no al dibujado del control. Podrías ver en el dibujado del control si puedes poner un flag para que no pinte con cada nueva adición y hacerlo todo al final, que sería lo esperado en un BeginUpdate - EndUpdate.

Gracias por contestar WHILENOTEOF, realizare tu sugerencia, y vere que efecto tiene. Saludos.

MartinHV
04-04-2019, 15:39:03
Hola, pon la propiedad del componente DoubleBuffered = True;

Saludos!

Gracias por contestar look, la propiedad ya la tengo habilitada, pero probare la sugerencia de WHILENOTEOF.

Saludos.