Esse tema remete a vários problemas de programação, uma lista extensa que não cabe aqui explorar, mas o que mais me interessa nesse instante é a apresentação dessa estrutura nova, em uma situação em que não sabemos de antemão quais atributos deverão ser apresentados ao usuário.
Portanto, separemos o tema em dois, o armazenamento e em seguida a apresentação, e exploremos somente este último, por enquanto.
Grid Dinâmico
O controle Grid é um dos componentes mais utilizados e importantes na interface Genexus, e isso é facil de explicar porque, pois o mesmo é um mecanismo que se encarrega de selecionar, filtrar, apresentar, pesquisar informações armazenadas em uma tabela dita estendida, ou seja, a partir de uma determinada tabela base, todas as relacionadas N-1 a essa, em modo cascata, ou seja, atingindo aos niveis mais baixos e distantes do diagrama com um unico controle. Quer mais?
Infelizmente, tem um 'defeito', opera sob o modelo conceitual Genexus e claro, somente com as regras definidas pelo Genexus, atributos, tabelas pertencentes a esse modelo conceitual, em outras palavras, para 99,9% dos casos atende sem maiores dificuldades pois Genexus opera de forma muito eficaz em modo comportado.
Não sei a respeito dos seus problemas de programação, mas de vez em quando enrosco nesse 0,1% da estatística, com situações onde o modelo comportado não atende, ou mesmo, por pura frescura, desejo apresentar uma interface diferente para o usuário. Vamos assumir essa segunda possibilidade, ok.
Como fazer então? para um grid tradicional é necessário um atributo previamente criado em alguma estrutura de transação, é necessário colocar esses atributos nas colunas do grid, e isso somente pode ser realizado em modo design? A resposta: gxuiGrid.
gxuiGrid x gxuiGridExtension
Genexus implementa o grid do tipo gxui em duas formas distintas, o gxuiGrid tradicional, e o gxuiGridExtension, este ultimo trata de converter um grid tradicional Genexus no padrão visual do gxui, o resultado é ótimo em ambos os casos.
Existe no entanto uma diferença significativa entre os componentes: colunas dinâmicas e mecanismos tradicionais de carga e recuperação.
gxuiGrid
|
gxuiGridExtension
|
|
colunas dinâmicas |
sim
|
nao
|
conteúdo dinâmico |
sim
|
sim
|
evento Refresh |
não
|
sim
|
evento Load |
não
|
sim
|
for each line |
não
|
sim
|
Vamos ao Exemplo
Seguindo a linha do Genexando vamos a um exemplo simples para não complicar muito a vida. De quebra, vamos carregar um gxuiGrid com um conjunto variável de dados. No exemplo, temos uma tabela, Estrutura, e na mesma diversos atributos (Titulo, CampoNome, Width, Hidden), que armazenam a composição desejada no gxuiGrid. Essa tabela é responsável por manter a estrutura do Grid.
if &tam > 0
&gxuicoluna = new()
endif
&gxuicoluna.header = EstruturaTitulo.Trim()
&gxuicoluna.dataIndex = EstruturaCampoNome.Trim()
&gxuicoluna.width = EstruturaWidth
&gxuicoluna.css = 'font-size:12px; color:#000000;'
&gxuicoluna.dataType = gxuiDataType.string
if EstruturaHidden =1
&gxuicoluna.hidden = gxuiBoolean.True
else
&gxuicoluna.hidden = gxuiBoolean.False
endif
&gxuiGridColumnModel.Columns.Add(&gxuicoluna)
&tam = 1
endfor
Para que funcione direitinho, carregue a tabela Estrutura com a definição dos campos que deseja colocar no Grid. No exemplo, utilizei no campo EstruturaCampoNome nomes simples como Coluna01, Coluna02, ... e por ai vai. A variável &gxuicoluna do tipo gxuiGridColumn, é utilizada para carregar a coleção de colunas em &gxuiGridColumnModel. Veja que para simplificar poderiamos utilizar aqui um DataProvider, mas propositalmente coloquei em um for...each, para exercitar um pouco a respeito de coleções.
&gxuiGridDataItem.Coluna01 = str(&it * 1)
&gxuiGridDataItem.Coluna02 = str(&it * 2)
&gxuiGridDataItem.Coluna03 = str(&it * 3)
&gxuiGridDataItem.Coluna04 = str(&it * 4)
&gxuiGridDataItem.Coluna05 = str(&it * 5)
&gxuiGridData.Itens.Add(&gxuiGridDataItem)
&gxuiGridDataItem = new()
endfor
Conclusão
Para quem está acostumado com a normalidade do Grid tradicional do Genexus, o gxuiGrid assusta um pouco, mas veja que vale a pena estudá-lo, dá pra pensar quantas excelentes oportunidades ele abre? de fato o controle é legal mesmo, portanto só nos resta agradecer ao pessoal da Artech pelo esforço para disponibilizá-lo para nós.
Quer aprender mais? instale a kb do RSSReader, disponivel no gxserver, e veja também como funciona o gxuiGridExtension
3 comentários:
Legal, Douglas, Parabéns!
Tenho uma dúvida, em determinada parte vc diz "O segredo é ter uma coleção em que os nomes dos itens coincidam com os nomes das colunas definidas para o gxuiGrid, como por exemplo o SDT abaixo."
Mas se a ideia é ter colunas dinâmicas, como saberei de antemão para informar no SDT?
Grande Bruno,
Como o gxuiGridData é baseado em um SDT para definição das colunas e seus dados, devemos definir o mesmo um com o numero de colunas que se pressupõe necessário, mesmo que não saibamos de antemão o que o usuário vai escolher para apresentar, podendo haver colunas a mais que a sua necessidade (Infelizmente não temos a estrutura do SDT dinâmica). As colunas que não forem utilizadas, poderão não ser apresentadas no controle, somente as que possuirão dados.
No exemplo optei por um SDT com colunas com nomes Coluna01, ..., sem muita relação com a informação a ser apresentada. E o for...each em seguida, carregou com informações essas colunas. Aqui você poderia, por exemplo, utilizar um DataProvider, ou mesmo acessar certa tabela com dados e carregar nas Coluna01, Coluna02,...
Tecnicamente, você teria uma lista de informações à disposição do usuário, e em seguida carregaria essas informações de suas tabelas, cálculos, ou qualquer outro meio, para o SDT.
No meu caso, utilizei o recurso associado a uma fonte de dados variável, ou seja, o mesmo Grid/Interface foi utilizado para mostrar informações de diversas consultas distintas, providas por diversos DataViews.
Respondi?
Obrigado pela pergunta.
Ab
Oi Douglas, você sabe como faz para ver quais linhas da grid foram selecionadas? Eu alterei a propriedade SelectionModel para checkbox e SingleSelect para false, mas não consegui descobrir como fazer para retornar quais linhas foram selecionadas
Postar um comentário