the club - megazine · utilizando arquivos css3. eu particularmente gosto de novidades, mas...

32
novembro 2012

Upload: others

Post on 18-Oct-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012

Page 2: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012

Page 3: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 03

Desafio The ClubDicas

30

C# Android

DelphiDelphi

índiceFireMonkey - Formulário base de cadastro com barra

de ferramentas - Parte I

Editorial

1204Delphi – Parte VIII

05Linguagem C# - Criando um Componente TextBox

personalizado

18

28

24

LegendaInicianteIntermediárioAvançado

Autor: Lucas de Oliveira

Autor: Marcos C. Silva

Autor: Luciano Pimenta

Autor: Thiago C. Montebugnoli

Android - Aprendendo a utilizar o ListView

Page 4: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201204

Bem-vindo

Delphi© é marca registrada da Embarcadero Technologies®™, as demais marcas citadas são registradas

pelos seus respectivos proprietários.

Thiago Montebugnoli - Editor [email protected]

Olá amigos do The Club, no final do mês de Outubro aconteceu a tão esperada “Embarcadero Delphi Conference”.

Nós estivemos por lá prestigiando este grande evento e pudemos assistir a várias palestras. Para compartilhar com vocês, nesta edição, estamos trazendo um pequeno artigo onde poderão conferir mais detalhes a respeito desta Conferência.

A revista deste mês conta ainda com outros artigos: nosso con-sultor técnico Lucas de Oliveira continua com a série de artigos relacionados ao FireMonkey, onde aborda como trabalhar com um formulário base de cadastro com barra de ferramentas, procurando exemplificar passo a passo para um maior aprendizado.

Marcos César Silva nos ensina a criar um componente TextBox personalizado, colocando em prática vários conceitos importantes da Linguagem C# como Herança e Sobrescrita de Métodos.

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 série de artigos relacionados ao Android. Para quem está começando, não deixem de lê-lo, pois trata-se de um dos mais importantes componentes: o “ListView”, recurso indispensável no desenvolvimento para esta plataforma.

Aproveite também e desfrute de nossa clássica seção de “Dicas Delphi”.

Desejo a todos uma boa leitura e um Forte abraço,

Av. Profº Celso Ferreira da Silva, 190 Jd. Europa - Avaré - SP - CEP 18.707-150

Informações e Suporte: (14) 3732-1529

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informações: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club 2012

Diretor TécnicoMarcos César Silva

DiagramaçãoEduardo Massud

ArteVitor M. Rodrigues

RevisãoCíntia Amaral

ColunistasMarcos César Silva

Thiago Cavalheiro MontebugnoliLucas de OliveiraLuciano Pimenta

Impressão e acabamento:GRIL - Gráfica e Editora

Taquarituba-SP - Tel. (14) 3762-1345

ReproduçãoA utilização, reprodução, apropriação, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criações intelectuais em cada publicação da revista “The Club Megazine” são terminantemente proibidos sem autorização escrita dos titulares dos direitos autorais.

Page 5: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 05

DELPHI

Embarcadero Delphi Conference 2012 O The Club esteve lá!

P rimeiramente gostaria de parabenizar toda a equipe do evento pela organização e estrutura oferecida aos desenvolvedores ali presentes. O evento aconteceu terça-feira, no dia 23 de Outubro em São Paulo no Centro de Convenções Rebouças. Para quem não conhece ou não sabe, este é um evento Oficial promovido pela própria Embarcadero e não gera custo algum pela participação da pessoa interessada. O evento disponibilizou 5 salas simultâneas 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 tópicos da conferência.

No primeiro horário escolhemos para assistir a palestra de abertura do Senhor David I e Michael Swindell, tendo como título “Indroducing HTML 5 Buil-der”. Foram discutidas diversas características desta nova ferramenta que tem como objetivo customizar aplicações das plataformas (Android, Mac, Windows) utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas e em um prazo muito longo de tempo por não se tratar de ferramentas indispensáveis para a maioria dos desenvolvedores.

Samuel David fala sobre a integração do Google Maps usando o Delphi XE 3. Discute um pequeno exemplo para aplicações desktop utilizando um compo-nente chamado TChromium. Particularmente achei interessante esta integração de uma forma rápida e prática, demonstrando algumas das funcionalidades do XE 3 com o Google.

Já Guinther Pauli, tendo como título de sua palestra “Aplicações Corporativas para Web com Asp.Net”, discutiu uma boa parte do tempo sobre as evoluções do Asp.Net, falou um poucos das versões do Framework, dando dicas e macetes para a platéia. 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, Repositório e Portal” foram abordados várias funcionalidades do ER/Studio, ferramenta responsável pela modelagem lógica e física de sistemas. O palestrante montou exemplos práticos e de fácil enten-dimento envolvendo ETL (Extract, Transform and Load), auditoria de informações, entre outros, proporcionando aos ouvintes o conhecimento um pouco mais avançado dos recursos oferecidos.

Com a chegada do Windows 8 não poderíamos deixar de conferir como fica a situação 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 compatível com esta versão 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. Conhece-mos também outras ferramentas como o HTML Builder 5, e recursos novos como: Aplicações em Windows 8, Aplicações para Mac, Android, Windows Phone, Aplicações para Web entre outras.

Logo abaixo segue o site oficial com as palestras, seguin-do por seus palestrantes e separadas por sala.

http://www.delphiconference.com.br/

Um forte abraço e até a próxima “Embarcadero Delphi Conference”. Imagem 01: Auditório Principal.

Page 6: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201206

Delphi Parte VIII

Vimos no artigo anterior, um pequeno exemplo de como a POO pode ajudar a construir aplicações 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 próprios 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 aplicações terem performances, sempre bati na tecla da parame-trização de dados, ou seja, os dados que são mostrados em tela devem ser a

menor quantidade possível, como já vimos no decorrer da nossa série, usando herança visual de formulários.

Em uma aplicação, a quantidade de consultas auxiliares é bastante gran-de, ou seja, pesquisa de clientes, fornecedores, produtos etc, além de serem utilizadas em vários locais da aplicação.

Criar um formulário de consulta para cada uma das pesquisas torna-se tra-balhoso, então por que não criar um componente para essas consultas. Nossa aplicação, 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 faríamos? A criação de um componente de pesquisa visa corrigir esse problema, para não criarmos várias telas de pesquisa.

Page 7: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 07

Inciando a construção

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

Imagem 1. Criando o pacote do componente

Salve o pacote com o nome de “pkLocalizar. dproj”.

Criando o formulário

Teremos de criar o formulário de pesquisa, que deve conter os controles de tela para digitar o texto, botão de pesquisa e um grid onde serão mostrados os dados, além 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 código, outro para pesquisa por uma descrição (nome, titulo etc). Crie um novo formulário no pacote e adicione os controles, veja na Imagem 2 como será o formulário de pesquisa.

Imagem 2. Formulário de pesquisa

No código do formulário devemos criar alguns métodos e propriedades, conforme o código a seguir:

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

Nota: Caso deseja, você pode criar uma coleção para ter vários tipos de pesquisa, como por exemplo, a propriedade Collumns do DBGrid. De acordo com essa coleção, dinamicamente, você poderia criar os itens do RadioButton da tela anterior. Fica como pesquisa para incrementar o componente.

No código anterior, criamos a assinatura de um método que será respon-sável por realizar a consulta (Buscar) e uma função, para retornar o código retornado pela consulta. Além disso, temos que criar uma propriedade do tipo TClientDataSet, responsável por ter os dados da consulta.

Caso deseja, mude para o controle que utiliza para trabalhar com dados locais (IBQuery, Query etc). As outras duas propriedades indicam o código SQL para a consulta por código ou por descrição, assim basta conImagemr a propriedade do Localizar, para ter a consulta parametrizada no componente.

O código do Buscar, simplesmente, repassa pro ClientDataSet o valor do Edit (edtLocalizar), onde o usuário digitará o valor de busca. No caso, temos que verificar qual o tipo de filtro escolhido pelo usuário, para poder conImagemr no DataSet o respectivo comando SQL da Listagem 1.

Listagem 1. Verificando o filtro escolhido

FDataSet.Close;if (rgLocalizar.ItemIndex = 0) thenbegin FDataSet.CommandText := FSQLCodigo; FDataSet.Params[0].AsInteger := StrToInt(edtLocalizar.Text);endelsebegin FDataSet.CommandText := FSQLDescricao; FDataSet.Params[0].AsString := ‘%’ + edtLocalizar.Text + ‘%’;end;FDataSet.Open;

O código do GetCodigo, para retornar o campo chave da tabela, é bastante simples, onde retornamos o primeiro campo (Field) do ClientDataSet.

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

Page 8: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201208

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 código do SetDataSet fica conforme o código a seguir:

if FDataSet <> Value thenbegin FDataSet := Value; DataSource1.DataSet := FDataSet;end;

No código, atribuímos 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 código para que fiquem com um tamanho especifico, fonte etc.

Para isso, criamos um método que realiza essa funcionalidade. Veja na Listagem 2.

Listagem 2. Método para conImagemr as duas colunas do grid.

var i : integer;begin{ conImagem as duas colunas do Grid}if Assigned(FDataSet) thenbegin grdLocalizar.Columns[0].Title.Caption := ‘Código’; 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ê especi-ficar. Entende-se que duas colunas são necessárias, pois vamos, em quase sua totalidade, retornar apenas código e uma descrição, mas você pode adaptar para retornar quantas colunas quiser.

Apenas lembrando que o formulário é genérico, deve atender a qualquer tipo de consulta, então, devemos pensar sempre no mais comum para o formulário.

Codificando o formulário

Para os botões, que vão indicar se devemos confirmar o item selecionado no DBGrid ou cancelar o formulário (fechando-o), devemos chamar o Close, e a seguir, conImagemr o ModalResult, que para o botão OK, será mrOK e Cancelar como mrCancel.

Veremos adiante, o motivo de usarmos o ModalResult. No evento On-DblClick do DBGrid, devemos usar o mesmo código do botão OK, apenas verificando antes se existem registros na consulta, verificando a propriedade RecordCount do FDataSet. Assim, o usuário pode dar um duplo clique no grid e o mesmo será fechado.

No OnDataChange do DataSource, vamos habilitar o OK, apenas se existi-rem registros no ClientDataSet, ou seja, mais uma validação que fizemos para não termos problemas com o componente:

btnOk.Enabled := FDataSet.RecordCount > 0;

Para finalizar o formulário, precisamos tratar o evento OnKeyPress do edtLocalizar, usando o código da Listagem 3.

Listagem 3. Código 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 código anterior, primeiramente, verificamos se foi apertado a tecla ENTER. Após, verificamos se o Edit não está vazio, isso é bom para que uma pesquisa muito grande não seja executando, trazendo lentidão ao sistema.

Poderíamos ainda, colocar uma quantidade mínima de caracteres a serem digitados para que o usuário chegue o mais perto possível do que está procurando. Após verificarmos se a propriedade DataSet não está vazia,

Page 9: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 09

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, não emite o bip característico do sistema operacional. Com essa conImagemção, o formulário de consulta está pronto. Alguns retoques a mais poderiam ser feitos, como conImagemr as colunas do DBGrid para que fiquem centralizadas pelo código e alinhadas a esquerda com o texto.

Quando o usuário apertar ESC, podemos fechar o formulário, ou ainda, quando o usuário apertar ENTER no DBGrid o mesmo fechar como se fosse clicado o botão OK. Isso são funcionalidades simples, que deixarei a cargo do leitor, mas a versão para download possui essas funcionalidades.

Criando o componente

Agora, precisamos criar uma unit, que receberá mais propriedades que serão repassadas ao formulário no momento de sua criação em memória, assim como também fazer o registro do componente no Delphi.

Crie uma nova unit e adicione o código 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

FDataSet write SetDataSet; property SQLCodigo: string read FSQLCodigo write SetSQLCodigo; property SQLDescricao: string read FSQLDescricao write SetSQLDescricao; end;

procedure Register;

implementation

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

No código, criamos uma classe TLocalizar, descendente de TComponent. Na seção private temos variáveis, uma referente a propriedade publicada DataSet (seção published) que teremos e outra referente ao formulário criado neste artigo, e ainda as variáveis referentes as propriedades SQL.

O SetDataSet conImagem a propriedade e sua implementação é bem sim-ples, onde apenas precisamos conImagemr a propriedade DataSet e verificar se o formulário está criado, através do FFormLocalizar. As propriedades dos comandos SQL também são simples, basta conImagemr as mesmas como a padronização de propriedades.

Na seção protected, precisamos implementar o Notification, que é responsável, por atribuir nil a propriedade DataSet, quando por exemplo o ClientDataSet associado a mesma, por excluído.

Isso evita erros no IDE do Delphi. Sua implementação usa o seguinte código:

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

Continuando o código da Listagem 4, na seção public temos duas funções. A primeira, Execute, indicará se houve algum registro escolhido no formulário, assim podemos repassar para a consulta principal, o valor do registro.

A segunda retorna o valor da chave primária do registro escolhido no grid do formulário, onde simplesmente, chama o GetCodigo da variável FFormLocalizar.

Por fim, o Register (abaixo de implemetation), registra na Component Pallete do Delphi, onde passamos como parâmetro o nome, a paleta e a classe do componente.

Page 10: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201210

Chamando o formulário de pesquisa

O Execute, é o principal método 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 imple-mentação do método.

Listagem 5. Método 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;

O código é bastante simples, primeiro verificamos se o ClientDataSet vinculado ao componente esta ativo, se não “abrimos” o mesmo.

A seguir, instanciamos o formulário de pesquisa, repassamos as proprie-dades e chamamos o ShowModal.

O resultado do Execute, será de acordo com o ModalResult do formulário, ou seja, caso seja mrOK foi selecionado algum registro na consulta, senão, nenhum registro foi selecionado.

Por isso, conImagemmos nos botões do formulário o ModalResult.

Por fim, no finally, liberamos o formulário da memória. Para finalizar, toda a criação 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 3. Componente instalado no Delphi

Colocando um ícone no componente

Para adicionarmos um ícone do componente, precisamos editar um ar-quivo DCR e adicionar no pacote. Caso esteja usando uma versão 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 botão direito em Contents e escolha New>Bitmap. Escolha uma imagem de tamanho 24x24 (use SuperVGA nas opções de cores). Após criar, de um duplo clique Bitmap1 e crie ou cole uma imagem de sua preferência. Após adicionar a imagem, renomeie o arquivo Bitmap1 para “TLOCALIZAR”.

Para versões mais novas, o Image Editor não acompanha o Delphi, então 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 opção Bitmap e clique em OK. Nas pro-priedades 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 conImagemções.

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 extensão DCR). Voltando ao Delphi, no source do pacote (DPK), adicione o código que irá adicionar o arquivo:

{$R *.dcr}

Poderíamos também indicar o nome do arquivo sem a utilização da más-cara. Agora, basta recompilar a aplicação e seu componente terá um novo ícone (Imagem 5).

Testando o componente

Agora, precisamos testar o componente. Vamos criar um projeto de testes e depois usaremos o Localizar no projeto da nossa série. Crie um novo projeto

Page 11: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 11

e crie uma conexão com um banco de dados, usando dbExpress ou qualquer outra suíte de componentes para acesso a dados. Nosso principal componente é o ClientDataSet.

Crie uma conexão 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 conexão criada para o formulário. Arraste a tabela Customer para o formulário, para ser criado um SQLDataSet.

Adicione também um DataSetProvider e modifique para True a proprie-dade Options>AllowCommandText, assim indicamos que o responsável por receber as consultas (instruções SQL) é o próprio ClientDataSet.

Adicione dois ClientDataSets ao formulário (“cdsEmployee” e “cdsBusca-Employee”). No cdsEmployee configure o CommandText para: “select * from EMPLOYEE where EMP_NO = :EMP_NO”.

Estamos selecionando todos os dados da tabela, mas parametrizando a mesma pelo código, assim nossa consulta retornará todos os registros, apenas quando indicarmos o valor do parâmetro. Você pode fazer sub-consultas, joins nessa consulta, que não 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 código e nome da tabela Employee, parametrizando pelo nome, que será conImagemdo no nosso componente.

Não esqueça de conImagemr os parâmetros nos dois ClientDataSets. Adi-cione um Localizar no formulário 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 formulário para que o mesmo fique semelhante a Imagem 6. Adicione também um botão para chamar o Localizar.

Agora, simplesmente, precisamos usar o seguinte código no botão:

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

Veja que o código é bem simples, onde verificamos se foi escolhido algum registro no formulário de consulta, usando o Execute. Após, simplesmente, conImagemmos o parâmetro da consulta com o valor retornado pelo com-ponente (ReturnValue).

Com isso, temos um componente de pesquisa que pode ser reaprovei-tado em vários formulários usando o mesmo componente de dados. Veja o mesmo em execução na Imagem 7, onde temos uma pesquisa pelo nome e outra pelo código.

Imagem 7. Testando o componente

Usando na aplicação

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 genérica. Vamos modificar para usar o nosso componente de pesquisa.

Adicionar três Localizar no formulário e faça a ligação da propriedade DataSet com os respectivos ClientDataSets de pesquisa.

Veja na Listagem 6 o valor das propriedades dos componentes e o código dos botões para chamar o componente de pesquisa e fazer as conImagemções necessárias.

Listagem 6. Alteração do código dos botões

Imagem 5. Novo ícone do componente

Imagem 6. Formulário de cadastro para teste

Page 12: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201212

Localizar Cliente

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

Botão Cliente

if (locCliente.Execute) then nCdCliente := locCliente.ReturnValueelse DMPesquisa.cdsPesquisaCliente.Close;

Localizar Empregado

SQLCodigo

select nCdEmpregado, sNmEmpregado from EMPRE-GADO where nCdEmpregado =:nCdEmpregadoSQLDescricao = select nCdEmpregado, sNmEmpregado from EMPREGADO where UPPER(sNmEmpregado) like :sNmEmpregado

Botão Empregado

if (locEmpregado.Execute) then nCdEmpregado := locEmpregado.ReturnValueelse DMPesquisa.cdsPesquisaEmpregado.Close;

Localizar Produto

SQLCodigo

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

Botão Produto

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

Veja a redução drástica de linhas de código que tivemos. Podemos ainda alterar nosso código existente para substituir as variáveis pelos métodos do Localizar. Por exemplo: não precisamos mais usar o nCdCliente e sim apenas o locCliente.ReturnValue. Só vantagens usando um controle de tela criado.

Veja na Imagem 8 a aplicação usando o Localizar.

Imagem 8. Usando o Localizar no formulário de vendas

Conclusão

Vimos neste artigo como podemos criar componentes que nos auxilie em aplicações client/server para ser utilizado em consultas auxiliares, poupando tempo de programação e diminuição de código. Poderíamos usar formulários com a mesma finalidade, mas o componente tem facilidade de ser instalado e estar disponível 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 abraço a todos!

É Técnico em Processamento de Dados, desenvolvedor Delphi/C# para aplicações Web com ASP.NET e Windows com Win32 e Windows Forms. Palestrante da 4ª edição da Borland Conference (BorCon).

Autor de mais de 60 artigos e de mais de 300 vídeos aulas publicadas em revistas e sites especializados. É consultor da FP2 Tecnologia (www.fp2.com.br) onde ministra cursos de programação e banco de dados. É desenvolvedor da Paradigma Web Bussi-ness em Florianópolis-SC.

Sobre o autor

Luciano Pimenta

www.lucianopimenta.net

Page 13: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 13

Formulário 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 práticas utilizadas no dia a dia de desenvolvimento na já tradicional plataforma VCL. Nos próximos artigos vamos continuar com esta ideia, mostrando algumas adaptações a serem feitas para utilizar a plataforma Firemonkey, e além de se utilizar das mesmas técnicas da VCL, ainda poder incremen-tar a interface de sua aplicação com os mais variados recursos visuais do FireMonkey.

Neste artigo mostraremos como criar um formulário base para telas de cadastro, com uma barra de ferramentas para navegação entre registros. Este formulário servirá de base para a criação de outros formulários de cadastro, ele não será exibido na aplicação, apenas servirá para manter um layout padrão de seus formulários, além é claro de centralizar os códigos mais comuns em formulários deste tipo, reutilizando-os nos formulários que utilizarem este como base.

Os formulários que herdarem este formulário base herdarão além do layout, que manterá um padrão para todos os formulários de cadastro, herdará também os seus códigos, e isto é muito importante, porque assim cada novo formulário pode se preocupar apenas com os seus códigos específicos, pois

os códigos comuns já estarão prontos.

Este primeiro artigo focará na criação do formulário base e na criação da barra de navegação entre os registros. Então sem mais delongas vamos à criação 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 através 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 diretório, Fire-Monkey_FormBase. Nesta pasta serão salvos os todos os arquivos do projeto.

Criando o formulário base de cadastro

Com a unPrincipal e o projeto já salvos, criaremos agora o formulário que servirá como base para novos formulários do projeto. Crie um novo Firemonkey HD Form – Delphi através 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 formulário renomeie para frmFormBase, assim podere-mos identifica-lo mais facilmente.

Agora vamos adicionar os componentes que iremos utilizar neste formulário.

Page 14: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012

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:

Tabela 1 – Propriedades dos componentes TSpeedButtons

Como podemos perceber na tabela 1 no FireMonkey, não tem a propriedade

Caption nos componentes como na VCL, a sua substituta é a propriedade Text. Como podemos ver, distribuímos sequencialmente um número para cada um dos botões em sua propriedade Tag, isto servirá para identifica-los genericamente mais tarde.

Disponha os componentes no formulário como mostra a Imagem 1.

Imagem 1 – Sugestão de layout para o formulário base

No FireMonkey, como na plataforma VCL, tem um recurso onde um objeto do layout do formulário pode controlar algumas propriedades de outros objetos ,desde que estes façam 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 não poderão executar nenhuma ação mesmo que estejam habilitados, até que o objeto pai seja habilitado novamente. A diferença é que na plataforma FireMonkey, este recurso não se limita apenas à componentes containers como TPanels e TGruopBox por exemplo, no Fire-monkey 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 também devem ser inde-pendentes um do outro, ou seja, nenhum deve controlar o outro.

Caso algum botão seja filho de outro na hierarquia deve-se deixa-lo como filho da ToolBar, pois cada botão terá uma ação diferente na navegação dos registros e dependendo da ação de um botão os outros poderão ficar desa-bilitados, por isso se faz necessário 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á estão devidamente alocados no layout do for-mulário, vamos agora adicionar os componentes de acesso a dados. Devemos lembrar que por se tratar de um formulário base, ele não fará nenhum vinculo direto com banco de dados, porém, deverá fornecer uma estrutura para tal função, aos formulários que receberem sua herança.

Adicione um TDataSetProvider (DataAccess), um TClientDataSet (DataAc-

cess), um TDataSource (DataAccess), um TBindScopeDB (LiveBindings) e um TBindingList (LiveBindings). Siga a tabela 2 para fazer a conImagemção destes cinco componentes.

Tabela 2 – Propriedades dos componentes de acesso a dados

Explicando o funcionamento dos componentes de acesso a dados no formulário

No geral o trio de componentes de acesso a dados (SQLDataSet, Data-SetProvider e ClientDataSet) são alocados em um DataModule, e ligados aos formulários através de um DataSource.

Porém a ideia apresentada neste artigo é de deixar um ClientDataSet já com as conImagemções básicas de ligações já realizadas. Outra vantagem deste método é que os códigos do ClientDataSet serão conImagemdos no próprio Formulário, facilitando a visualização dos códigos do mesmo.

No Delphi 7 esta mesma técnica se faz sem a necessidade de trazer ao formulário junto com o ClientDataSet o DataSetProvider. Porém fazia uso de um componente da palheta DataSnap chamado TLocalConnection.

Este componente era adicionado ao DataModule, no ClientDataSet bas-tava informar na propriedade RemoteServer o componente TLocalConnection presente no DataModule, e o ClientDataSet visualizará o DataSetProvider como se estivesse no Próprio DataModule.

No Delphi XE2 não tem o componente TLocalConnection, e é por isso que o DataSetProvider veio junto com o ClientDataSet ao formulário, para manter o mesmo método utilizado no Delphi 7.

Desta forma no DataModule, iremos ter apenas o componente que faz a conexão com o banco de dados, TSQLConnection, e o componente que

Imagem 2 – Alterando a hierarquia dos objetos do formulário

Page 15: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201214 15

acessa individualmente cada tabela do banco de dados, TSQLDataSet, ambos da palheta DBExpress.

Explicado o porquê de tantos componentes de acesso a dados no formu-lário, vamos então explicar rapidamente a conImagemção deles.

O dspBase (TDataSetProvider) não terá nenhum valor mesmo na proprie-dade DataSet, pois este será preenchido pelo formulário que receber a herança do frmFormBase, outra propriedade a ser alterada é a Options/poAllowCom-mandText, esta permitirá que o ClientDataSet execute consultas SQL na base de dados, por fim, para melhorar a performance das transações de alteração e exclusão, foi alterada a propriedade UpdateMode para upWhereKeyolny, que significa que apenas realizará as atualizações pelas primary keys.

O cdsBase (TClientDataSet) apenas fará a ligação com o dspBase através da propriedade ProviderName. O dsBase (TDataSource) deve fazer ligação com o cdsBase, através de sua propriedade DataSet.

Como foi visto nos artigos anteriores sobre FireMonkey, esta plataforma não possui o grupo de componentes da palheta DataControls, e é por este mesmo motivo que foi agregado ao Delphi à tecnologia LiveBindings (ligações ao vivo), em suma esta tecnologia permite manipular as propriedades de componentes visuais em tempo de execução, 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 es-copo de binding próprio para a ligação com o banco de dados, esta é a função do BindScopeDBBase (TBindScopeDB), deve-se informar qual DataSource ele manipulará através da propriedade DataSource, neste caso é o dsBase.

Por fim, o BindingList (TBindingList) não terá nenhuma conImagemção, mas sua a função é de suma importância para os próximos formulários, pois é nele que serão listados todos os BindingLinks e as LiveBindings do formulário. Tanto o BindScopeDBBase quanto o BindingList são do grupo de componentes da palheta LiveBindings.

Definindo variáveis públicas para o frmFormBase

As variáveis públicas serão preenchidas pelos formulários que receberem a herança do frmFormBase, estas variáveis possibilitarão a manipulação dinâmica do código, a partir delas manipularemos o código base dos botões e outros procedimentos que serão comuns em formulários de cadastro.

Como mencionado estas serão variáveis públicas, ou seja, serão declaradas na sessão pública da unit. Veja na tabela 3 a lista das variáveis públicas que serão utilizadas do frmFormBase.

A maioria destas variáveis servirá como parâmetro para a chamada de um formulário de pesquisa. Vamos utilizar como exemplo o formulário de pesquisa criado no artigo “FireMonkey - utilizando mestre-detalhe e formu-lário pesquisa - parte II” da revista The Club do mês de outubro deste ano, o conteúdo desta revista também pode ser acessado na sessão de revistas do site oficial da revista The Club (www.theclub.com.br).

Você pode seguir o artigo para criar o formulário de pesquisa neste projeto ou caso já tenha construído o formulário de pesquisa em outro projeto, basta copiar os arquivos unPesquisa.pas e unPesquisa.fmx para o diretório deste projeto, e depois adicionar ao projeto usando o menu (Project / Add to Project)

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 cláusula Uses da unFormBase. Veremos posteriormente como passar os parâmetros ao frmPesquisa.

As duas primeiras variáveis, SQL_PADRAO E TABELA, farão o revezamento no código, ou seja, se informar a SQL_PARAO não precisa informar a TABELA e vice-versa, isso quer dizer que quando tiver uma SQL_PADRAO informada, o código fará a manipulação de SQL através dela, caso não tenha, o código mani-pulará uma SQL mais simples utilizando o nome da tabela informado na variável TABELA. Percebe se que a utilização da primeira variável, SQL_PADRAO, se faz necessário 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 variável GEN_NAME armazenará o nome do Generator responsável por armazenar o valor da chave primária da tabela base.

Com esta variável, será possível fazer uso de uma função de auto-incre-mento para as chaves primárias, que estará acessível neste formulário. Para poder acessar o banco de dados genericamente, foi criado a variável CONEXAO do tipo TSQLConnection. Para utilizar o componente TSQLConnection é preciso declarar na sessão uses a biblioteca Data.SqlExpr a qual ela pertence.

A variável FOCO se encarregará de jogar o foco automático para o objeto a ela atribuído.

Criando os métodos para o funcionamento da barra de navegação

Criaremos dois métodos para realizar a tarefa de dar mobilidade á barra de fer-ramentas, como vimos anteriormente, nossa barra de ferramentas possui 12 botões identificados pelas suas propriedades Tag. O que teremos que fazer é, por exemplo, desabilitar alguns botões dependendo da ação que está sendo executada no formulário.

O primeiro método é uma função, que retornará um valor booleano que se refere ao estado que o botão deverá assumir conforme a sua tag, a função se chama EstadoBotao. Veja na listagem 1 como é feita a sua declaração na sessão pública da unit e o corpo do código.

// DECLARAÇÃO DA FUNÇÃOpublic { Public declarations } function EstadoBotao(Sender : TObject; DS : TDataSource): Boolean;// CORPO DA FUNÇÃOfunction 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])

Page 16: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201216

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 // PRÓXIMO 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 – Função EstadoBotao

Ao observar o código da função, percebe-se que ela verifica quais estados os botões, identificados pela sua propriedade Tag, podem assumir referente ao estado atual do DataSet ligado ao DataSource passado como parâmetro.

Esta função será utilizada pelo próximo método que é um procedimento, de nome ControlaBotoes, ele executará a ação de habilitar e desabilitar cada botão, a partir do resultado obtido pela função EstadoBotao.

Ele deve estar declarado na sessão pública logo abaixo da declaração da função EstadoBotao. Veja na listagem 2 o exemplo do seu código.

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 :=

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 métodos juntos, farão a manipulação do estado dos botões, como ativá-los ou desativá-los.

Porém ainda não fizemos a chamada destes métodos, eles devem ser chamados toda vez que tiver alguma alteração no estado do dataset.

Sendo assim vamos fazer a chamada do procedimento no evento onData-Change do dsBase (TDataSource), veja na listagem 3 como é feito a chamada deste método.

procedure TfrmFormBase.dsBaseDataChange(Sender: TObject; Field:

TField);begin ControlaBotoes;end;

Listagem 3 – Fazendo a chamada do procedimento no evento onData-Change do dsBase

Configurando as ações de cada botão

Outro componente que é comumente utilizado na VCL é o TActionList, principalmente para centralizar as ações de botões. Porém, este também não está disponível na plataforma FireMonkey, portanto iremos manipular as ações dos botões da barra de ferramentas a partir do evento onClick do botão sbIncluir, depois disso basta vincular este evento (procedimento) a todos os demais botões. Veja na listagem 4 a implementação do código.

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

Tabela 3 – Lista de variáveis públicas do frmFormBase

Page 17: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 17

cdsBase.Edit; if (Assigned(FOCO)) then TControl(FOCO).SetFocus; end; 4: begin if MessageDlg(‘Confirma a exclusão?’, TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0) = mrYes then cdsBase.Delete; end; 5: begin if MessageDlg(‘Confirma a gravação?’, TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0) = mrYes then cdsBase.Post; end;

6: begin if MessageDlg(‘Cancelar edição?’, 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);

if (SQL_PADRAO <> ‘’) then frmPesquisa.SQL_PADRAO := SQL_PADRAO else frmPesquisa.TABELA := TABELA;

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

Listagem 4 – Definindo as ações de cada botão no evento onClick do sbIncluir

A primeira verificação que fazemos neste evento é se o parâmetro Sender é um componente da classe TSpeedButton. Sendo assim, utilizamos a classe TSpeedButton utilizando o parâmetro Sender para recuperarmos o valor de sua Tag, dentro do método Case Of.

Assim passamos qual o procedimento a ser tomado dependendo do botão clicado, identificados pelo valor de sua Tag.

Se for o botão excluir, gravar ou o cancelar, faremos uma verificação uti-lizando o método nativo do Delphi MessageDialog, exibindo uma mensagem de confirmação para o usuário e dependendo de sua resposta executa a ação do botão.

Outra observação é no botão de pesquisar, Tag 12. É nesta parte que pas-samos os parâmetros globais para o frmPesquisa, observe que após criarmos o form em memória já passamos todos os parâmetros a ele, depois é só chamá-lo pelo método ShowModal, por fim, eliminá-lo da memória.

Lembrando que o formulário de pesquisa utilizado como exemplo, é o mesmo que foi criado no artigo de Firemonkey da revista The Club do mês de outubro de 2012, não foi alterado nada, apenas foi adicionado a este projeto da forma como foi criado.

Após adicionar o código da listagem 4 no evento onClick do sbIncluir, basta amarrar este evento a todos os demais botões. Uma forma bem simples de se fazer isto é pressionar a tecla Shift e clicar em cada botão 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 opção sbIncluirClick, feito isso dê um duplo clique no evento para finalizar a amarração, se der certo, o cursor do mouse ficará piscando na primeira linha do procedimento sbIncluirClick na unit.

Até este momento nosso projeto possui três units, unPrincipal, unForm-Base e unPesquisa. Nossa barra de ferramentas está pronta e totalmente funcional, porém, continuaremos com este projeto no próximo artigo, onde descreveremos mais alguns métodos comuns para um formulário de cadastro.

Conclusão

Neste artigo foi mostrado a primeira parte de como criar um formulário base de cadastro, o foco neste artigo foi como construir a barra de ferramentas do formulário base, vimos as adaptações a serem realizadas se comparadas com a plataforma VCL, e também o porque de trazer o componentes TClien-tDataSet para o formulário unificando os códigos referentes à tabela a ser trabalhado no formulário.

O próximo artigo terá a continuação deste projeto, mostraremos mais alguns métodos padrões em formulários de cadastro e também como fazer uma herança deste formulário base. Espero que tenham gostado do que viram até aqui e que tenha sido útil de alguma forma, até o nosso próximo artigo, um abraço a todos.

Consultor Técnico The Club.

Sobre o autor

Lucas Vieira de Oliveira

[email protected]

Page 18: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201218

Linguagem C#Criando um Componente

TextBox personalizado

Muitas vezes necessitamos utilizar um componente diferente ou com alguma funcionalidade a mais em nossas aplicações, na maioria dos casos devemos rea-lizar 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 métodos até chegar ao resultado que desejamos.

Na linguagem C# isto se torna uma tarefa fácil e prática, sendo que neste artigo vou criar um “TextBox” personalizado contendo validações de CPF, CNPJ e PIS usando o método “OnValidating()”. Reescreverei métodos e propriedades como: “OnLostFocus()”, “OnGotFocus()” e ”ForeColor” para dar uma impressão um pouco mais interessante ao usuário. Será necessário também criar uma classe “Tipo” para trabalharmos com o Tipo de validação necessária.

Para esta tarefa achei mais prático utilizar um “combobox” acoplado nas suas propriedades.

Criando o Componente

Inicie o Microsoft Visual Studio e crie um novo projeto como “Class Libary”. (Não

se preocupe que disponibilizarei todo o código fonte)

Clique com o botão direito sobre a solução e escolha “Add/New Item...”. Criare-mos uma classe do início. 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 contém a classe TextBox.System.Drawing: Assembly responsável pela troca de cores dos componentes.System.ComponentModel: Classes responsáveis pela manipulação e conversão

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 herança para a classe “TextBox”. Defina também o “Constructor” e “Destructor”

Page 19: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 19

do componente. Especificamente neste artigo não precisei utilizá-los, mas recomendo sempre a criação do mesmo.

//Herança de Classespublic class TextBoxTheClub: TextBox{ //Definindo o Contructor public TextBoxTheClub() {

}

//Definindo o Destructor ~TextBoxTheClub() {

}

Vou reescrever os métodos “OnLostFocus()”, “OnGotFocus()” e a propriedade “ForeColor” sendo respectivamente responsáveis por perder o foco, receber o foco e mudar cor da fonte, que neste caso defini como “DarkBlue”.

//Sobrescrever a propriedade cor da Fontepublic override Color ForeColor{

get { return Color.DarkBlue; } set { base.ForeColor = value; }}

//Sobrescrever o evento ao receber o focoprotected override void OnGotFocus(EventArgs e){ base.OnGotFocus(e); this.BackColor = System.Drawing.Color.LightYellow;

}

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

public class Tipo : StringConverter{public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {return new StandardValuesCollection(new string[] { “CPF”, “CNPJ”, “PIS” }); }}

Foi necessário criar uma pequena classe denominada Tipo, herdando da “String-Converter”. Usaremos o “Override” do método “GetStandardValuesSupported” responsável por indicar se o conversor oferece ou não suporte a um conjunto de valores, retornando um booleano e o método “GetStandardvalues()“ que possibilita a manipulação de uma coleção de dados, que no caso específico identificamos como: CPF, CNPJ e PIS.

[TypeConverter(typeof(Tipo)), Category(“validação”)]

public string TipoValidacao{ get; set;}

Para identificarmos o tipo de validação foi necessário criar uma propriedade

“TipoValidacao” usando os operadores “Get” e “Set”, pois através deles que podemos recuperar e atribuir os valores descritos acima. Graças a esta propriedade que conse-guimos manipular as conImagemções propostas pelo desenvolvedor.

protected override void OnValidating(System.ComponentModel.CancelEventArgs e){ base.OnValidating(e);

if (this.Text.Length > 0) { if (TipoValidacao == “CPF”) {

Imagem 01: Criar uma classe para o TextBox.

Page 20: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201220

if (ValidarCpf(this.Text) == true) { MessageBox.Show(“CPF Válido!!”); } else { MessageBox.Show(“CPF Inválido!!”); this.Focus(); } } else if (TipoValidacao == “CNPJ”) { if (ValidarCnpj(this.Text) == true) { MessageBox.Show(“CNPJ Válido!!”);

} else { MessageBox.Show(“CNPJ Inválido!!”); this.Focus(); } } else if (TipoValidacao == “PIS”) { if (ValidarPis(this.Text) == true) { MessageBox.Show(“PIS Válido!!”); } else { MessageBox.Show(“PIS Inválido!!”); this.Focus(); } } }}

O evento “Onvalidating()” é executado no momento que saímos do Textbox, ou seja, o validamos. Este evento será responsável por chamar as funções de validações 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 pública “TipoValida-cao” identificando o que o desenvolvedor deseja validar. Por final chamamos a função desejada. Não entrarei em detalhes como foram montadas as funções pelo fato deste artigo abordar a criação de componentes. Segue em seguida as funções “ValidarCpf()”, “ValidarCnpj()” e “ValidarPis()”.

public static bool ValidarCnpj(string cnpj)

{ 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;

Page 21: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 21

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 Instalação

Clique com o botão direito na “Toolbox” e escolha “Choose Items...” para adicionar a .dll criada anteriormente. Imagem 03.

Imagem 03: Instalando o Componente.

No botão “Browse...” localize no diretório onde foi salvo, por exemplo:

C:\Diretorio\TextBoxTheClub\bin\Debug\TextBoxTheClub.dllVer 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 prático

Para testá-lo basta encará-lo como um TextBox comum, mas com algu-mas funcionalidades a mais. Para isto crie um novo Projeto e adicione alguns “TextBoxTheClub” no formulário. Ver Imagem 06.

Clicando nas propriedades podemos conferir o tipo de validação que foi programado. Aproveite e escolha uma de cada tipo. Ver Imagem 07.

Rodando a aplicação podemos conferir a execução das funções no evento “Onvalidating()”, a troca de cor de acordo com o foco e o tipo pré-definido da

Imagem 02: Compilando.

Page 22: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201222

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

Conclusão

A criação de componentes se torna uma prática muito recomendada na programação Orientada a Objetos, sendo muito utilizada desde o início dos tempos. O principal intuito deste artigo foi de demonstrar que através de

Consultor de Sistemas na consultoria de sistemas Da-taSmart e Consultor Técnico do The Club, Bacharel em Ciência da Computação, MBA em Gestão Empresarial, Certificações MCAD (Microsoft Certified Application Developer) e MCSD.NET (Microsoft Certified Solution Developer .NET)

Sobre o autor

Marcos César Silva

[email protected]

pequenos conceitos conseguimos economizar tempo e código no decorrer do desenvolvimento de aplicações. Abordei assuntos como: Herança de Classes, Sobrescrita de métodos e propriedades, criação de classes auxiliares e fun-ções estáticas. Existem diversas formas e mecanismos para se desenvolver um componente, procurei neste artigo simplificar o máximo possível a fim de um aprendizado maior. Fica assim, um grande abraço e até o mês que vem!

Imagem 08: Exemplo em Run-Time. Imagem 06: Criando um exemplo.

Imagem 07: Tipo de Validação (CPF, CNPJ e PIS).

Page 23: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 23

ANDROIDAprendendo 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 implementação de funções ligadas ao Banco de Dados, classes ou qualquer coleção de dados.

A documentação On-Line para o desenvolvedor Android descreve o ListView como um grupo de exibição que mostra uma lista de itens com pos-sibilidade de rolagem. Os itens da lista são automaticamente inseridos usando um adaptador que utiliza o conteúdo de uma fonte (uma consulta qualquer ou com banco de dados), convertendo cada item resultando em uma visão que por fim é mostrado ao usuário final.

Este artigo possuirá dois exemplos, o primeiro utilizando a classe ArrayA-dapter e o segundo faremos uma pequena implementação 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 serão oriundos de uma classe com alguns atributos, ou seja, não teremos nenhum Banco de Dados. É importante entender que a origem dos dados não importa neste processo. A estrutura será da conforme a tabela 1:

Para criar uma classe clique com o botão direito sobre o pacote principal escolha “New/Class” definindo como “Clientes.java”. Esta classe possuirá todas as propriedades descritas anteriormente com seus métodos “Getters and Setters”. Para criar estes métodos automaticamente, clique com o botão direito e escolha “Source/Generate Getters and Setters”. Este recurso do Eclipse possibilita a automatização de vários processos, incluindo este. Ver Imagem 01.

Imagem 01: Geração automática dos Métodos “Getters and Setters”.

Page 24: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201224

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) {

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(“[email protected]”); 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(“[email protected]”); 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(“[email protected]”); 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(“[email protected]”); 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(“[email protected]”); cliente4.setCnpj_Cpf(“366.999.888-99”); cliente4.setTipo_Pessoa(“F”); cliente4.setSituacao(“0”); lista_cliente.add(cliente4);

Page 25: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 25

Clientes cliente5 = new Clientes(); cliente5.setId_Cliente(6); cliente5.setNome(“The Club”); cliente5.setEmail(“[email protected]”); 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(“[email protected]”); cliente6.setCnpj_Cpf(“99.888.898.0001/01”); cliente6.setTipo_Pessoa(“J”); cliente6.setSituacao(“0”); lista_cliente.add(cliente6); return lista_cliente; }}

No método ListarClientes() onde alimento esta classe com alguns dados aleatórios 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 também e adicione alguns componentes: Um textBox, dois RadioButtons, Um Button e um ListView. Ver Imagem 02 do Lay-Out Sugerido.

Segue também 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=”horizontal” 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”

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 necessárias ao decorrer do desen-volvimento.

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

public class menuescolherAtividade extends Activity { RadioGroup rgEscolher; ListView lstView;

Imagem 02: Tela Principal.

Page 26: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201226

Criamos também algumas variáveis para serem inicializadas no evento “Oncreate()” da Atividade. O RadioGroup para escolher o tipo de visualização do ListView e o ListView que fará as devidas referências.

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.menuescolher); InicializaListeners(); }

No evento OnCreate() defina o Layout criado anteriormente e execute o método InicializaListeners(), o mesmo sendo responsável por atribuir os objetos às devidas variáveis.

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 método Listar() está ligado ao evento OnClick() do botão. 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); } }

A função ListarArrayAdapter é a mais importante, pois é com ela que va-mos atribuir os dados da classe Clientes ao ListView. Primeiramente instancie a classe Clientes e execute o método ListarClientes() atribuindo a uma variável do tipo List<Clientes>. Aproveite para criar outra variável do tipo ArrayList que será responsável por armazenar nossos dados. Faremos um Loop para varrer os registros da variável lista_Clientes para obtermos o ID e o Nome concatenado utilizando o método get().

Armazenamos em uma variável do tipo ArrayAdapter<String>, passando por parâmetro: 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 aplicação, ela deverá ficar idêntica a Imagem 03.

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 método GetView(). Este método é o responsável por exibir os itens na tela, para isto vamos através dele criar um layout em XML específico para esta tarefa. Através deste arquivo vamos “Inflá-lo” e receber o resultado necessário. Dividiremos este processo em 3 etapas, sendo o primeiro responsável pela criação do Lay-Out, seguido pela Classe personalizada e sua devida utilização.

1 - Criando o “Lay-Out” personalizado

Este lay-Out possuirá campos referentes ao Nome, Cnpf/Cpf, Email, Tipo de Pessoa e Situação 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 código XML correspondente.

<?xml version=”1.0” encoding=”utf-8”?><LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”

Page 27: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 27

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=”horizontal” android:layout_height=”wrap_

content” android:layout_marginRight=”15dip” android:id=”@+id/radios”> <RadioButton android:layout_height=”wrap_content” android:text=”Física” android:id=”@+id/rbFisica” android:layout_width=”wrap_content” android:textSize=”8dip”> </RadioButton> <RadioButton android:layout_height=”wrap_content” android:text=”Jurídica” 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=”?android: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 des-critos anteriormente clicando com o botão direito no item “New/Class”. Importe os pacotes necessários e em seguida faça a herança para a classe “ArrayAdapter<Clientes>” para implementar os métodos necessários. Segue o código fonte comentado.

package pct.Android_ListView;

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

public class theclubadapter extends ArrayAdapter<Clientes>{ private final LayoutInflater inflater; private final int recursoId;

Variáveis utilizadas ao decorrer da implementação, sendo a primeira res-ponsável por montar o Layout do ListView e a segunda sendo uma identificação 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 parâmetros responsáveis res-pectivamente pelo Contexto, Identificação do Lay-out XML e a Lista contendo os dados dos Clientes.

@Override public View getView(int position, View

Page 28: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201228

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 método inflate, responsável por “inflar” uma view e ter acesso aos seus atributos.

Através da View capturada atribuímos cada campo para um tipo de vari-ável e em seguida obtermos o resultado nestas mesmas variáveis. Os campos Nome, Email, Cnpj_Cpf apenas inserimos o valores, já para o Tipo de Pessoa fazemos um If identificando se é Jurídica ou Física e na Situação outro para verificar se o cliente está ativo ou não. Por final retornamos uma View para ser utilizada adiante.

3- Utilizando a Classe “theclubAdapter.java”

Esta é a parte mais fácil do artigo, utilize a mesma Atividade criada para pro-gramar o primeiro exemplo e crie uma função chamada ListarTheClubAdapter().

public void ListarTheClubAdapter(){ Clientes clientes = new Clientes();List<Clientes> lista_clientes = clientes.

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

Nesta função instanciamos a classe clientes, jogamos em uma List<Clientes> e por final vamos fazer uso da classe “theclubadapter”, passando por parâmetro o contexto, o XML theclubadapter.xml e a lista de clientes. Por último atribuímos a um ListView. O resultado ficará idêntico ao da Imagem 05.

Imagem 05: Exemplo com TheClubAdapter.

Conclusão

O ListView se torna um componente indispensável quando trabalhamos com o Sistema Android se comparando ao DbGrid do Delphi, o GridView do Asp.Net. O ListView se destaca no aspecto de personalização do Lay-Out, sendo possível “brincar” da maneira e da forma que desejarmos. Utiliza um “Adapter”, que trocando em miúdos seria um adaptador que usa o conteúdo 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 básico aos senhores.

Abraço e até o mês que vem!

Thiago Cavalheiro Montebugnoli é tecnólogo, formado pela Faculdade de Tecnologia de Botucatu – SP (FATEC) foi consultor técnico 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 Proces-samento de Dados da Prefeitura Municipal de Itaí-SP. Possui as seguintes certificações: MCP - Microsoft Certified Professional, MCTS - Microsoft Certi-fied Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

Sobre o autor

Thiago Cavalheiro Montebugnoli

[email protected]

Page 29: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012 29

Dicas DELPHISalvando e restaurando uma TStringGrid

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 formulário, neste exemplo o nome do formulário é Form1. Segue o exemplo na Listagem 1.

// Criar o tipo TChars antes do Type From1type TChars = set of Char;

Listagem 1 – Criando o tipo TChars

Vamos criar uma função denominada FilterChar que retornará uma string. O corpo da função 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 – Código da função FilterChar

Para utilizar esta função em um exemplo adicione ao seu formulário um Edit e dois botões, um botão retornará apenas as letras do texto digitado no Edit e o outro botão retornará apenas os números digitados. Seguem na listagem 3 os códigos do evento onClick de ambos os botões.

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 números digitados no edit ShowMessage(FilterChars(Edit1.Text, [‘0’..’9’, ‘,’]));end;

Listagem 3 – Exemplo de utilização da função FilterChar

Page 30: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 201230

VerticalHorizontal

Page 31: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012

Page 32: The Club - megazine · utilizando arquivos CSS3. Eu particularmente gosto de novidades, mas sinceramente tenho a certeza que ferramentas como estas serão utilizadas por poucas pessoas

novembro 2012