No artigo anterior examinamos os principais recursos do FastGrid — o componente de grid para Delphi do pacote FastReport VCL. Agora vamos descer um nível e analisar a estrutura interna do componente: estudaremos as propriedades do grid e dos elementos visuais que o compõem, examinaremos o objeto View, as colunas, suas propriedades e eventos, e, no final, abordaremos brevemente a configuração do trabalho com dados.
Este material será útil para desenvolvedores Delphi e C++ Builder que usam o FastGrid como parte do FastReport VCL ou que apenas pretendem começar a dominá-lo.
O grid (TfrGrid) é o controle principal sobre o qual são posicionados todos os demais objetos que garantem o seu funcionamento. Praticamente todas as propriedades e eventos do componente são padrão e estão presentes na maioria dos controles da VCL. A exceção são dois eventos específicos do grid:
A adição e a remoção de diferentes Views no grid são feitas por meio do menu do componente. Ao criar o grid, um objeto View é adicionado automaticamente a ele.
Em tempo de design, o grid também exibe a legenda — uma pequena lista dos objetos localizados no grid. Nela há um menu disponível não apenas para o grid, mas também para os componentes (colunas) posicionados nele. Além disso, a legenda permite ativar rapidamente qualquer um desses componentes. Se a legenda não for necessária, ela pode ser removida definindo a propriedade ShowLegend := False do grid.
O objeto View é o elemento principal do grid responsável pela exibição do seu conteúdo. Os objetos View podem ser gerenciados por meio da legenda. No menu de cada View estão disponíveis as seguintes opções (no Unbound View algumas delas não estão presentes):
Ao trabalhar com controles complexos, você se depara constantemente com um grande número de propriedades do tipo Color e Font, além de propriedades como ParentFont. No FastGrid, todas essas propriedades ficam ocultas dentro da propriedade Appearance. Ela é composta por propriedades aninhadas, cada uma responsável pela aparência de uma determinada parte do grid.
Vamos examinar o funcionamento dessas propriedades usando como exemplo a Appearance.Data — ela é responsável pela aparência da área de dados do grid.
Como se pode ver na captura de tela, essa propriedade é composta por propriedades aninhadas do tipo BackgroundColor, FontColor, FontName e por um conjunto de sinalizadores na subpropriedade AssignedValues com os mesmos nomes. O princípio de funcionamento é o seguinte: por meio do AssignedValues indicamos quais das propriedades simples são aplicadas diretamente e quais são herdadas do objeto pai. Por exemplo, se definirmos AssignedValues.FontColor como True, ao alterar a cor da fonte do grid, a cor da fonte na área de dados não mudará.
As propriedades Appearance são usadas principalmente para configurar a fonte e a cor dos objetos que as contêm. Em outras palavras, elas substituem ParentColor, ParentFont e outras propriedades de comportamento semelhante, mas oferecem mais flexibilidade: parte dos parâmetros pode ser redefinida localmente, e o restante é herdado do grid.
Vamos verificar como isso funciona no projeto de demonstração do FastGrid. Abriremos no Delphi o projeto GridDemo.dpr — ele está localizado no menu Iniciar, na pasta "FastReport VCL Products", na subpasta "2026.2.0-Sources-Demos" (o número da versão no nome da pasta pode ser diferente; além disso, na IDE deve estar instalada uma versão do FastReport que inclua o FastGrid). Abriremos o módulo DataAwareDemo.pas e iremos para o formulário. Alteraremos algumas propriedades aninhadas da Appearance. O resultado foi este:
Agora definiremos diretamente no grid a propriedade Font.Name := 'Courier New'. Essa fonte foi escolhida por questão de clareza. A aparência do grid ficará assim:
Vemos que a fonte mudou em todos os elementos de texto do grid, mas a cor e os atributos permaneceram os mesmos. Já na coluna City a fonte não sofreu alteração — nós a definimos diretamente na coluna. Essa abordagem permite gerenciar a exibição do conteúdo do grid com mais flexibilidade. Vale notar: por padrão, todos os AssignedValues estão definidos como False, ou seja, os valores de quase todos os parâmetros são obtidos do grid.
Todas as propriedades do objeto View estão agrupadas em vários grupos.
Active — permite definir a atividade da View atual.
Appearance — define a aparência do objeto View. Se no AssignedValues o parâmetro correspondente estiver definido como False, o valor é obtido diretamente do grid:
DataController — propriedade que define o acesso aos dados. Examiná-la-emos com mais detalhes no próximo artigo.
OptionsBehavior — define o comportamento do grid. Propriedades aninhadas:
OptionsCustomization — permite ao usuário determinadas operações: filtragem, agrupamento e ordenação dos dados; ocultação, movimentação e redimensionamento das colunas, entre outras. Essas operações podem ser sobrepostas pela propriedade análoga de cada coluna.
OptionsData — permite ao usuário realizar operações com os dados do grid: inserção, adição, exclusão e edição.
OptionsDataNavigator — permite configurar o navegador de dados: sua posição, seu encaixe nas laterais do grid, bem como o tamanho dos botões, sua aparência e o conjunto de botões exibidos.
OptionsView — permite configurar a aparência do grid. Vamos examinar alguns subpropriedades com mais detalhes:
Os objetos View também podem ser manipulados por código. Um novo objeto pode ser criado com a seguinte construção: frGrid.Views.CreateView(TfrGridTableView).
Para removê-lo, exclua a View da lista de Views do grid (frGrid.Views.Remove(View)) ou simplesmente chame View.Free. Se for necessário alternar programaticamente para outra View, basta definir nela View.Active := True.
É possível determinar a coluna atualmente ativa da View por meio da propriedade View.Controller.FocusedColumnIndex.
O objeto View oferece uma grande quantidade de eventos que o programador pode utilizar: tanto os padrão, como o OnKeyDown, quanto os específicos do grid — a finalidade deles, em geral, fica clara pelos nomes. Um aspecto interessante do conjunto de eventos da View (e não apenas dela) é a presença, em alguns eventos, do parâmetro var AAllow: Boolean. Ao definir esse parâmetro como False no manipulador do evento, o programador pode facilmente impedir uma ou outra ação. Por exemplo, se o definirmos no manipulador do OnEditing, impediremos a passagem da célula atual para o modo de edição.
Vamos examinar alguns dos eventos da View com mais detalhes.
Esses eventos têm elementos em comum. Em todos os manipuladores, o parâmetro AItem é uma referência à coluna da tabela, e ARowIndex é o número da linha de dados no DataController vinculado ao grid.
A View contém um conjunto de colunas. As colunas podem ser adicionadas tanto no editor de formulários da IDE quanto em tempo de execução do programa. Vamos examinar as principais propriedades da coluna.
Appearance — define a aparência da coluna:
Caption — cabeçalho da coluna.
DataBinding — propriedade que define a vinculação dos dados à coluna. Será examinada com mais detalhes adiante.
GroupIndex, MergedGroupIndex — o índice do grupo ao qual a coluna pertence e o índice da coluna nesse grupo. Por padrão, são iguais a -1 (a coluna não pertence a nenhum grupo). Alterando essas propriedades, é possível gerenciar diretamente o agrupamento no grid — criar e excluir grupos. Se a exibição da área de agrupamento estiver permitida, o usuário em tempo de execução pode criar e excluir grupos por conta própria: basta arrastar o cabeçalho da coluna para a área de agrupamento. A coluna, nesse caso, desaparece da lista de visíveis, mas os dados no grid ficam agrupados pelo valor do campo dessa coluna. Vale notar que o grid sempre executará a ordenação por essa coluna.
O agrupamento pode ser multinível — basta arrastar os cabeçalhos desejados das colunas. E se arrastar o cabeçalho de uma coluna mantendo a tecla Ctrl pressionada, é possível criar um grupo baseado em várias colunas. Se o agrupamento não for mais necessário, arraste o cabeçalho da coluna da área de agrupamento de volta ao grid.
Index — o índice visível da coluna na tela. Alterando essa propriedade, é possível modificar diretamente a posição da coluna no grid.
MinWidth — a largura mínima da coluna. Atenção: por padrão, esse valor não é 0, mas 20.
Options — essa propriedade permite configurar exatamente quais ações o usuário pode realizar com a coluna: colocá-la no modo de edição, filtrar pelos dados da coluna, agrupar, ocultar a coluna, redimensioná-la, movê-la, alterar os dados da coluna, ordenar, além de exibi-la na lista de colunas. Como se vê, essa lista de ações é praticamente análoga à que se encontra em View.OptionsCustomization.
Properties — por meio dessa propriedade é possível definir o editor a ser usado na coluna. Se a propriedade não for definida, o grid tentará escolher um editor com base no tipo de dados da coluna. E se atribuirmos a essa propriedade um valor da lista suspensa, depois será possível expandi-la e configurar as propriedades do editor definido. Os editores serão examinados em detalhes em um artigo separado. Por enquanto, vale notar que o editor é responsável não apenas pela edição do valor de uma única célula, mas também pela exibição dos valores de toda a coluna. Os editores também estão disponíveis como componentes independentes. Note que o acesso às propriedades do editor é possível apenas quando o editor é definido explicitamente: para os editores padrão, não existe a possibilidade de configurar propriedades.
SortOrderIndex, SortOrder — com essas propriedades é possível definir a ordenação dos campos do grid. O campo SortOrderIndex é responsável pela prioridade do campo na ordenação: primeiro é feita a ordenação pelo campo com SortOrderIndex = 0; se os valores dessa coluna coincidirem, ordenamos pela coluna com SortOrderIndex = 1. Se definirmos SortOrderIndex = -1, a ordenação por essa coluna não é realizada.
A propriedade SortOrder define a direção da ordenação: soNone — sem ordenação, soAscending — ordenação crescente, soDescending — decrescente. Note que o usuário pode definir a ordenação das colunas também em tempo de execução: basta clicar com o botão esquerdo do mouse no cabeçalho da coluna. Ao clicar novamente, a direção da ordenação mudará para a oposta. A ordenação será executada pela coluna cujo cabeçalho foi clicado. Para cancelar a ordenação, basta clicar no cabeçalho da coluna mantendo a tecla Ctrl pressionada. E se, ao clicar, mantiver a tecla Shift pressionada, é possível ordenar imediatamente por várias colunas.
Uma coluna pode ser criada por código por meio do método View.Columns.CreateColumn. Para definir o editor dela, atribua à propriedade Column.PropertiesAlias uma cadeia de caracteres com o nome do editor ou defina na propriedade Column.PropertiesClass o tipo de classe do editor.
É possível limpar a lista de colunas da View com o método View.Columns.Clear. As propriedades Columns.VisibleCount e Columns.VisibleItems também podem ser úteis — por meio delas é possível acessar apenas as colunas visíveis, e as próprias colunas nessa lista ficarão ordenadas de acordo com a sua posição na tela.
Vamos examinar os eventos da coluna de dados. Como já mencionado, alguns eventos da coluna são análogos aos eventos da View.
Para encerrar o artigo, examinaremos brevemente a configuração do grid para o trabalho com dados no nível de definição de propriedades. Como já sabemos, o grid pode trabalhar com dados em dois modos: DB e Unbound.
No modo DB, o grid se vincula aos dados usando o componente padrão TDataSource, de maneira semelhante ao que faz, por exemplo, o componente padrão TDBGrid. Após definir, no Object Inspector (inspetor de objetos), View.DataController := 'DB', é possível expandir essa propriedade e indicar o TDataSource desejado. Depois de definir o DataSource, pode-se percorrer as colunas e, na propriedade DataBinding.FieldName de cada coluna, indicar o nome do campo de dados desejado. A propriedade DataBinding.FieldType não pode ser alterada — o seu valor é obtido do campo de dados vinculado do DataSource.
No modo Unbound, o grid funciona de maneira um pouco diferente. Após definir View.DataController := 'Unbound', o grid passa ao modo de trabalho com os dados armazenados no próprio grid. Para definir as colunas do conjunto de dados, primeiro é preciso criá-las — por exemplo, a partir do menu de contexto da View na legenda — e depois ir aos objetos de colunas e definir, no campo DataBinding.FieldName de cada coluna, o nome do campo de dados e, no campo DataBinding.FieldType, o tipo do campo de dados. Depois disso, no armazenamento interno do grid é criado o conjunto de campos correspondente, com o qual é possível trabalhar.
Examinamos a estrutura interna do FastGrid: o papel do grid como controle básico, o objeto View e suas propriedades, o mecanismo Appearance com a subpropriedade AssignedValues, as colunas com suas configurações e eventos, além dos dois modos de trabalho com dados — DB e Unbound. Isso é suficiente para configurar a aparência e o comportamento do grid tanto em tempo de design quanto por meio do código.
Resta a última grande questão — o trabalho com dados: DataController, vinculação do DataSource, edição e navegação pelos registros. É exatamente ela que examinaremos detalhadamente no próximo artigo da série.