PDA

Ver la Versión Completa : ¿Cómo ocultar los botones de un componente "TCategoryButtons"?


dec
25-03-2015, 09:00:51
Hola a todos,

¡A ver si podéis echarme una mano con esto! Estoy utilizando un componente "TCategoryButtons" (http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.CategoryButtons) en cierto programa, y, me gustaría que se pudieran filtrar los botones para que sólo se mostrasen los que coincidiesen con aquello que busque el usuario. Es decir, suponiendo que tengo una lista de botones como:


Manolo
Pedrito
Francisco


... suponiendo que el usuario busque "Manolo", me gustaría que "Pedrito" y "Francisco" no apareciesen. El asunto no parece baladí, puesto que, cada botón de "TCategoryButtons" es un objeto "TButtonItem" (http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.CategoryButtons.TButtonItem_Properties), que, no cuenta con una propiedad "Visible" o similar. Es decir, puedo "recorrer" todos los botones del componente, pero, no puedo ocultarlos llegado el caso.

Estoy a punto de descartar que exista la posibilidad de hacer lo que quiero, sin embargo, me llama la atención que el propio IDE de Delphi (al menos en Delphi XE2 es así) muestra la paleta de componentes en un "TCategoryButton", al menos el programa WinSpy (http://www.catch22.net/software/winspy-17) indica que su clase se llama "TIDECategoryButtons", y, como sabéis, sí que es posible filtrar dicha lista de componentes...

¿Alguien se ha topado algún vez con este "problema"? ¿Y conoce la solución? ¿Y la quiere compartir? :D

¡Muchas gracias!

Neftali [Germán.Estévez]
25-03-2015, 10:37:39
Pues la verdad es que a primera vista no se ve forma de hacerlo.
He revisado un poco el código (imagino que igual que has hecho tú) y si hay forma de hacerlo no es trivial.
:confused::confused:

dec
25-03-2015, 12:25:03
Hola,

Gracias Germán. En efecto, al menos en un "TCategoryButtons" estándar, parece que no se contempla esa posibilidad. :(

jhonny
26-03-2015, 16:22:18
Caramba, después de voltear un poco buscando, aparentemente no hay una manera "usual" de hacerlo, si alguno la tiene, por favor dígalo...

Lo único que se me ocurrió fue simplemente liberar los botones que no coincidan con tu búsqueda, luego de recorrer los TButtonItem y luego crearlos en ejecución cuando sean requeridos.

Adecuando el siguiente código para la necesidad de "ocultar":

CategoryButtons1.Categories[0].Items[0].Free;

Y el del siguiente link para la necesidad de volver a "mostrar":

Código sacado de http://www.functionx.com/delphi/controls/categorybuttons.htm:

procedure TForm1.FormCreate(Sender: TObject);
var
SeriesOfButtons : TCategoryButtons;
Category : TButtonCategory;
btn : TButtonItem;
begin
SeriesOfButtons := TCategoryButtons.Create(Self);
SeriesOfButtons.Parent := Self;

SeriesOfButtons.Left := 8;
SeriesOfButtons.Top := 40;

Category := SeriesOfButtons.Categories.Add;

btn := Category.Items.Add();
end;

dec
26-03-2015, 16:50:16
Hola Jhonny,

Pensé en la solución que propones, pero, no está demás volver sobre ello. En un principio la descarté, porque, precisamente, digamos que aprovecho la posibilidad de preparar dichos botones en tiempo de diseño, desde el mismo IDE de Delphi. Sin embargo, si no hay más remedio (tal vez cambiar a otro componente que permita lo que queremos de forma "natural") sería cuestión de ver el desempeño final de dicha solución.

Gracias por responder Jhonny. Si decido hacerlo ya contaré cómo va el asunto. :)

jhonny
26-03-2015, 17:12:50
Hola Jhonny,

Gracias por responder Jhonny. Si decido hacerlo ya contaré cómo va el asunto. :)

Estaré atento :)

dec
25-05-2015, 23:52:07
Hola,

Bueno, pues, en efecto, nuestro amigo Jhonny iba bien encaminado. Parece claro que no pueden ocultarse botones de un "TCategoryButtons", pero, el control se comporta muy bien a la hora de crear las categorías y botones en tiempo de ejecución, de hecho parece preparado para algo así, de manera que resulta más o menos sencillo realizar el filtrado, una vez que podemos crear los elementos en tiempo de ejecución, basta con buscar por la cadena de búsqueda en el caption de un botón... antes de crearlo y añadirlo al control.

El quid está por tanto en tener una fuente desde la que que crear dichos elementos, por ejemplo, en mi caso se trata de sendos arrays estáticos, donde defino todas las acciones y todos los controles disponibles (véase la imagen de abajo) así como algunas de sus características, entre ellas su nombre, que es lo que me sirve a la hora de buscar o filtrar una determinada acción o control. En fin, que es posible hacer lo que me preguntaba al principio, siempre que no creemos las categorías y botones en tiempo de diseño, en todo caso, pudiendo recrearlos en tiempo de ejecución.

http://i.imgur.com/fMMpb11.gif

Tal vez incluso podríamos ir un poco más allá. Por ejemplo, yo creo que el propio Delphi utiliza este control (u otro similar) para su paleta de componentes, por ejemplo. Ahora bien, Delphi nos muestra "en negrita" el texto que estamos buscando o el filtro que estamos usando. Yo creo que esto podría hacerse utilizando algún evento "Draw" del "TCategoryButtons". Otra cosa que tengo que decir es que yo estoy filtrando sobre unos 100 elementos más o menos: no sé cómo se comportará con muchos más, pero, no pinta del todo mal.

Casimiro Notevi
26-05-2015, 00:15:22
... yo creo que el propio Delphi utiliza este control (u otro similar) para su paleta de componentes, por ejemplo. Diría que sí es ese mismo componente. Y se ve que va agil.

dec
26-05-2015, 01:51:36
Hola Casimiro,

Sí que se parecen ambos componentes, sí. De hecho se me olvidó comentar que las categorías de este componente cuentan con los métodos "BeginUpdate" y "EndUpdate", lo que evita "parpadeos". Lo cierto es que parece que el componente está hecho para algo así: no tanto para añadir categorías y botones en tiempo de diseño (que también), como para trabajar con ellos en tiempo de ejecución. De hecho en mi caso esto es hasta una ganancia extra: puesto que ya no tendré que ir añadiendo botones en tiempo de diseño, sino que al añadir acciones al "mapa de acciones", el componente mostrará las nuevas acciones sin más. Una ganancia colateral para variar. :)