Você está na página 1de 32

novembro 2012

novembro 2012

ndice
Editorial

04
C#

Delphi Parte VIII

Autor: Luciano Pimenta

05

12

FireMonkey - Formulrio base de cadastro com barra


de ferramentas - Parte I

Autor: Lucas de
Oliveira

Android

Linguagem C# - Criando um Componente TextBox


personalizado

Autor: Marcos C.
Silva

Delphi

Delphi

18

24

Android - Aprendendo a utilizar o ListView

Autor: Thiago C.
Montebugnoli

Desafio The Club

Dicas

28

Legenda

30

Iniciante
Intermedirio
Avanado
novembro 2012

03

Bem-vindo
Ol amigos do The Club, no final do ms de Outubro aconteceu
a to esperada Embarcadero Delphi Conference.
Ns estivemos por l prestigiando este grande evento e pudemos
assistir a vrias palestras. Para compartilhar com vocs, nesta edio,
estamos trazendo um pequeno artigo onde podero conferir mais
detalhes a respeito desta Conferncia.
A revista deste ms conta ainda com outros artigos: nosso consultor tcnico Lucas de Oliveira continua com a srie de artigos
relacionados ao FireMonkey, onde aborda como trabalhar com um
formulrio base de cadastro com barra de ferramentas, procurando
exemplificar passo a passo para um maior aprendizado.

Av. Prof Celso Ferreira da Silva, 190


Jd. Europa - Avar - SP - CEP 18.707-150
Informaes e Suporte: (14) 3732-1529

Internet

http://www.theclub.com.br
Cadastro: cadastro@theclub.com.br
Suporte: suporte@theclub.com.br
Informaes: info@theclub.com.br
Skype Cadastro: theclub_cadastro
Skype Suporte: theclub_linha1
theclub_linha2
theclub_linha3

www.twitter.com/theclubbr

Marcos Csar Silva nos ensina a criar um componente TextBox


personalizado, colocando em prtica vrios conceitos importantes
da Linguagem C# como Herana e Sobrescrita de Mtodos.
J nosso colaborador mensal Luciano Pimenta prossegue com
os artigos relacionados ao Delphi, sendo que nesta Oitava parte
descreve conceitos primordiais aos desenvolvedores, teis tanto
para os iniciantes quanto para os mais experientes.
Para finalizar, continuo com a srie de artigos relacionados ao
Android. Para quem est comeando, no deixem de l-lo, pois
trata-se de um dos mais importantes componentes: o ListView,
recurso indispensvel no desenvolvimento para esta plataforma.
Aproveite tambm e desfrute de nossa clssica seo de Dicas
Delphi.
Desejo a todos uma boa leitura e um Forte abrao,

Copyright The Club 2012


Diretor Tcnico
Marcos Csar Silva
Diagramao
Eduardo Massud
Arte
Vitor M. Rodrigues
Reviso
Cntia Amaral
Colunistas
Marcos Csar Silva
Thiago Cavalheiro Montebugnoli
Lucas de Oliveira
Luciano Pimenta

Impresso e acabamento:
GRIL - Grfica e Editora
Taquarituba-SP - Tel. (14) 3762-1345
Reproduo

Thiago Montebugnoli - Editor Chefe


thiago@theclub.com.br

04

novembro 2012

A utilizao, reproduo, apropriao, armazenamento em banco


de dados, sob qualquer forma ou meio, de textos, fotos e outras
criaes intelectuais em cada publicao da revista The Club
Megazine so terminantemente proibidos sem autorizao
escrita dos titulares dos direitos autorais.
Delphi marca registrada da Embarcadero Technologies,
as demais marcas citadas so registradas
pelos seus respectivos proprietrios.

DELPHI

Embarcadero Delphi Conference 2012

O The Club esteve l!


rimeiramente gostaria de parabenizar toda a equipe do evento pela organizao e estrutura oferecida aos desenvolvedores ali presentes. O evento
aconteceu tera-feira, no dia 23 de Outubro em So Paulo no Centro de Convenes Rebouas. Para quem no conhece ou no sabe, este um
evento Oficial promovido pela prpria Embarcadero e no gera custo algum pela participao da pessoa interessada. O evento disponibilizou 5
salas simultneas de palestras, contendo no total de 29 palestras e 2 minicursos. Discutirei um pouco sobre as palestras que assistimos e logo
em seguida citarei todos os tpicos da conferncia.

No primeiro horrio escolhemos para assistir a palestra de abertura do Senhor David I e Michael Swindell, tendo como ttulo Indroducing HTML 5 Builder. Foram discutidas diversas caractersticas desta nova ferramenta que tem como objetivo customizar aplicaes das plataformas (Android, Mac, Windows)
utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas sero utilizadas por poucas
pessoas e em um prazo muito longo de tempo por no se tratar de ferramentas indispensveis para a maioria dos desenvolvedores.
Samuel David fala sobre a integrao do Google Maps usando o Delphi XE 3. Discute um pequeno exemplo para aplicaes desktop utilizando um componente chamado TChromium. Particularmente achei interessante esta integrao de uma forma rpida e prtica, demonstrando algumas das funcionalidades
do XE 3 com o Google.
J Guinther Pauli, tendo como ttulo de sua palestra Aplicaes Corporativas para Web com Asp.Net, discutiu uma boa parte do tempo sobre as evolues
do Asp.Net, falou um poucos das verses do Framework, dando dicas e macetes para a platia. O assunto principal desta palestra foi o uso do Delphi Prism,
o mesmo utiliza a linguagem Oxygen junto com uma Ide de desenvolvimento do Visual Studio da Microsoft. Esta palestra se tornou um pouco cansativa pelo
fato de envolver tecnologias j existentes a um bom tempo na linguagem C# por exemplo, ficando como um conhecimento a mais para quem j trabalha com
o bom e velho Delphi.
Na quarta palestra, ministrada pelo Dormevilly Tertius, com o nome ER/Studio Ecosystem: Modelagem, ETL, Repositrio e Portal foram abordados vrias
funcionalidades do ER/Studio, ferramenta responsvel pela modelagem lgica e fsica de sistemas. O palestrante montou exemplos prticos e de fcil entendimento envolvendo ETL (Extract, Transform and Load), auditoria de informaes, entre outros, proporcionando aos ouvintes o conhecimento um pouco mais
avanado dos recursos oferecidos.
Com a chegada do Windows 8 no poderamos deixar de
conferir como fica a situao do desenvolvedor envolvendo
novas tecnologias, e isto que Kelver Merlotti nos demonstra
em sua palestra Desenvolvendo para Windows 8. Utilizando
o XE 3, sendo totalmente compatvel com esta verso do
Windows, ele monta pequenos exemplos das funcionalidades
destas duas tecnologias.
Bem, estas foram algumas das palestras que o The Club
assistiu e por isso procurei escrever um pouco sobre elas.
Novamente ressalto que o evento estava coberto por timos
palestrantes e representantes que nos propuseram a ensinar
e apresentar novos recursos do novo Delphi XE 3. Conhecemos tambm outras ferramentas como o HTML Builder 5, e
recursos novos como: Aplicaes em Windows 8, Aplicaes
para Mac, Android, Windows Phone, Aplicaes para Web
entre outras.
Logo abaixo segue o site oficial com as palestras, seguindo por seus palestrantes e separadas por sala.
http://www.delphiconference.com.br/

Um forte abrao e at a prxima Embarcadero Delphi


Conference.

Imagem 01: Auditrio Principal.


novembro 2012

05

Delphi
Parte VIII
Vimos no artigo anterior, um pequeno exemplo de como a POO pode
ajudar a construir aplicaes cliente-server no Delphi de forma eficiente
e de qualidade. Neste artigo, ainda continuaremos vendo POO, onde
mostrarei como criar um controle VCL no Delphi.Nas partes III e IV, vimos
alguns componentes da VCL e para nossa alegria, podemos criar nossos
prprios componentes. Isso mesmo, podemos criar componentes do
zero ou estender algum existente. O que vou mostrar neste artigo,
um componente simples, para localizar dados, que pode ser modificado
de acordo com a necessidade do desenvolvedor.
Para aplicaes terem performances, sempre bati na tecla da parametrizao de dados, ou seja, os dados que so mostrados em tela devem ser a
06

novembro 2012

menor quantidade possvel, como j vimos no decorrer da nossa srie, usando


herana visual de formulrios.
Em uma aplicao, a quantidade de consultas auxiliares bastante grande, ou seja, pesquisa de clientes, fornecedores, produtos etc, alm de serem
utilizadas em vrios locais da aplicao.
Criar um formulrio de consulta para cada uma das pesquisas torna-se trabalhoso, ento por que no criar um componente para essas consultas. Nossa
aplicao, cada cadastro tem uma aba com pesquisa para o respectivo cadastro.
Mas vamos imaginar que uma pesquisa de cliente, pode ser feita em outros
locais. Como faramos? A criao de um componente de pesquisa visa corrigir
esse problema, para no criarmos vrias telas de pesquisa.

Inciando a construo
Primeiramente, precisamos criar um pacote. Mesmo usando o Delphi XE2,
voc pode usar qualquer verso do Delphi para criar o componente. Clique
em File>New>Other e acesse o item Package (Imagem 1).

procedure Buscar;
function GetCodigo: integer;
property DataSet: TClientDataSet;
property SQLCodigo: string;
property SQLDescricao: string;

Nota: Caso deseja, voc pode criar uma coleo para ter vrios tipos
de pesquisa, como por exemplo, a propriedade Collumns do DBGrid. De
acordo com essa coleo, dinamicamente, voc poderia criar os itens
do RadioButton da tela anterior. Fica como pesquisa para incrementar
o componente.
No cdigo anterior, criamos a assinatura de um mtodo que ser responsvel por realizar a consulta (Buscar) e uma funo, para retornar o cdigo
retornado pela consulta. Alm disso, temos que criar uma propriedade do tipo
TClientDataSet, responsvel por ter os dados da consulta.

Imagem 1. Criando o pacote do componente


Salve o pacote com o nome de pkLocalizar. dproj.

Criando o formulrio
Teremos de criar o formulrio de pesquisa, que deve conter os controles
de tela para digitar o texto, boto de pesquisa e um grid onde sero mostrados
os dados, alm de um DataSource que ser vinculado a um DataSet. Voc pode
incluir componentes de sua necessidade.
Nossa tela de pesquisa ter dois filtros: um para pesquisa pelo cdigo,
outro para pesquisa por uma descrio (nome, titulo etc). Crie um novo
formulrio no pacote e adicione os controles, veja na Imagem 2 como ser o
formulrio de pesquisa.

Caso deseja, mude para o controle que utiliza para trabalhar com dados
locais (IBQuery, Query etc). As outras duas propriedades indicam o cdigo
SQL para a consulta por cdigo ou por descrio, assim basta conImagemr a
propriedade do Localizar, para ter a consulta parametrizada no componente.
O cdigo do Buscar, simplesmente, repassa pro ClientDataSet o valor do
Edit (edtLocalizar), onde o usurio digitar o valor de busca. No caso, temos que
verificar qual o tipo de filtro escolhido pelo usurio, para poder conImagemr
no DataSet o respectivo comando SQL da Listagem 1.
Listagem 1. Verificando o filtro escolhido

FDataSet.Close;
if (rgLocalizar.ItemIndex = 0) then
begin
FDataSet.CommandText := FSQLCodigo;
FDataSet.Params[0].AsInteger :=
StrToInt(edtLocalizar.Text);
end
else
begin
FDataSet.CommandText := FSQLDescricao;
FDataSet.Params[0].AsString := % +
edtLocalizar.Text + %;
end;
FDataSet.Open;

O cdigo do GetCodigo, para retornar o campo chave da tabela, bastante


simples, onde retornamos o primeiro campo (Field) do ClientDataSet.
Imagem 2. Formulrio de pesquisa
No cdigo do formulrio devemos criar alguns mtodos e propriedades,
conforme o cdigo a seguir:

Result := DataSet.Fields[0].AsInteger;

novembro 2012

07

Claro, precisamos indicar o campo chave na consulta SQL (propriedades


SQLCodigo e SQLDescricao) para que seja o primeiro registro. Ao apertar
CRTL+C, o Delphi cria o manipulador para a propriedade DataSet. O cdigo
do SetDataSet fica conforme o cdigo a seguir:

Apenas lembrando que o formulrio genrico, deve atender a qualquer


tipo de consulta, ento, devemos pensar sempre no mais comum para o
formulrio.

Codificando o formulrio
if FDataSet <> Value then
begin
FDataSet := Value;
DataSource1.DataSet := FDataSet;
end;

No cdigo, atribumos para a propriedade DataSet do DataSource, o valor


passado. Assim, ao conImagemrmos a propriedade no Object Inspector, o
DataSet vinculado ao DataSource. Como teremos apenas duas colunas no
grid, podemos configur-las via cdigo para que fiquem com um tamanho
especifico, fonte etc.
Para isso, criamos um mtodo que realiza essa funcionalidade. Veja na
Listagem 2.

Para os botes, que vo indicar se devemos confirmar o item selecionado


no DBGrid ou cancelar o formulrio (fechando-o), devemos chamar o Close,
e a seguir, conImagemr o ModalResult, que para o boto OK, ser mrOK e
Cancelar como mrCancel.
Veremos adiante, o motivo de usarmos o ModalResult. No evento OnDblClick do DBGrid, devemos usar o mesmo cdigo do boto OK, apenas
verificando antes se existem registros na consulta, verificando a propriedade
RecordCount do FDataSet. Assim, o usurio pode dar um duplo clique no grid
e o mesmo ser fechado.
No OnDataChange do DataSource, vamos habilitar o OK, apenas se existirem registros no ClientDataSet, ou seja, mais uma validao que fizemos para
no termos problemas com o componente:

Listagem 2. Mtodo para conImagemr as duas colunas do grid.


btnOk.Enabled := FDataSet.RecordCount > 0;
var
i : integer;
begin
{ conImagem as duas colunas do Grid}
if Assigned(FDataSet) then
begin
grdLocalizar.Columns[0].Title.Caption
:= Cdigo;
grdLocalizar.Columns[1].Title.Caption
:= DescrColumn;
for i := 0 to 1 do
begin
grdLocalizar.Columns[i].Title.Font.
Name := Verdana;
grdLocalizar.Columns[i].Title.Font.
Style := [fsBold];
end;
grdLocalizar.Columns[0].Title.Alignment
:= taCenter;
grdLocalizar.Columns[0].Alignment :=
taCenter;
grdLocalizar.Columns[0].Width := 70;
grdLocalizar.Columns[1].Width := 520;
end;
end;

O valor do Width ser de acordo com o tamanho do Grid que voc especificar. Entende-se que duas colunas so necessrias, pois vamos, em quase sua
totalidade, retornar apenas cdigo e uma descrio, mas voc pode adaptar
para retornar quantas colunas quiser.
08

novembro 2012

Para finalizar o formulrio, precisamos tratar o evento OnKeyPress do


edtLocalizar, usando o cdigo da Listagem 3.
Listagem 3. Cdigo do OnKeyPress do Edit

{ se apertou ENTER, realiza a busca }


if key = #13 then
if edtLocalizar.Text <> then
begin
if Assigned(FDataSet)then
begin
Buscar;
grdLocalizar.SetFocus;
StatusBar1.SimpleText := Format(
%d registro(s) encontrado(s) com
%s,
[FDataSet.RecordCount,
edtLocalizar.Text]);
Key := #0;
end;
end;

No cdigo anterior, primeiramente, verificamos se foi apertado a tecla


ENTER. Aps, verificamos se o Edit no est vazio, isso bom para que uma
pesquisa muito grande no seja executando, trazendo lentido ao sistema.
Poderamos ainda, colocar uma quantidade mnima de caracteres a
serem digitados para que o usurio chegue o mais perto possvel do que
est procurando. Aps verificarmos se a propriedade DataSet no est vazia,

chamamos o Buscar, conImagemmos o foco para o DBGrid e adicionamos uma


mensagem na StatusBar, com a quantidade de registros encontramos com o
valor digitado no Edit.
O key := #0, no emite o bip caracterstico do sistema operacional. Com
essa conImagemo, o formulrio de consulta est pronto. Alguns retoques a
mais poderiam ser feitos, como conImagemr as colunas do DBGrid para que
fiquem centralizadas pelo cdigo e alinhadas a esquerda com o texto.
Quando o usurio apertar ESC, podemos fechar o formulrio, ou ainda,
quando o usurio apertar ENTER no DBGrid o mesmo fechar como se fosse
clicado o boto OK. Isso so funcionalidades simples, que deixarei a cargo do
leitor, mas a verso para download possui essas funcionalidades.

FDataSet write SetDataSet;


property
SQLCodigo: string read FSQLCodigo write
SetSQLCodigo;
property
SQLDescricao: string read FSQLDescricao
write SetSQLDescricao;
end;
procedure Register;
implementation

Criando o componente
Agora, precisamos criar uma unit, que receber mais propriedades que
sero repassadas ao formulrio no momento de sua criao em memria,
assim como tambm fazer o registro do componente no Delphi.

procedure Register;
begin
RegisterComponents(Luciano Pimenta,
[TLocalizar]);
end;

Crie uma nova unit e adicione o cdigo da Listagem 4.


Listagem 4. Unit do componente

unit uLocalizar;
interface
uses Classes, Forms, DB, Dialogs,
ufrLocalizar, Graphics, Controls,DBClient;
type
TLocalizar = class(TComponent)
private
FDataSet: TClientDataSet;
FFormLocalizar: TfrLocalizar;
FSQLDescricao: string;
FSQLCodigo: string;
procedure SetDataSet(const Value:
TClientDataSet);
procedure SetSQLCodigo(const Value:
string);
procedure SetSQLDescricao(const Value:
string);
protected
procedure Notification(AComponent:
TComponent;
Operation: TOperation); override;
public
function Execute: Boolean;
function ReturnValue: integer;
published
property DataSet: TClientDataSet read

No cdigo, criamos uma classe TLocalizar, descendente de TComponent. Na


seo private temos variveis, uma referente a propriedade publicada DataSet
(seo published) que teremos e outra referente ao formulrio criado neste
artigo, e ainda as variveis referentes as propriedades SQL.
O SetDataSet conImagem a propriedade e sua implementao bem simples, onde apenas precisamos conImagemr a propriedade DataSet e verificar
se o formulrio est criado, atravs do FFormLocalizar. As propriedades dos
comandos SQL tambm so simples, basta conImagemr as mesmas como a
padronizao de propriedades.
Na seo protected, precisamos implementar o Notification, que
responsvel, por atribuir nil a propriedade DataSet, quando por exemplo o
ClientDataSet associado a mesma, por excludo.
Isso evita erros no IDE do Delphi. Sua implementao usa o seguinte cdigo:

inherited;
if Operation = opRemove then
if AComponent = FDataSet then
FDataSet := nil;

Continuando o cdigo da Listagem 4, na seo public temos duas funes.


A primeira, Execute, indicar se houve algum registro escolhido no formulrio,
assim podemos repassar para a consulta principal, o valor do registro.
A segunda retorna o valor da chave primria do registro escolhido no
grid do formulrio, onde simplesmente, chama o GetCodigo da varivel
FFormLocalizar.
Por fim, o Register (abaixo de implemetation), registra na Component
Pallete do Delphi, onde passamos como parmetro o nome, a paleta e a classe
do componente.
novembro 2012

09

Chamando o formulrio de pesquisa


O Execute, o principal mtodo do nosso componente. Ele se comporta
semelhante ao Execute dos controles Dialogs do Delphi, ou seja, retornado
true se foi escolhido um registro na consulta. Na Listagem 5, temos a implementao do mtodo.
Listagem 5. Mtodo Execute

if not FDataSet.Active then


FDataSet.Active := True;
FFormLocalizar := TfrLocalizar.
Create(nil);
try
FFormLocalizar.DataSet := FDataSet;
FFormLocalizar.SQLCodigo := FSQLCodigo;
FFormLocalizar.SQLDescricao :=
FSQLDescricao;
FFormLocalizar.ShowModal;
Result := FFormLocalizar.ModalResult =
mrOk;
finally
FFormLocalizar.Free;
end;

Colocando um cone no componente


Para adicionarmos um cone do componente, precisamos editar um arquivo DCR e adicionar no pacote. Caso esteja usando uma verso mais antiga,
como o Delphi 7, podemos usar o Image Editor, acessando o menu Tools>Image
Editor. No editor, clique em File>New>Component resource file (dcr).
Clique como boto direito em Contents e escolha New>Bitmap. Escolha
uma imagem de tamanho 24x24 (use SuperVGA nas opes de cores). Aps
criar, de um duplo clique Bitmap1 e crie ou cole uma imagem de sua preferncia.
Aps adicionar a imagem, renomeie o arquivo Bitmap1 para TLOCALIZAR.
Para verses mais novas, o Image Editor no acompanha o Delphi, ento
vamos usar uma ferramenta externa para resource files. Para esse artigo, usei
a ferramenta XN Resource Editor que pode ser baixada em: www.wilsonc.
demon.co.uk/d10resourceeditor.htm.
Para criar o resource e bem simples, abra a ferramenta e acesse o menu
Resource>Add Resource. Escolha a opo Bitmap e clique em OK. Nas propriedades configure 24 para Width e Height. Cole a imagem que deseja ou
importe a mesma usando o menu Resource. No painel lateral, renomeie a
pasta 1 para TLOCALIZAR.
Veja na Imagem 4 a ferramenta com as conImagemes.

O cdigo bastante simples, primeiro verificamos se o ClientDataSet


vinculado ao componente esta ativo, se no abrimos o mesmo.
A seguir, instanciamos o formulrio de pesquisa, repassamos as propriedades e chamamos o ShowModal.
O resultado do Execute, ser de acordo com o ModalResult do formulrio,
ou seja, caso seja mrOK foi selecionado algum registro na consulta, seno,
nenhum registro foi selecionado.
Por isso, conImagemmos nos botes do formulrio o ModalResult.
Por fim, no finally, liberamos o formulrio da memria. Para finalizar, toda
a criao do componente, no pacote, clique em Compile e depois em Install.
Caso tudo tenha dado certo, voc ter um componente instalado em uma
nova paleta no Delphi (Imagem 3).

Imagem 4. Criando um resource no XN Resource Editor


Para os dois casos (Image Editor ou XN Resource Editor), salve o arquivo
na mesma pasta do pacote criado no Delphi (com a extenso DCR). Voltando
ao Delphi, no source do pacote (DPK), adicione o cdigo que ir adicionar o
arquivo:

{$R *.dcr}

Poderamos tambm indicar o nome do arquivo sem a utilizao da mscara. Agora, basta recompilar a aplicao e seu componente ter um novo
cone (Imagem 5).

Testando o componente
Imagem 3. Componente instalado no Delphi

10

novembro 2012

Agora, precisamos testar o componente. Vamos criar um projeto de testes


e depois usaremos o Localizar no projeto da nossa srie. Crie um novo projeto

Imagem 5. Novo cone do componente


e crie uma conexo com um banco de dados, usando dbExpress ou qualquer
outra sute de componentes para acesso a dados. Nosso principal componente
o ClientDataSet.
Crie uma conexo no Data Explorer para o banco Employee.fdb do Firebird.
Caso deseja, pode usar qualquer outro banco que possua um driver no Delphi.
Arraste a conexo criada para o formulrio. Arraste a tabela Customer para o
formulrio, para ser criado um SQLDataSet.
Adicione tambm um DataSetProvider e modifique para True a propriedade Options>AllowCommandText, assim indicamos que o responsvel por
receber as consultas (instrues SQL) o prprio ClientDataSet.
Adicione dois ClientDataSets ao formulrio (cdsEmployee e cdsBuscaEmployee). No cdsEmployee configure o CommandText para: select * from
EMPLOYEE where EMP_NO = :EMP_NO.

Imagem 6. Formulrio de cadastro para teste


Veja que o cdigo bem simples, onde verificamos se foi escolhido algum
registro no formulrio de consulta, usando o Execute. Aps, simplesmente,
conImagemmos o parmetro da consulta com o valor retornado pelo componente (ReturnValue).
Com isso, temos um componente de pesquisa que pode ser reaproveitado em vrios formulrios usando o mesmo componente de dados. Veja o
mesmo em execuo na Imagem 7, onde temos uma pesquisa pelo nome e
outra pelo cdigo.

Estamos selecionando todos os dados da tabela, mas parametrizando a


mesma pelo cdigo, assim nossa consulta retornar todos os registros, apenas
quando indicarmos o valor do parmetro. Voc pode fazer sub-consultas, joins
nessa consulta, que no ser afetada no nosso componente de pesquisa.
No cdsBuscaEmployee digite na mesma propriedade: select EMP_NO,
FIRST_NAME from EMPLOYEE where upper(FIRST_NAME) like :FIRST_NAME.
Nesse controle, estamos retornando apenas o cdigo e nome da tabela
Employee, parametrizando pelo nome, que ser conImagemdo no nosso
componente.
No esquea de conImagemr os parmetros nos dois ClientDataSets. Adicione um Localizar no formulrio e configure DataSet para cdsBuscaEmployee.
Digite nas propriedades SQL do Localizar, os mesmos comandos mostrados
anteriormente para cada propriedade SQL.
Adicione os campos do cdsEmployee no formulrio para que o mesmo
fique semelhante a Imagem 6. Adicione tambm um boto para chamar o
Localizar.
Agora, simplesmente, precisamos usar o seguinte cdigo no boto:

if Localizar1.Execute then
begin
cdsEmployee.Close;
cdsEmployee.Params[0].AsInteger :=
Localizar1.ReturnValue;
cdsEmployee.Open;
end;

Imagem 7. Testando o componente

Usando na aplicao
Onde vamos usar nosso componente de pesquisa? No cadastro de vendas,
temos algumas pesquisas auxiliares (cliente, empresa e produto), onde usamos
a tela de pesquisa genrica. Vamos modificar para usar o nosso componente
de pesquisa.
Adicionar trs Localizar no formulrio e faa a ligao da propriedade
DataSet com os respectivos ClientDataSets de pesquisa.
Veja na Listagem 6 o valor das propriedades dos componentes e o cdigo
dos botes para chamar o componente de pesquisa e fazer as conImagemes
necessrias.
Listagem 6. Alterao do cdigo dos botes

novembro 2012

11

Localizar Cliente

Boto Produto

select nCdCliente, sNmCliente from CLIENTE


where nCdCliente =:nCdCliente
SQLDescricao = select nCdCliente,
sNmCliente from CLIENTE where
UPPER(sNmCliente) like :sNmCliente

if (locProduto.Execute) then
nCdProduto := locProduto.ReturnValue
else
DMPesquisa.cdsPesquisaProduto.Close;

Veja a reduo drstica de linhas de cdigo que tivemos. Podemos ainda


alterar nosso cdigo existente para substituir as variveis pelos mtodos do
Localizar. Por exemplo: no precisamos mais usar o nCdCliente e sim apenas
o locCliente.ReturnValue. S vantagens usando um controle de tela criado.

Boto Cliente
if (locCliente.Execute) then
nCdCliente := locCliente.ReturnValue
else
DMPesquisa.cdsPesquisaCliente.Close;

Veja na Imagem 8 a aplicao usando o Localizar.

Localizar Empregado
SQLCodigo

select nCdEmpregado, sNmEmpregado from EMPREGADO where nCdEmpregado =:nCdEmpregado


SQLDescricao = select nCdEmpregado,
sNmEmpregado from EMPREGADO where
UPPER(sNmEmpregado) like :sNmEmpregado

Boto Empregado
if (locEmpregado.Execute) then
nCdEmpregado := locEmpregado.
ReturnValue
else
DMPesquisa.cdsPesquisaEmpregado.Close;

Imagem 8. Usando o Localizar no formulrio de vendas

Concluso
Vimos neste artigo como podemos criar componentes que nos auxilie em
aplicaes client/server para ser utilizado em consultas auxiliares, poupando
tempo de programao e diminuio de cdigo. Poderamos usar formulrios
com a mesma finalidade, mas o componente tem facilidade de ser instalado
e estar disponvel em qualquer projeto Win32.
O que mostrei aqui foi apenas o pontap inicial, use sua criatividade para
agilizar seu dia a dia de programador. Um grande abrao a todos!

Localizar Produto

Sobre o autor

SQLCodigo

Luciano Pimenta

select nCdProduto, sNmProduto from PRODUTO


where nCdProduto = :nCdProduto
SQLDescricao = select nCdProduto,
sNmProduto from PRODUTO where
UPPER(sNmProduto) like :sNmProduto

12

novembro 2012

Tcnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicaes


Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4 edio
da Borland Conference (BorCon).
Autor de mais de 60 artigos e de mais de 300 vdeos aulas publicadas em revistas
e sites especializados. consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra
cursos de programao e banco de dados. desenvolvedor da Paradigma Web Bussiness em Florianpolis-SC.

www.lucianopimenta.net

Formulrio
base de cadastro com barra de
ferramentas
Parte I
Ol pessoal, nos ltimos artigos sobre FireMonkey, no Delphi XE2,
foi mostrado como fazer na plataforma FireMonkey algumas prticas
utilizadas no dia a dia de desenvolvimento na j tradicional plataforma
VCL. Nos prximos artigos vamos continuar com esta ideia, mostrando
algumas adaptaes a serem feitas para utilizar a plataforma Firemonkey,
e alm de se utilizar das mesmas tcnicas da VCL, ainda poder incrementar a interface de sua aplicao com os mais variados recursos visuais
do FireMonkey.
Neste artigo mostraremos como criar um formulrio base para telas de
cadastro, com uma barra de ferramentas para navegao entre registros. Este
formulrio servir de base para a criao de outros formulrios de cadastro, ele
no ser exibido na aplicao, apenas servir para manter um layout padro
de seus formulrios, alm claro de centralizar os cdigos mais comuns em
formulrios deste tipo, reutilizando-os nos formulrios que utilizarem este
como base.
Os formulrios que herdarem este formulrio base herdaro alm do
layout, que manter um padro para todos os formulrios de cadastro, herdar
tambm os seus cdigos, e isto muito importante, porque assim cada novo
formulrio pode se preocupar apenas com os seus cdigos especficos, pois

os cdigos comuns j estaro prontos.


Este primeiro artigo focar na criao do formulrio base e na criao
da barra de navegao entre os registros. Ento sem mais delongas vamos
criao de um novo projeto FireMonkey HD Application - Delphi no Delphi XE2.

Criando o projeto FireMonkey_FormBase


Abra o seu Delphi XE2 e crie um novo projeto FireMonkey HD Application Delphi
atravs do menu (File/ New/ FireMonkey HD Application - Delphi). Crie uma pasta em
seu computador com o nome FireMonkey_FormBase, salve dentro dela a primeira
unit com o nome de unPrincipal e o projeto com o mesmo nome do diretrio, FireMonkey_FormBase. Nesta pasta sero salvos os todos os arquivos do projeto.

Criando o formulrio base de cadastro


Com a unPrincipal e o projeto j salvos, criaremos agora o formulrio que servir
como base para novos formulrios do projeto. Crie um novo Firemonkey HD Form
Delphi atravs do menu (File/ New/ Firemonkey HD Form - Delphi), salve a unit deste
form na pasta do projeto com o nome de unFormBase.
Na propriedade name do formulrio renomeie para frmFormBase, assim poderemos identifica-lo mais facilmente.
Agora vamos adicionar os componentes que iremos utilizar neste formulrio.
novembro 2012

13

Adicione uma TToolBar (Standard), um TPanel (Standard), um TStatusBar (Standard) e


doze TSpeedButton (Additional), altere as propriedades Name, Text, Tag e Width dos
doze TSpeedButtons seguindo o valores da tabela 1:

cess), um TDataSource (DataAccess), um TBindScopeDB (LiveBindings) e um


TBindingList (LiveBindings). Siga a tabela 2 para fazer a conImagemo destes
cinco componentes.

Tabela 2 Propriedades dos componentes de acesso a dados


Tabela 1 Propriedades dos componentes TSpeedButtons
Como podemos perceber na tabela 1 no FireMonkey, no tem a propriedade
Caption nos componentes como na VCL, a sua substituta a propriedade Text. Como
podemos ver, distribumos sequencialmente um nmero para cada um dos botes
em sua propriedade Tag, isto servir para identifica-los genericamente mais tarde.
Disponha os componentes no formulrio como mostra a Imagem 1.

Imagem 1 Sugesto de layout para o formulrio base


No FireMonkey, como na plataforma VCL, tem um recurso onde um objeto
do layout do formulrio pode controlar algumas propriedades de outros objetos
,desde que estes faam parte de seu n no menu TreeView (janela Structure),
ou seja, possua objetos filhos. Se alterar a propriedade Enabled do objeto pai
para false, todos os filhos deste no podero executar nenhuma ao mesmo
que estejam habilitados, at que o objeto pai seja habilitado novamente. A
diferena que na plataforma FireMonkey, este recurso no se limita apenas
componentes containers como TPanels e TGruopBox por exemplo, no Firemonkey qualquer objeto visual do layout pode ter componentes filhos, at
mesmo TLabels e TButtons. Mencionei este recurso, pois os TSpeedButtons
adicionados ao form devem pertencer a ToolBar, e tambm devem ser independentes um do outro, ou seja, nenhum deve controlar o outro.

Explicando o funcionamento dos componentes de acesso a dados no


formulrio
No geral o trio de componentes de acesso a dados (SQLDataSet, DataSetProvider e ClientDataSet) so alocados em um DataModule, e ligados aos
formulrios atravs de um DataSource.
Porm a ideia apresentada neste artigo de deixar um ClientDataSet j
com as conImagemes bsicas de ligaes j realizadas. Outra vantagem deste
mtodo que os cdigos do ClientDataSet sero conImagemdos no prprio
Formulrio, facilitando a visualizao dos cdigos do mesmo.
No Delphi 7 esta mesma tcnica se faz sem a necessidade de trazer ao
formulrio junto com o ClientDataSet o DataSetProvider. Porm fazia uso de
um componente da palheta DataSnap chamado TLocalConnection.
Este componente era adicionado ao DataModule, no ClientDataSet bastava informar na propriedade RemoteServer o componente TLocalConnection
presente no DataModule, e o ClientDataSet visualizar o DataSetProvider como
se estivesse no Prprio DataModule.
No Delphi XE2 no tem o componente TLocalConnection, e por isso que
o DataSetProvider veio junto com o ClientDataSet ao formulrio, para manter
o mesmo mtodo utilizado no Delphi 7.
Desta forma no DataModule, iremos ter apenas o componente que faz
a conexo com o banco de dados, TSQLConnection, e o componente que

Caso algum boto seja filho de outro na hierarquia deve-se deixa-lo como
filho da ToolBar, pois cada boto ter uma ao diferente na navegao dos
registros e dependendo da ao de um boto os outros podero ficar desabilitados, por isso se faz necessrio deixar todos como filhos da ToolBar. Caso
haja um caso assim, basta arrastar o SpeedButton para o n da ToolBar. Veja
um exemplo na Imagem 2.
Os componentes visuais j esto devidamente alocados no layout do formulrio, vamos agora adicionar os componentes de acesso a dados. Devemos
lembrar que por se tratar de um formulrio base, ele no far nenhum vinculo
direto com banco de dados, porm, dever fornecer uma estrutura para tal
funo, aos formulrios que receberem sua herana.
Adicione um TDataSetProvider (DataAccess), um TClientDataSet (DataAcnovembro 2012

Imagem 2 Alterando a hierarquia dos objetos do formulrio

acessa individualmente cada tabela do banco de dados, TSQLDataSet, ambos


da palheta DBExpress.
Explicado o porqu de tantos componentes de acesso a dados no formulrio, vamos ento explicar rapidamente a conImagemo deles.
O dspBase (TDataSetProvider) no ter nenhum valor mesmo na propriedade DataSet, pois este ser preenchido pelo formulrio que receber a herana
do frmFormBase, outra propriedade a ser alterada a Options/poAllowCommandText, esta permitir que o ClientDataSet execute consultas SQL na base
de dados, por fim, para melhorar a performance das transaes de alterao e
excluso, foi alterada a propriedade UpdateMode para upWhereKeyolny, que
significa que apenas realizar as atualizaes pelas primary keys.
O cdsBase (TClientDataSet) apenas far a ligao com o dspBase atravs
da propriedade ProviderName. O dsBase (TDataSource) deve fazer ligao com
o cdsBase, atravs de sua propriedade DataSet.
Como foi visto nos artigos anteriores sobre FireMonkey, esta plataforma
no possui o grupo de componentes da palheta DataControls, e por este
mesmo motivo que foi agregado ao Delphi tecnologia LiveBindings (ligaes
ao vivo), em suma esta tecnologia permite manipular as propriedades de
componentes visuais em tempo de execuo, ou at mesmo criar BindingLinks
para os Fields de um DataSource, este que ser o nosso caso.
Para possibilitar criarmos estes BindingLinks, necessitaremos de um escopo de binding prprio para a ligao com o banco de dados, esta a funo
do BindScopeDBBase (TBindScopeDB), deve-se informar qual DataSource ele
manipular atravs da propriedade DataSource, neste caso o dsBase.
Por fim, o BindingList (TBindingList) no ter nenhuma conImagemo,
mas sua a funo de suma importncia para os prximos formulrios, pois
nele que sero listados todos os BindingLinks e as LiveBindings do formulrio.
Tanto o BindScopeDBBase quanto o BindingList so do grupo de componentes
da palheta LiveBindings.

Definindo variveis pblicas para o frmFormBase


As variveis pblicas sero preenchidas pelos formulrios que receberem a
herana do frmFormBase, estas variveis possibilitaro a manipulao dinmica
do cdigo, a partir delas manipularemos o cdigo base dos botes e outros
procedimentos que sero comuns em formulrios de cadastro.
Como mencionado estas sero variveis pblicas, ou seja, sero declaradas
na sesso pblica da unit. Veja na tabela 3 a lista das variveis pblicas que
sero utilizadas do frmFormBase.
A maioria destas variveis servir como parmetro para a chamada de
um formulrio de pesquisa. Vamos utilizar como exemplo o formulrio de
pesquisa criado no artigo FireMonkey - utilizando mestre-detalhe e formulrio pesquisa - parte II da revista The Club do ms de outubro deste ano, o
contedo desta revista tambm pode ser acessado na sesso de revistas do
site oficial da revista The Club (www.theclub.com.br).
Voc pode seguir o artigo para criar o formulrio de pesquisa neste projeto
ou caso j tenha construdo o formulrio de pesquisa em outro projeto, basta
copiar os arquivos unPesquisa.pas e unPesquisa.fmx para o diretrio deste
projeto, e depois adicionar ao projeto usando o menu (Project / Add to Project)
14

e selecionando a unit a ser adicionada no projeto, neste caso a unPesquisa.


Depois de adicionado a unPesquisa ao projeto FireMonkey_FormBase, s
adicion-la na clusula Uses da unFormBase. Veremos posteriormente como
passar os parmetros ao frmPesquisa.
As duas primeiras variveis, SQL_PADRAO E TABELA, faro o revezamento
no cdigo, ou seja, se informar a SQL_PARAO no precisa informar a TABELA e
vice-versa, isso quer dizer que quando tiver uma SQL_PADRAO informada, o
cdigo far a manipulao de SQL atravs dela, caso no tenha, o cdigo manipular uma SQL mais simples utilizando o nome da tabela informado na varivel
TABELA. Percebe se que a utilizao da primeira varivel, SQL_PADRAO, se faz
necessrio em caso de uma consulta SQL mais complexa que exija, por exemplo,
algum JOIN entre outras tabelas, no mais, basta informar o nome da tabela.
A varivel GEN_NAME armazenar o nome do Generator responsvel por
armazenar o valor da chave primria da tabela base.
Com esta varivel, ser possvel fazer uso de uma funo de auto-incremento para as chaves primrias, que estar acessvel neste formulrio. Para
poder acessar o banco de dados genericamente, foi criado a varivel CONEXAO
do tipo TSQLConnection. Para utilizar o componente TSQLConnection preciso
declarar na sesso uses a biblioteca Data.SqlExpr a qual ela pertence.
A varivel FOCO se encarregar de jogar o foco automtico para o objeto
a ela atribudo.

Criando os mtodos para o funcionamento da barra de


navegao
Criaremos dois mtodos para realizar a tarefa de dar mobilidade barra de ferramentas, como vimos anteriormente, nossa barra de ferramentas possui 12 botes
identificados pelas suas propriedades Tag. O que teremos que fazer , por exemplo,
desabilitar alguns botes dependendo da ao que est sendo executada no formulrio.
O primeiro mtodo uma funo, que retornar um valor booleano que se
refere ao estado que o boto dever assumir conforme a sua tag, a funo se chama
EstadoBotao. Veja na listagem 1 como feita a sua declarao na sesso pblica da
unit e o corpo do cdigo.
// DECLARAO DA FUNO
public
{ Public declarations }
function EstadoBotao(Sender : TObject;
DS : TDataSource): Boolean;
// CORPO DA FUNO
function TfrmFormBase.EstadoBotao(Sender:
TObject; DS: TDataSource): Boolean;
begin
Result := False;
// EDITAR E EXCLUIR
if (TSpeedButton(Sender).Tag in [3, 4])
then
Result := (DS.DataSet.RecordCount > 0)
and (DS.DataSet.State = dsBrowse)
else
// INCLUIR, ATUALIZAR E LOCALIZAR
if (TSpeedButton(Sender).Tag in [2, 7,
12]) then
Result := DS.DataSet.State = dsBrowse
else
// GRAVAR E CANCELAR
if (TSpeedButton(Sender).Tag in [5, 6])
novembro 2012

15

Tabela 3 Lista de variveis pblicas do frmFormBase

then

Result := DS.DataSet.State in
[dsInsert, dsEdit]
else
// PRIMEIRO E ANTERIOR
if (TSpeedButton(Sender).Tag in [8, 9])
then
Result := (DS.DataSet.State =
dsBrowse) and not (DS.DataSet.Bof)
else
// PRXIMO E LTIMO
if (TSpeedButton(Sender).Tag in [10,
11]) then
Result := (DS.DataSet.State =
dsBrowse) and not (DS.DataSet.Eof)
else
// SAIR
if (TSpeedButton(Sender).Tag in [13])
then
Result := True;
end;

Listagem 1 Funo EstadoBotao


Ao observar o cdigo da funo, percebe-se que ela verifica quais estados
os botes, identificados pela sua propriedade Tag, podem assumir referente
ao estado atual do DataSet ligado ao DataSource passado como parmetro.
Esta funo ser utilizada pelo prximo mtodo que um procedimento,
de nome ControlaBotoes, ele executar a ao de habilitar e desabilitar cada
boto, a partir do resultado obtido pela funo EstadoBotao.
Ele deve estar declarado na sesso pblica logo abaixo da declarao da
funo EstadoBotao. Veja na listagem 2 o exemplo do seu cdigo.
procedure TfrmFormBase.ControlaBotoes;
begin
sbIncluir.Enabled :=
EstadoBotao(sbIncluir, dsBase);
sbEditar.Enabled :=
EstadoBotao(sbEditar, dsBase);
sbExcluir.Enabled :=
EstadoBotao(sbExcluir, dsBase);
sbGravar.Enabled :=
EstadoBotao(sbGravar, dsBase);
sbCancelar.Enabled :=
EstadoBotao(sbCancelar, dsBase);
sbAtualizar.Enabled :=
EstadoBotao(sbAtualizar, dsBase);
sbPrimeiro.Enabled :=
16

novembro 2012

EstadoBotao(sbPrimeiro, dsBase);
sbAnterior.Enabled :=
EstadoBotao(sbAnterior, dsBase);
sbProximo.Enabled :=
EstadoBotao(sbProximo, dsBase);
sbUltimo.Enabled :=
EstadoBotao(sbUltimo, dsBase);
sbLocalizar.Enabled :=
EstadoBotao(sbLocalizar, dsBase);
sbSair.Enabled :=
EstadoBotao(sbAtualizar, dsBase);
end;

Listagem 2 Procedimento ControlaBotoes


Estes dois mtodos juntos, faro a manipulao do estado dos botes,
como ativ-los ou desativ-los.
Porm ainda no fizemos a chamada destes mtodos, eles devem ser
chamados toda vez que tiver alguma alterao no estado do dataset.
Sendo assim vamos fazer a chamada do procedimento no evento onDataChange do dsBase (TDataSource), veja na listagem 3 como feito a chamada
deste mtodo.
procedure TfrmFormBase.
dsBaseDataChange(Sender: TObject; Field:
TField);
begin
ControlaBotoes;
end;

Listagem 3 Fazendo a chamada do procedimento no evento onDataChange do dsBase

Configurando as aes de cada boto


Outro componente que comumente utilizado na VCL o TActionList,
principalmente para centralizar as aes de botes. Porm, este tambm
no est disponvel na plataforma FireMonkey, portanto iremos manipular as
aes dos botes da barra de ferramentas a partir do evento onClick do boto
sbIncluir, depois disso basta vincular este evento (procedimento) a todos os
demais botes. Veja na listagem 4 a implementao do cdigo.
procedure TfrmFormBase.
sbIncluirClick(Sender: TObject);
begin
if (Sender is TSpeedButton) then
begin
case TSpeedButton(Sender).Tag of
2: begin
cdsBase.Insert;
if (Assigned(FOCO)) then
TControl(FOCO).SetFocus;
end;
3: begin

cdsBase.Edit;
if (Assigned(FOCO)) then
TControl(FOCO).SetFocus;
end;
4: begin
if MessageDlg(Confirma a
excluso?, TMsgDlgType.mtConfirmation,
[TMsgDlgBtn.mbYes,
TMsgDlgBtn.mbNo], 0) = mrYes then
cdsBase.Delete;
end;
5: begin
if MessageDlg(Confirma a
gravao?, TMsgDlgType.mtConfirmation,
[TMsgDlgBtn.mbYes,
TMsgDlgBtn.mbNo], 0) = mrYes then
cdsBase.Post;
end;
6: begin
if MessageDlg(Cancelar
edio?, TMsgDlgType.mtConfirmation,
[TMsgDlgBtn.mbYes,
TMsgDlgBtn.mbNo], 0) = mrYes then
cdsBase.Cancel;
end;
7: cdsBase.Refresh;
8: cdsBase.First;
9: cdsBase.Prior;
10: cdsBase.Next;
11: cdsBase.Last;
12: begin
frmPesquisa := TfrmPesquisa.
Create(Self);

SQL_PADRAO
TABELA;
CAMPO_CHAVE;
CAMPO_BUSCA;

if (SQL_PADRAO <> ) then


frmPesquisa.SQL_PADRAO :=
else
frmPesquisa.TABELA :=
frmPesquisa.CAMPO_CHAVE :=
frmPesquisa.CAMPO_BUSCA :=

frmPesquisa.DESCRICAO :=
DESCRICAO_PESQUISA;
frmPesquisa.CDS := cdsBase;
frmPesquisa.ShowModal;
FreeAndNil(frmPesquisa);
end;
13: Close;
end;
end;
end;

Listagem 4 Definindo as aes de cada boto no evento onClick do


sbIncluir
A primeira verificao que fazemos neste evento se o parmetro Sender
um componente da classe TSpeedButton. Sendo assim, utilizamos a classe
TSpeedButton utilizando o parmetro Sender para recuperarmos o valor de
sua Tag, dentro do mtodo Case Of.

Assim passamos qual o procedimento a ser tomado dependendo do boto


clicado, identificados pelo valor de sua Tag.
Se for o boto excluir, gravar ou o cancelar, faremos uma verificao utilizando o mtodo nativo do Delphi MessageDialog, exibindo uma mensagem
de confirmao para o usurio e dependendo de sua resposta executa a ao
do boto.
Outra observao no boto de pesquisar, Tag 12. nesta parte que passamos os parmetros globais para o frmPesquisa, observe que aps criarmos o
form em memria j passamos todos os parmetros a ele, depois s cham-lo
pelo mtodo ShowModal, por fim, elimin-lo da memria.
Lembrando que o formulrio de pesquisa utilizado como exemplo, o
mesmo que foi criado no artigo de Firemonkey da revista The Club do ms de
outubro de 2012, no foi alterado nada, apenas foi adicionado a este projeto
da forma como foi criado.
Aps adicionar o cdigo da listagem 4 no evento onClick do sbIncluir, basta
amarrar este evento a todos os demais botes. Uma forma bem simples de se
fazer isto pressionar a tecla Shift e clicar em cada boto exceto o sbIncluir,
desta maneira ir selecionar todos de uma s vez, depois de feito isso s ir
janela Object Inspector e abrir a aba Events, no evento onClick selecione a
opo sbIncluirClick, feito isso d um duplo clique no evento para finalizar a
amarrao, se der certo, o cursor do mouse ficar piscando na primeira linha
do procedimento sbIncluirClick na unit.
At este momento nosso projeto possui trs units, unPrincipal, unFormBase e unPesquisa. Nossa barra de ferramentas est pronta e totalmente
funcional, porm, continuaremos com este projeto no prximo artigo, onde
descreveremos mais alguns mtodos comuns para um formulrio de cadastro.

Concluso
Neste artigo foi mostrado a primeira parte de como criar um formulrio
base de cadastro, o foco neste artigo foi como construir a barra de ferramentas
do formulrio base, vimos as adaptaes a serem realizadas se comparadas
com a plataforma VCL, e tambm o porque de trazer o componentes TClientDataSet para o formulrio unificando os cdigos referentes tabela a ser
trabalhado no formulrio.
O prximo artigo ter a continuao deste projeto, mostraremos mais
alguns mtodos padres em formulrios de cadastro e tambm como fazer
uma herana deste formulrio base. Espero que tenham gostado do que viram
at aqui e que tenha sido til de alguma forma, at o nosso prximo artigo,
um abrao a todos.

Sobre o autor
Lucas Vieira de Oliveira
Consultor Tcnico The Club.

suporte@theclub.com.br

novembro 2012

17

Linguagem C#
Criando um Componente
TextBox personalizado

se preocupe que disponibilizarei todo o cdigo fonte)


Muitas vezes necessitamos utilizar um componente diferente ou com alguma
funcionalidade a mais em nossas aplicaes, na maioria dos casos devemos realizar esta tarefa herdando de um componente principal ou at mesmo o criando
do zero, escrevendo-o diretamente da classe Object. Podemos manipular suas
propriedades e mtodos at chegar ao resultado que desejamos.

Na linguagem C# isto se torna uma tarefa fcil e prtica, sendo que neste artigo
vou criar um TextBox personalizado contendo validaes de CPF, CNPJ e PIS usando o
mtodo OnValidating(). Reescreverei mtodos e propriedades como: OnLostFocus(),
OnGotFocus() e ForeColor para dar uma impresso um pouco mais interessante
ao usurio. Ser necessrio tambm criar uma classe Tipo para trabalharmos com
o Tipo de validao necessria.
Para esta tarefa achei mais prtico utilizar um combobox acoplado nas suas
propriedades.
Criando o Componente
Inicie o Microsoft Visual Studio e crie um novo projeto como Class Libary. (No
18

novembro 2012

Clique com o boto direito sobre a soluo e escolha Add/New Item.... Criaremos uma classe do incio. Ver Imagem 01. Vou abordar assuntos j mencionados em
assuntos anteriores, primeiramente importe algumas bibliotecas teis ao longo do
desenvolvimento.

using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
System.Windows.Forms: Assembly que contm a classe TextBox.
System.Drawing: Assembly responsvel pela troca de cores dos componentes.
System.ComponentModel: Classes responsveis pela manipulao e converso
de dados dos componentes.
O primeiro passo ao criar uma classe definir o atributo como Public, para
podermos visualiz-la em qualquer parte do projeto e logo em seguida usar o recurso
de herana para a classe TextBox. Defina tambm o Constructor e Destructor

}
//Sobrescrever o evento ao perder o foco
protected override void
OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
this.BackColor = Color.White;
}

Imagem 01: Criar uma classe para o TextBox.


do componente. Especificamente neste artigo no precisei utiliz-los, mas recomendo
sempre a criao do mesmo.

//Herana de Classes
public class TextBoxTheClub: TextBox
{
//Definindo o Contructor
public TextBoxTheClub()
{
}
//Definindo o Destructor
~TextBoxTheClub()
{
}
Vou reescrever os mtodos OnLostFocus(), OnGotFocus() e a propriedade
ForeColor sendo respectivamente responsveis por perder o foco, receber o foco e
mudar cor da fonte, que neste caso defini como DarkBlue.

//Sobrescrever a propriedade cor da Fonte


public override Color ForeColor
{
get
{
}
set
{
}

return Color.DarkBlue;

base.ForeColor = value;

//Sobrescrever o evento ao receber o foco


protected override void
OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
this.BackColor = System.Drawing.
Color.LightYellow;

public class Tipo : StringConverter


{
public override bool GetStandardValuesSupp
orted(ITypeDescriptorContext context)
{
return true;

}

public override TypeConverter.
StandardValuesCollection GetStandardValues
(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new
string[] { CPF, CNPJ, PIS });
}
}
Foi necessrio criar uma pequena classe denominada Tipo, herdando da StringConverter. Usaremos o Override do mtodo GetStandardValuesSupported
responsvel por indicar se o conversor oferece ou no suporte a um conjunto de
valores, retornando um booleano e o mtodo GetStandardvalues() que possibilita
a manipulao de uma coleo de dados, que no caso especfico identificamos como:
CPF, CNPJ e PIS.

[TypeConverter(typeof(Tipo)),
Category(validao)]
public string TipoValidacao
{
get;
set;
}
Para identificarmos o tipo de validao foi necessrio criar uma propriedade
TipoValidacao usando os operadores Get e Set, pois atravs deles que podemos
recuperar e atribuir os valores descritos acima. Graas a esta propriedade que conseguimos manipular as conImagemes propostas pelo desenvolvedor.

protected override void


OnValidating(System.ComponentModel.
CancelEventArgs e)
{
base.OnValidating(e);
if (this.Text.Length > 0)
{
if (TipoValidacao == CPF)
{
novembro 2012

19

Text) == true)

if (ValidarCpf(this.
{

MessageBox.

Show(CPF Vlido!!);
}
else
{
Show(CPF Invlido!!);
}

CNPJ)

MessageBox.
this.Focus();

}
else if (TipoValidacao ==
{

Text) == true)

if (ValidarCnpj(this.
{

Show(CNPJ Vlido!!);

MessageBox.

}
else
{

MessageBox.
Show(CNPJ Invlido!!);
this.Focus();
}
}
else if (TipoValidacao ==
PIS)
{
if (ValidarPis(this.Text)
== true)
{
MessageBox.Show(PIS
Vlido!!);
}
else
{
MessageBox.Show(PIS
Invlido!!);
this.Focus();
}
}
}
}
O evento Onvalidating() executado no momento que samos do Textbox, ou
seja, o validamos. Este evento ser responsvel por chamar as funes de validaes
de CPF, CNPJ e PIS. No primeiro momento verificamos se o campo est preenchido com
a propriedade length e logo em seguida usamos a propriedade pblica TipoValidacao identificando o que o desenvolvedor deseja validar. Por final chamamos a funo
desejada. No entrarei em detalhes como foram montadas as funes pelo fato deste
artigo abordar a criao de componentes. Segue em seguida as funes ValidarCpf(),
ValidarCnpj() e ValidarPis().

public static bool ValidarCnpj(string


cnpj)
20

novembro 2012

int[] multiplicador1 = new int[12] {


5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
int[] multiplicador2 = new int[13] {
6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
int soma;
int resto;
string digito;
string tempCnpj;
cnpj = cnpj.Trim();
cnpj = cnpj.Replace(., ).
Replace(-, ).Replace(/, );
if (cnpj.Length != 14)
return false;
tempCnpj = cnpj.Substring(0, 12);
soma = 0;
for (int i = 0; i < 12; i++)
soma += int.Parse(tempCnpj[i].
ToString()) * multiplicador1[i];
resto = (soma % 11);
if (resto < 2)
resto = 0;
else
resto = 11 - resto;
digito = resto.ToString();
tempCnpj = tempCnpj + digito;
soma = 0;
for (int i = 0; i < 13; i++)
soma += int.Parse(tempCnpj[i].
ToString()) * multiplicador2[i];
resto = (soma % 11);
if (resto < 2)
resto = 0;
else
resto = 11 - resto;
digito = digito + resto.ToString();
return cnpj.EndsWith(digito);
}
public static bool ValidarCpf(string cpf)
{
int[] multiplicador1 = new int[9] {
10, 9, 8, 7, 6, 5, 4, 3, 2 };
int[] multiplicador2 = new int[10] {
11, 10, 9, 8, 7, 6, 5, 4, 3, 2 };
string tempCpf;
string digito;
int soma;
int resto;
cpf = cpf.Trim();
cpf = cpf.Replace(., ).
Replace(-, );
if (cpf.Length != 11)
return false;
tempCpf = cpf.Substring(0, 9);
soma = 0;
for (int i = 0; i < 9; i++)
soma += int.Parse(tempCpf[i].
ToString()) * multiplicador1[i];
resto = soma % 11;

if (resto < 2)
resto = 0;
else
resto = 11 - resto;
digito = resto.ToString();
tempCpf = tempCpf + digito;
soma = 0;
for (int i = 0; i < 10; i++)
soma += int.Parse(tempCpf[i].
ToString()) * multiplicador2[i];
resto = soma % 11;
if (resto < 2)
resto = 0;
else
resto = 11 - resto;
digito = digito + resto.ToString();
return cpf.EndsWith(digito);
}
public static bool ValidarPis(string pis)
{
int[] multiplicador = new int[10] { 3,
2, 9, 8, 7, 6, 5, 4, 3, 2 };
int soma;
int resto;
if (pis.Trim().Length != 11)
return false;
pis = pis.Trim();
pis = pis.Replace(-, ).
Replace(., ).PadLeft(11, 0);
soma = 0;
for (int i = 0; i < 10; i++)
soma += int.Parse(pis[i].
ToString()) * multiplicador[i];
resto = soma % 11;
if (resto < 2)
resto = 0;
else
resto = 11 - resto;
return pis.EndsWith(resto.ToString());
}
Prontinho, acabamos de criar um pequeno componente utilizando o C#, Salve o
projeto e o compile. Ver Imagem 02.

A Instalao
Clique com o boto direito na Toolbox e escolha Choose Items... para adicionar
a .dll criada anteriormente. Imagem 03.

Imagem 03: Instalando o Componente.

No boto Browse... localize no diretrio onde foi salvo, por exemplo:


C:\Diretorio\TextBoxTheClub\bin\Debug\TextBoxTheClub.dll
Ver Imagem 04.

Imagem 04: Adicionando no ToolBox.


A Imagem 05 mostra o TextBoxTheClub instalado corretamente na palheta de
componentes.

Imagem 05: TextBoxTheClub localizado na ToolBox.

Criando um exemplo prtico


Para test-lo basta encar-lo como um TextBox comum, mas com algumas funcionalidades a mais. Para isto crie um novo Projeto e adicione alguns
TextBoxTheClub no formulrio. Ver Imagem 06.

Imagem 02: Compilando.

Clicando nas propriedades podemos conferir o tipo de validao que foi


programado. Aproveite e escolha uma de cada tipo. Ver Imagem 07.
Rodando a aplicao podemos conferir a execuo das funes no evento
Onvalidating(), a troca de cor de acordo com o foco e o tipo pr-definido da
novembro 2012

21

Imagem 06: Criando um exemplo.

Imagem 08: Exemplo em Run-Time.


pequenos conceitos conseguimos economizar tempo e cdigo no decorrer do
desenvolvimento de aplicaes. Abordei assuntos como: Herana de Classes,
Sobrescrita de mtodos e propriedades, criao de classes auxiliares e funes estticas. Existem diversas formas e mecanismos para se desenvolver
um componente, procurei neste artigo simplificar o mximo possvel a fim de
um aprendizado maior. Fica assim, um grande abrao e at o ms que vem!

Imagem 07: Tipo de Validao (CPF, CNPJ e PIS).

Sobre o autor
Marcos Csar Silva

cor da fonte. Ver Imagem 08 o exemplo em Run-Time.

Concluso
A criao de componentes se torna uma prtica muito recomendada na
programao Orientada a Objetos, sendo muito utilizada desde o incio dos
tempos. O principal intuito deste artigo foi de demonstrar que atravs de

22

novembro 2012

Consultor de Sistemas na consultoria de sistemas DataSmart e Consultor Tcnico do The Club, Bacharel em Cincia
da Computao, MBA em Gesto Empresarial, Certificaes
MCAD (Microsoft Certified Application Developer) e MCSD.
NET (Microsoft Certified Solution Developer .NET)

marcos@theclub.com.br

ANDROID
Aprendendo a utilizar o
ListView
Ol amigos do The Club, estou de volta com artigos relacionados ao
Sistema Android. Apresentarei o ListView, sendo um dos componentes
mais utilizados e importantes desta plataforma pelo fato de possibilitar
a implementao de funes ligadas ao Banco de Dados, classes ou
qualquer coleo de dados.
A documentao On-Line para o desenvolvedor Android descreve o
ListView como um grupo de exibio que mostra uma lista de itens com possibilidade de rolagem. Os itens da lista so automaticamente inseridos usando
um adaptador que utiliza o contedo de uma fonte (uma consulta qualquer ou
com banco de dados), convertendo cada item resultando em uma viso que
por fim mostrado ao usurio final.

Para criar uma classe clique com o boto direito sobre o pacote principal
escolha New/Class definindo como Clientes.java. Esta classe possuir
todas as propriedades descritas anteriormente com seus mtodos Getters
and Setters. Para criar estes mtodos automaticamente, clique com o boto
direito e escolha Source/Generate Getters and Setters. Este recurso do Eclipse
possibilita a automatizao de vrios processos, incluindo este. Ver Imagem 01.

Este artigo possuir dois exemplos, o primeiro utilizando a classe ArrayAdapter e o segundo faremos uma pequena implementao nesta classe para
personalizar e montar um layout desejado pelo desenvolvedor. Seguiremos
os mesmos passos descritos nos artigos anteriores, crie um novo Projeto em
Android, defina o nome da atividade principal como menuescolherAtividade.

Criando a Classe Clientes


Os dados utilizados para testes nestes exemplos sero oriundos de uma
classe com alguns atributos, ou seja, no teremos nenhum Banco de Dados.
importante entender que a origem dos dados no importa neste processo.
A estrutura ser da conforme a tabela 1:

Imagem 01: Gerao automtica dos Mtodos Getters and Setters.


novembro 2012

23

package pct.Android_ListView;
import java.util.ArrayList;
import java.util.List;
public class Clientes
{

private int Id_Cliente;
private String Nome;

private String Tipo_Pessoa;

private String Cnpj_Cpf;

private String Email;

private String Situacao;


public int getId_Cliente()
{

return Id_Cliente;
}

public void setId_Cliente(int id_
Cliente)
{

Id_Cliente = id_Cliente;
}

public String getNome()
{

return Nome;
}

public void setNome(String nome)
{

Nome = nome;
}

public String getTipo_Pessoa()
{

return Tipo_Pessoa;
}

public void setTipo_Pessoa(String
tipo_Pessoa)
{

Tipo_Pessoa = tipo_Pessoa;
}

public String getCnpj_Cpf()
{

return Cnpj_Cpf;
}

public void setCnpj_Cpf(String cnpj_
Cpf)
{

Cnpj_Cpf = cnpj_Cpf;
}

public String getEmail()
{

return Email;
}

public void setEmail(String email)
{

Email = email;
}

public String getSituacao()

{

}

return Situacao;


public void setSituacao(String
situacao)
{
24

novembro 2012


Situacao = situacao;
}


public Clientes()
{

}

public List<Clientes>
ListarClientes()
{
List<Clientes> lista_cliente = new
ArrayList<Clientes>();


Clientes cliente = new
Clientes();
cliente.setId_Cliente(1);
cliente.setNome(Thiago
Montebugnoli);
cliente.setEmail(thiago@
theclub.com.br);
cliente.setCnpj_
Cpf(366.999.888-99);
cliente.setTipo_Pessoa(F);
cliente.setSituacao(1);
lista_cliente.add(cliente);


Clientes cliente1 = new
Clientes();
cliente1.setId_Cliente(2);

cliente1.setNome(Marcos Cesar
Silva);
cliente1.setEmail(marcos@
theclub.com.br);
cliente1.setCnpj_
Cpf(166.999.888-99);
cliente1.setTipo_Pessoa(F);
cliente1.setSituacao(1);
lista_cliente.add(cliente1);


Clientes cliente2 = new
Clientes();
cliente2.setId_Cliente(3);
cliente2.setNome(Bruno);
cliente2.setEmail(bruno@
theclub.com.br);
cliente2.setCnpj_
Cpf(222.222.888-99);
cliente2.setTipo_Pessoa(J);
cliente2.setSituacao(1);
lista_cliente.add(cliente2);


Clientes cliente3 = new
Clientes();
cliente3.setId_Cliente(4);
cliente3.setNome(Vitor);
cliente3.setEmail(vitor@
theclub.com.br);
cliente3.setCnpj_
Cpf(999.999.999-99);
cliente3.setTipo_Pessoa(J);
cliente3.setSituacao(0);
lista_cliente.add(cliente3);


Clientes cliente4 = new
Clientes();
cliente4.setId_Cliente(5);
cliente4.setNome(Eduardo);
cliente4.setEmail(eduardo@
theclub.com.br);
cliente4.setCnpj_
Cpf(366.999.888-99);
cliente4.setTipo_Pessoa(F);
cliente4.setSituacao(0);
lista_cliente.add(cliente4);


Clientes cliente5 = new
Clientes();
cliente5.setId_Cliente(6);

cliente5.setNome(The Club);
cliente5.setEmail(suporte@
theclub.com.br);
cliente5.setCnpj_
Cpf(41.789.789.0001/05);
cliente5.setTipo_Pessoa(J);
cliente5.setSituacao(1);
lista_cliente.add(cliente5);


Clientes cliente6 = new
Clientes();
cliente6.setId_Cliente(7);
cliente6.setNome(Datasmart);
cliente6.setEmail(datarmart@
theclub.com.br);
cliente6.setCnpj_
Cpf(99.888.898.0001/01);
cliente6.setTipo_Pessoa(J);
cliente6.setSituacao(0);
lista_cliente.add(cliente6);


return lista_cliente;
}
}

No mtodo ListarClientes() onde alimento esta classe com alguns dados


aleatrios e retorno em seguida uma Lista de clientes, ou seja, retorno um
conjunto de dados para a Classe Clientes, a qual servir de exemplo para o
uso de nossos exemplos.

Criando a tela principal


Em res/layout crie um XML e defina o nome como menuescolher.
xml. Aproveite tambm e adicione alguns componentes: Um textBox, dois
RadioButtons, Um Button e um ListView. Ver Imagem 02 do Lay-Out Sugerido.
Segue tambm a estrutura XML Correspondente:
<?xml version=1.0 encoding=utf-8?>
<LinearLayout xmlns:android=http://
schemas.android.com/apk/res/android
android:orientation=vertical
android:layout_width=fill_parent
android:layout_height=fill_parent>
<TextView android:typeface=sans
android:id=@+id/txtPesquisar
android:textAppearance=?android:attr/
textAppearanceMedium
android:layout_width=200dp
android:text=Escolher ListView:
android:layout_height=wrap_content
android:layout_gravity=center
android:gravity=center>
</TextView>
<RadioGroup android:orientation=horiz
ontal
android:id=@+id/rgEscolher
android:layout_height=wrap_content
android:layout_width=wrap_content
android:gravity=center
android:layout_gravity=center>
<RadioButton
android:checked=true
android:layout_width=wrap_
content
android:typeface=sans

Imagem 02: Tela Principal.


android:id=@+id/rbArrayAdapter
android:text=ArrayAdapter
android:layout_height=wrap_
content>
</RadioButton>
<RadioButton android:layout_
width=wrap_content
android:typeface=sans
android:id=@+id/rbTheClubAdapter
android:text=TheClubAdapter
android:layout_height=wrap_
content>
</RadioButton>
</RadioGroup>
<Button android:text=Listar Dados
android:onClick=Listar
android:id=@+id/btnListar
android:typeface=sans
android:layout_height=wrap_content
android:layout_gravity=center_
horizontal
android:layout_width=120dp>
</Button>
<ListView android:layout_weight=1
android:layout_width=match_parent
android:layout_height=352dp
android:id=@+id/lstSimples>
</ListView>
</LinearLayout>

Criando um exemplo simples


Na Atividade principal definida como: menuescolherAtividade.java,
inicialmente importe algumas bibliotecas necessrias ao decorrer do desenvolvimento.
import
import
import
import
import
import
import
import
import

java.util.ArrayList;
java.util.List;
android.app.Activity;
android.os.Bundle;
android.view.View;
android.widget.ArrayAdapter;
android.widget.Button;
android.widget.ListView;
android.widget.RadioGroup;

public class menuescolherAtividade extends


Activity
{
RadioGroup rgEscolher;
ListView lstView;

novembro 2012

25

Criamos tambm algumas variveis para serem inicializadas no evento


Oncreate() da Atividade. O RadioGroup para escolher o tipo de visualizao
do ListView e o ListView que far as devidas referncias.
@Override
public void onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.
menuescolher);
InicializaListeners();
}

A funo ListarArrayAdapter a mais importante, pois com ela que vamos atribuir os dados da classe Clientes ao ListView. Primeiramente instancie
a classe Clientes e execute o mtodo ListarClientes() atribuindo a uma varivel
do tipo List<Clientes>. Aproveite para criar outra varivel do tipo ArrayList que
ser responsvel por armazenar nossos dados. Faremos um Loop para varrer os
registros da varivel lista_Clientes para obtermos o ID e o Nome concatenado
utilizando o mtodo get().
Armazenamos em uma varivel do tipo ArrayAdapter<String>, passando
por parmetro: o contexto atual, o tipo de layout que teremos no ListView, o
Tipo de Fonte utilizada e o ArrayList com os dados concatenados. Ao compilar
e executar a aplicao, ela dever ficar idntica a Imagem 03.

No evento OnCreate() defina o Layout criado anteriormente e execute


o mtodo InicializaListeners(), o mesmo sendo responsvel por atribuir os
objetos s devidas variveis.

public void InicializaListeners()

{


rgEscolher = (RadioGroup)
findViewById(R.id.rgEscolher);


lstView = (ListView)
findViewById(R.id.lstSimples);

}


public void Listar(View v)

{

switch (rgEscolher.
getCheckedRadioButtonId())

{
case R.id.rbArrayAdapter
: ListarArrayAdapter();

break;

case R.id.
rbTheClubAdapter : ListarTheClubAdapter();
break;
}

}

J o mtodo Listar() est ligado ao evento OnClick() do boto. Nesta rotina


ser feito um Switch/case para verificar qual RadioButton foi selecionado.

public void ListarArrayAdapter()

{

Clientes clientes = new
Clientes();

List<Clientes> lista_clientes =
clientes.ListarClientes();



ArrayList<String> cli = new
ArrayList<String>();

for (int i = 0; i < lista_
clientes.size(); i++)

{
String Id_Cliente = String.valueOf(lista_
clientes.get(i).getId_Cliente();


String Nome = lista_
clientes.get(i).getNome();

cli.add(Id_Cliente + + Nome);
ArrayAdapter<String> arrayAdapter
= new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_2,
android.R.id.text1, cli);

lstView.
setAdapter(arrayAdapter);

}

}
26

novembro 2012

Imagem 03: Exemplo com ArrayAdapter.

Criando um exemplo personalizado


A Classe ArrayAdapter nos d uma gama muito grande de possibilidades
para implementar recursos personalizados ao ListView por exemplo. Nesta
parte do artigo vou criar uma classe sobrescrevendo o mtodo GetView(). Este
mtodo o responsvel por exibir os itens na tela, para isto vamos atravs
dele criar um layout em XML especfico para esta tarefa. Atravs deste arquivo
vamos Infl-lo e receber o resultado necessrio. Dividiremos este processo
em 3 etapas, sendo o primeiro responsvel pela criao do Lay-Out, seguido
pela Classe personalizada e sua devida utilizao.

1 - Criando o Lay-Out personalizado


Este lay-Out possuir campos referentes ao Nome, Cnpf/Cpf, Email, Tipo
de Pessoa e Situao do Cadastro. Para iniciar crie um arquivo XML e defina o
nome como theclubadaper.xml, Adicionando 3 TextView, 2 RadioButtons e
1 CheckBox. Ver Imagem 04.

Imagem 04: Lay-Out Sugerido.


A seguir o cdigo XML correspondente.
<?xml version=1.0 encoding=utf-8?>
<LinearLayout xmlns:android=http://
schemas.android.com/apk/res/android

android:layout_width=fill_parent
android:layout_height=70dip
android:paddingTop=5dip
android:paddingBottom=5dip
android:orientation=vertical>
<LinearLayout android:id=@+id/
linearLayout1
android:layout_width=wrap_content
android:layout_height=match_parent
android:orientation=horizontal>
<LinearLayout
android:orientation=vertical
android:layout_width=135dp
android:layout_height=match_
parent>
<TextView android:id=@+id/
txtNome
android:layout_width=match_
parent
android:layout_height=20dp>
</TextView>
<TextView android:id=@+id/
txtEmail
android:layout_width=match_
parent
android:layout_height=20dp>
</TextView>
<TextView android:id=@+id/
txtCnpjCpf
android:layout_width=match_
parent
android:layout_height=20dp>
</TextView>
</LinearLayout>
<LinearLayout
android:gravity=center_vertical
android:orientation=horizontal
android:layout_width=wrap_content
android:layout_height=match_
parent>
<RadioGroup android:layout_
width=wrap_content
android:orientation=horizont
al
android:layout_height=wrap_
content

android:layout_
marginRight=15dip
android:id=@+id/radios>
<RadioButton
android:layout_height=wrap_content
android:text=Fsica
android:id=@+id/rbFisica
android:layout_width=wrap_
content
android:textSize=8dip>
</RadioButton>
<RadioButton
android:layout_height=wrap_content
android:text=Jurdica
android:id=@+id/
rbJuridica
android:layout_width=wrap_
content
android:textSize=8dip>
</RadioButton>
</RadioGroup>
</LinearLayout>
<LinearLayout
android:gravity=right|center_vertical
android:orientation=vertical
android:layout_width=40dip
android:layout_height=50dp>
<TextView android:id=@+id/
txtStatus

android:textSize=8dip
android:textAppearance=?androi
d:attr/textAppearanceSmall
android:layout_width=wrap_
content
android:layout_gravity=center_
horizontal
android:text=Ativo
android:layout_height=wrap_
content>
</TextView>
<CheckBox android:layout_
width=wrap_content
android:id=@+id/cxSituacao
android:layout_height=wrap_
content>
</CheckBox>
</LinearLayout>
</LinearLayout>
</LinearLayout>

2 - Criando a Classe theclubAdapter.java


Para criar a classe theclubAdapter.java siga os mesmos passos descritos anteriormente clicando com o boto direito no item New/Class.
Importe os pacotes necessrios e em seguida faa a herana para a classe
ArrayAdapter<Clientes> para implementar os mtodos necessrios. Segue
o cdigo fonte comentado.
package pct.Android_ListView;
import
import
import
import
import
import
import
import
import

java.util.List;
android.content.Context;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
android.widget.ArrayAdapter;
android.widget.CheckBox;
android.widget.RadioButton;
android.widget.TextView;

public class theclubadapter extends


ArrayAdapter<Clientes>
{
private final LayoutInflater inflater;
private final int recursoId;

Variveis utilizadas ao decorrer da implementao, sendo a primeira responsvel por montar o Layout do ListView e a segunda sendo uma identificao
do theclubadapter.XML.
public theclubadapter(Context context, int
resource, List<Clientes> objects)
{

super(context, resource, objects);

this.inflater = LayoutInflater.
from(context);

this.recursoId = resource;
}

No constructor da classe passamos alguns parmetros responsveis respectivamente pelo Contexto, Identificao do Lay-out XML e a Lista contendo
os dados dos Clientes.

@Override
public View getView(int position, View
novembro 2012

27

convertView, ViewGroup parent)


{
Clientes cliente =
getItem(position);

convertView = inflater.
inflate(recursoId, parent, false);
TextView txtNome = (TextView) convertView.
findViewById(R.id.txtNome);
TextView txtEmail = (TextView)
convertView.findViewById(R.id.txtEmail);
TextView txtCnpjCpf = (TextView)
convertView.findViewById(R.id.txtCnpjCpf);
RadioButton rbFisica = (RadioButton)
convertView.findViewById(R.id.rbFisica);
RadioButton rbJuridica = (RadioButton)
convertView.findViewById(R.id.rbJuridica);
CheckBox checkSituacao = (CheckBox)
convertView.findViewById(R.id.cxSituacao);


txtNome.setText(cliente.getNome());

txtEmail.setText(cliente.
getEmail());

txtCnpjCpf.setText(cliente.getCnpj_
Cpf());


if(cliente.getTipo_Pessoa() == J)

{

rbJuridica.setChecked(true);

}

else

{

rbFisica.setChecked(true);

}


if(cliente.getSituacao() == 1 )

{

checkSituacao.
setChecked(true);

}

else

{


checkSituacao.
setChecked(false);

}


return convertView;
}
}

Efetuamos a Sobrescrita do evento GetView(), neste momento que


montamos o lay-out desejado. Utilize a classe Clientes para obter o registro e
logo em seguida utilizar o mtodo inflate, responsvel por inflar uma view
e ter acesso aos seus atributos.
Atravs da View capturada atribumos cada campo para um tipo de varivel e em seguida obtermos o resultado nestas mesmas variveis. Os campos
Nome, Email, Cnpj_Cpf apenas inserimos o valores, j para o Tipo de Pessoa
fazemos um If identificando se Jurdica ou Fsica e na Situao outro para
verificar se o cliente est ativo ou no. Por final retornamos uma View para
ser utilizada adiante.

3- Utilizando a Classe theclubAdapter.java


Esta a parte mais fcil do artigo, utilize a mesma Atividade criada para programar o primeiro exemplo e crie uma funo chamada ListarTheClubAdapter().
public void ListarTheClubAdapter()
{
Clientes clientes = new Clientes();
List<Clientes> lista_clientes = clientes.
28

novembro 2012

ListarClientes();
ArrayAdapter<Clientes> ad = new
theclubadapter(this,
R.layout.
theclubadapter, lista_clientes);
lstView.setAdapter(ad);
}

Nesta funo instanciamos a classe clientes, jogamos em uma


List<Clientes> e por final vamos fazer uso da classe theclubadapter, passando
por parmetro o contexto, o XML theclubadapter.xml e a lista de clientes. Por
ltimo atribumos a um ListView. O resultado ficar idntico ao da Imagem 05.

Imagem 05: Exemplo com TheClubAdapter.

Concluso
O ListView se torna um componente indispensvel quando trabalhamos
com o Sistema Android se comparando ao DbGrid do Delphi, o GridView do
Asp.Net. O ListView se destaca no aspecto de personalizao do Lay-Out,
sendo possvel brincar da maneira e da forma que desejarmos. Utiliza um
Adapter, que trocando em midos seria um adaptador que usa o contedo
vindo de uma fonte de dados, sendo que a mesma poder vir de diversas
origens. Espero que estes dois pequenos exemplos sirvam de base para o
conhecimento bsico aos senhores.
Abrao e at o ms que vem!

Sobre o autor
Thiago Cavalheiro Montebugnoli
Thiago Cavalheiro Montebugnoli tecnlogo, formado pela Faculdade
de Tecnologia de Botucatu SP (FATEC) foi consultor tcnico do The Club, j
desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco
de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Processamento de Dados da Prefeitura Municipal de Ita-SP. Possui as seguintes
certificaes: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer
e MCSD - Microsoft Certified Solution Developer.

thiago@theclub.com.br

Dicas DELPHI
Salvando e restaurando uma TStringGrid

// Criar o tipo TChars antes do Type From1


type
TChars = set of Char;

Listagem 1 Criando o tipo TChars


procedure TForm1.SaveGrid;
var
f: TextFile;
x, y: Integer;
begin
AssignFile(f, NomeArquivo.extensao);
Rewrite(f);
Writeln(f, StringGrid1.ColCount);
Writeln(f, StringGrid1.RowCount);
for x := 0 to StringGrid1.ColCount -1 do
for y := 0 to StringGrid1.RowCount -1
do
Writeln(f, StringGrid1.Cells[x, y]);
CloseFile(f);
end;
procedure TForm1.LoadGrid;
var
f: TextFile;
temp, x, y: Integer;
tempStr: String;
begin
AssignFile(f, NomeArquivo.extensao );
Reset(f);
readln(f, temp);
StringGrid1.ColCount := temp;
Readln(f, temp);
StringGrid1.RowCount := temp;
for x := 0 to StringGrid1.ColCount -1 do
for y := 0 to StringGrid1.RowCount -1
do
begin
Readln(f, tempStr);
StringGrid1.Cells[x, y] :=
tempStr;
end;
CloseFile(f);
end;

Separando caracteres de uma string


A Primeira coisa a fazer criar um tipo de dados denominado TChars, antes
to tipo criado para o seu formulrio, neste exemplo o nome do formulrio
Form1. Segue o exemplo na Listagem 1.

Vamos criar uma funo denominada FilterChar que retornar uma string.
O corpo da funo segue na listagem 2.

function TForm1.FilterChars(const S:
String;
const ValidChars: TChars): String;
var
I: Integer;
begin
Result := ;
for I := 1 to Length(S) do
if S[I] in ValidChars Then
Result := Result + S[I];
end;

Listagem 2 Cdigo da funo FilterChar


Para utilizar esta funo em um exemplo adicione ao seu formulrio um
Edit e dois botes, um boto retornar apenas as letras do texto digitado no Edit
e o outro boto retornar apenas os nmeros digitados. Seguem na listagem
3 os cdigos do evento onClick de ambos os botes.

procedure TForm1.Button1Click(Sender:
TObject);
begin
// Retorna apenas as letras digitadas no
edit
ShowMessage(FilterChars(Edit1.Text,
[A..Z, a..z]));
end;
procedure TForm1.Button2Click(Sender:
TObject);
begin
// Retorna apenas os nmeros digitados
no edit
ShowMessage(FilterChars(Edit1.Text,
[0..9, ,]));
end;

Listagem 3 Exemplo de utilizao da funo FilterChar


novembro 2012

29

Horizontal

30

Vertical

novembro 2012

novembro 2012

novembro 2012