Você está na página 1de 128

Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte 1 - Exemplo prtico Esse artigo o primeiro de uma srie, as quais apresentam um exemplo

o prtico e simples abordando o desenvolvimento em multicamadas em C#. Cenrio: Desenvolvimento de um Sistema de Controle de Aplices de Seguros. Estes artigos atendem a solicitao de vrios leitores que pediram um exemplo do desenvolvimento em C# ao terem acompanhado a srie anterior do desenvolvimento de uma aplicao para disk-pizza feita em VB.NET. No ltimo artigo ser postado o cdigo completo. Desenvolvendo uma aplicao Multicamadas para Windows em C# Parte 1) Camada de Dados. Introduo Os aplicativos multicamadas dividem a funcionalidade em vrias camadas separadas por agrupamentos lgicos onde esto as suas funcionalidades. Esse artigo o primeiro de uma srie, as quais apresentam um exemplo prtico e simples abordando o desenvolvimento em multicamadas em C#. Estes artigos atendem a solicitao de vrios leitores que pediram um exemplo do desenvolvimento em C# ao terem acompanhado a srie anterior do desenvolvimento de uma aplicao para disk-pizza feita em VB.NET. A Programao Orientada a Objetos (POO) possibilita uma abordagem simples para a utilizao de dados usando objetos. Neste exemplo, as camadas estaro dispostas no mesmo computador, mas os conceitos e funcionalidades aqui descrios podero ser utilizadas de forma igual em ambientes distribudos. Estrura em trs camadas: A Figura 1 - Camadas da Aplicao apresenta a estrutura bsica de um aplicativo exemplo que ser desenvolvido em C# com a base de dados em SQL Server.

<!--[if !vml]--> <!--[endif]--> Figura 1 - Camadas da Aplicao

Camada de Dados: Tambm conhecida como camada de informaes, responsvel por manter os dados pertencentes ao aplicativo. Essa camada normalmente armazena dados em um sistema gerenciador de banco de dados relacional (SGBDR) (Deitel et al 2002). No exemplo que apresentado ser utilizado o SQL Server 2005, nada impede que o leitor utilize outro, desde que adapte as strings de conexo e declaraes de objetos na linguagem. recomendvel porm, que seja utilizado o SQL Server 2005 ou o SQL Server 2005 Express Edition. Camada Intermediria: A camada intermediria implementa a lgica de negcio e a lgica do controlador. Essa camada atua como intermedirio entre os dados da camada de apresentao e os clientes do aplicativo. A lgica do controlador processa os pedidos do cliente e recupera do banco de dados. A lgica de negcios representam os mtodos correspondentes as regras do negcio e garante que os dados sejam confiveis, antes que o aplicativo servidor atualize o banco de dados ou apresente os dados aos usurios. Exemplos: <!--[if !supportLists]--> <!--[endif]-->Antes de gravar os dados de um cliente no banco de dados, na camada lgica de negcios, poderia haver uma regrar para checar se a data de nascimento do cliente por exemplo no maior que a data atual. 2

<!--[if !supportLists]--> <!--[endif]-->Se os campos obrigatrios foram preenchidos com dados vlidos, etc..., Ou seja, as regras de negcio dizem como os usurios/clientes podem e no podem acessar dados do aplicativo e como os aplicativos processam os dados. (Deitel et al, 2002). Camada de Apresentao: Tambm conhecida como camada de interface com o usurio ou camada superior, que no caso do exemplo que ser apresentado so os formulrios tipo Windows, se fosse uma aplicao para Web seriam os navegadores. A camada de apresentao interage com a camada intermediria para fazer pedidos e recuperar dados da camada de dados. Ento, a camada do cliente exibe para o usurio os dados recuperados pela camada intermediria. Cenrio Sistema de Controle de Aplices de Seguros de Veculos Este visto no Diagrama de ER representa um modelo simplificado de um sistema de controle de aplices de seguro para veculos automotores. Ao examinar a Figura 2 - Sistema Controle de Aplices de Seguro - Baseado em (Guedes, 2006) percebe-se: a) Que um cliente para ser cliente efetivamente precisa possuir no mnimo uma aplice, podendo ter mais carros segurados, no entanto uma aplice pertence de forma exclusiva a um cliente. b) Que uma aplice pode ser paga em vrias parcelas. Que uma aplice refere-se a um veculo de um modelo determinado. E que esse mesmo modelo de veculo pode estar segurado em outra aplice de outro cliente. c) Que um sinistro pertece a uma nica aplice. Mas esta aplice pode ter uma ou mais sinistros ocorridos. Que o sinistro cadastrado pode ser de um tipo ou mais e representar vrios danos. Nota: Para fins didticos este modelo est simplificado, faltam campos, poderamos aplicar mais regras de normalizao, como por exemplo a marca do veculo poderia estar em uma tabela separada e assim por diante. Porm isso foge ao escopo do objetivo principal que o aprendizado do desenvolvimento em camadas. Diagrama de Entidade Relacionamento A Figura 2 - Sistema Controle de Aplices de Seguro - Baseado em (Guedes, 2006) representa o Digrama de ER explicado anteriormente.

Figura 2 -Sistema Controle de Aplices de Seguro - Baseado em (Guedes, 2006) Objetivo do primeiro artigo: Preparar a camada de dados, a qual ser acessada pelos mtodos da classe intermediria que representam a lgica do controlador, no caso do exemplo apresentado. Mo na Massa Inicie o Sql Server 2005 crie um banco de dados chamado seguros, Abra uma janela New Query e execute o script abaixo para a criao das tabelas j com os relacionamentos, se assim o desejar. Caso contrrio, se desejar criar manualmente consulte o artigo anterior que escrevi sobre a camada de dados. No Link: 4

http://www.devmedia.com.br/articles/viewcomp.asp?comp=6504 Scripts para criao das tabelas. Nota: No esquea de criar o banco com o nome seguros, para facilitar o desenvolvimento do aplicativo nos prximos artigos. USE SEGUROS SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbCliente]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbCliente]( [idCli] [int] NOT NULL, [nomeCli] [nvarchar](50) NOT NULL, [enderecoCli] [nvarchar](50) NULL, [foneCli] [nvarchar](20) NULL, [faxCli] [nvarchar](20) NULL, [obsCli] [nvarchar](max) NULL, CONSTRAINT [PK_tbCliente] PRIMARY KEY CLUSTERED ( [idCli] ASC 5

)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbDano]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbDano]( [idDano] [int] NOT NULL, [descDano] [nvarchar](50) NULL, CONSTRAINT [PK_tbDano] PRIMARY KEY CLUSTERED ( [idDano] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END 6

GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbTipo]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbTipo]( [idTipo] [int] NOT NULL, [descTipo] [nvarchar](30) NULL, CONSTRAINT [PK_tbTipo] PRIMARY KEY CLUSTERED ( [idTipo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO 7

SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbModelo]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbModelo]( [idModelo] [int] NOT NULL, [descModelo] [nvarchar](50) NOT NULL, [descMarca] [nvarchar](50) NOT NULL, CONSTRAINT [PK_tbModelo] PRIMARY KEY CLUSTERED ( [idModelo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO 8

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbApolice]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbApolice]( [idApolice] [nvarchar](8) NOT NULL, [idCli] [int] NOT NULL, [kmVeiApolice] [int] NOT NULL, [numApolice] [int] NOT NULL, [dataApolice] [datetime] NULL, [dataValApolice] [datetime] NULL, [valorApolice] [float] NULL, [idModelo] [int] NULL, [sinistroApolice] [bit] NULL, [idSinistro] [int] NULL, CONSTRAINT [PK_tbVeiculoSegurado] PRIMARY KEY CLUSTERED ( [idApolice] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] END 9

GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbParcela]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbParcela]( [nroParc] [int] NOT NULL, [idApolice] [nvarchar](8) NOT NULL, [dataVenParcela] [datetime] NOT NULL, [valParcela] [float] NOT NULL, [quitadaParcela] [bit] NULL, [quitadaData] [datetime] NULL, CONSTRAINT [PK_tbParcela] PRIMARY KEY CLUSTERED ( [nroParc] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] 10

END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tbSinistro]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[tbSinistro]( [idSinistro] [int] NOT NULL, [dataSinistro] [datetime] NOT NULL, [descSinistro] [nvarchar](50) NOT NULL, [idTipo] [int] NOT NULL, [idDano] [int] NOT NULL, CONSTRAINT [PK_tbSinistro] PRIMARY KEY CLUSTERED ( [idSinistro] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] 11

END GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbApolice_tbCliente]') AND parent_object_id = OBJECT_ID(N'[dbo].[tbApolice]')) ALTER TABLE [dbo].[tbApolice] WITH CHECK ADD CONSTRAINT [FK_tbApolice_tbCliente] FOREIGN KEY([idCli]) REFERENCES [dbo].[tbCliente] ([idCli]) GO ALTER TABLE [dbo].[tbApolice] CHECK CONSTRAINT [FK_tbApolice_tbCliente] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbApolice_tbModelo]') AND parent_object_id = OBJECT_ID(N'[dbo].[tbApolice]')) ALTER TABLE [dbo].[tbApolice] WITH CHECK ADD CONSTRAINT [FK_tbApolice_tbModelo] FOREIGN KEY([idModelo]) REFERENCES [dbo].[tbModelo] ([idModelo]) GO ALTER TABLE [dbo].[tbApolice] CHECK CONSTRAINT [FK_tbApolice_tbModelo] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbApolice_tbSinistro]') AND parent_object_id = OBJECT_ID(N'[dbo].[tbApolice]')) ALTER TABLE [dbo].[tbApolice] WITH NOCHECK ADD CONSTRAINT [FK_tbApolice_tbSinistro] FOREIGN KEY([idSinistro]) REFERENCES [dbo].[tbSinistro] ([idSinistro]) GO 12

ALTER TABLE [dbo].[tbApolice] NOCHECK CONSTRAINT [FK_tbApolice_tbSinistro] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbParcela_tbApolice]') AND parent_object_id = OBJECT_ID(N'[dbo].[tbParcela]')) ALTER TABLE [dbo].[tbParcela] WITH CHECK ADD CONSTRAINT [FK_tbParcela_tbApolice] FOREIGN KEY([idApolice]) REFERENCES [dbo].[tbApolice] ([idApolice]) GO ALTER TABLE [dbo].[tbParcela] CHECK CONSTRAINT [FK_tbParcela_tbApolice] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbSinistro_tbDano]') AND parent_object_id = OBJECT_ID(N'[dbo].[tbSinistro]')) ALTER TABLE [dbo].[tbSinistro] WITH CHECK ADD CONSTRAINT [FK_tbSinistro_tbDano] FOREIGN KEY([idDano]) REFERENCES [dbo].[tbDano] ([idDano]) GO ALTER TABLE [dbo].[tbSinistro] CHECK CONSTRAINT [FK_tbSinistro_tbDano] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tbSinistro_tbTipo]') AND parent_object_id = OBJECT_ID(N'[dbo].[tbSinistro]')) ALTER TABLE [dbo].[tbSinistro] WITH CHECK ADD CONSTRAINT [FK_tbSinistro_tbTipo] FOREIGN KEY([idTipo]) REFERENCES [dbo].[tbTipo] ([idTipo]) GO 13

ALTER TABLE [dbo].[tbSinistro] CHECK CONSTRAINT [FK_tbSinistro_tbTipo] Se tiver dvidas em como executar esse script, siga os procedimentos abaixo indicados: 1) Na janela do Microsoft SQL Server Management Studio, clique com o boto direito do mouse sobre Databases, escolha New Database...

Figura 3 - New Database... 2) Na janela New Database, digite o nome do banco de dados, seguros e em seguida clique em OK.

Figura 4 - New Database: seguros 3) Na janela do Object Explorer, clique com o boto direito do mouse sobre o banco de dados criado (seguros) e escolha new query.

14

Figura 5 - Object Explorer

- New Query

4) Na janela query, copie script desse artigo e cole nessa janela. Em seguida clique no boto execute.

Figura 6 - Janela Query e Boto Execute 5) Expanda no Object Explorer [+] o banco de dados seguro e clique sobre Database Diagram com o boto direito. Responda afirmativamente a caixa de dilogo para criar um novo diagrama.

15

Figura 7 - Novo Diagrama do Banco de Dados 6) Adicione todas as tabelas, para que fique parecido com a Figura 1 - Sistema Controle de Aplices de Seguro - Baseado em (Guedes, 2006). Concluso Nesse artigo que o primeiro de uma srie artigos os quais apresentam um exemplo prtico e simples de um sistema de controle de aplices de seguro, abordando o desenvolvimento em camadas em C#. Nota do Autor: Em breve, disponibilizarei o segundo artigo, pois como as aulas esto retornando aqui na Faculdade o tempo est curto, nem parece que o dia tem 24 hoas. Bom, vida de professor assim, preparar aulas e depois mais aulas. J Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte 2 - Exemplo prtico [Camada Intermediria] A camada intermediria implementa a lgica de negcio e a lgica do controlador. Essa camada atua como intermedirio entre os dados da camada de apresentao e os clientes do aplicativo. A lgica do controlador processa os pedidos do cliente e recupera do banco de dados.

Desenvolvendo uma aplicao Multicamadas para Windows em C# Parte 2 )Camada Intermediria: Lgica do Controlador

16

Introduo Este artigo o segundo de uma srie de sete artigos que apresentam um exemplo prtico e simples abordando o desenvolvimento em camadas em C#, sabemos que a programao orientada a objetos (POO) possibilita uma abordagem simples para a utilizao de dados usando objetos. No artigo anterior foi apresentado um cenrio para o desenvolvimento da aplicao e criado o Banco de Dados com as respectivas tabelas e o mapeamento Entidade Relacionamento entre elas. Neste artigo ser apresentada a classes da camada 2 Camada Intermediaria que representa a lgica do controlador, classe essa que faz a interface entre a lgica de negcio e os dados no banco de dados.

Figura 1 - Observe Camada 2.1 Os mtodos da lgica do controlador devem assegurar a confiabilidade dos dados antes que o servidor de Banco de Dados atualize ou exiba as informaes ao cliente do aplicativo (camada de apresentao). Sabe-se que de acordo com as necessidades atuais das empresas e alteraes constantes na legislao e evidentemente nos aplicativos, o modelo de desenvolvimento em vrias camadas, com a utilizao de classes com finalidades especficas, facilitam a atualizao das aplicaes e tambm permitem o reuso do cdigo. 2 Camada Intermediaria Vamos comear organizando o projeto proposto. Para isso abra inicie um novo projeto em Visual C# - Windows Application, veja Figura 2 - New Project. D o nome para esse projeto de Seguros_OO e clique em OK. 17

Figura 2 - New Project Para que possa ser organizado e visualizado o cdigo nas diferentes camadas, adicione a este projeto duas novas pastas chamadas: Camada Intermediaria e Camada Apresentacao. Expanda a pasta Camada Intermediaria e crie duas novas pastas chamadas respectivamente Logica Controlador e Logica Negocios. Para criar, clique com o boto direito do mouse sobre a soluo, selecione Add New Folder. D os nomes conforme acima, ao final voc ter:

18

Figura 3 - Pastas Vamos adicionar a primeira classe, que ser responsvel pelo controle dos dados. Essa classe far parte da Lgica do Controlador. Chamaremos essa classe de clsDados.vb. 1) Clique com o boto direito sobre Logica Controlador e selecione Add .. Class .. D o nome de clsDados.cs para essa classe. Conforme figura.

Figura 4 - Classe clsDados.cs 19

Vamos ao cdigo da Classe de Dados, clsDados.cs. Classe genrica que utilizada para fazer a interface entre as classes contidas na lgica de negcios e a camada de dados. Nela pode-se realizar as operaes bsicas de banco de dados, como: incluso, alterao, consulta e excluso. Revisando: A orientao a objetos usa classes para encapsular variveis de instncia (dados) e mtodos (comportamentos). Estrutura da classe: clsDados

2) Digitar o cdigo abaixo na classe clsDados.cs.D um duplo clique sobre o nome do arquivo e digite. Se preferir, claro, copie. using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { class clsDados { // Adapte a string de acordo com sua conexo. 20

string conexao = "Data Source=(local);Initial Catalog=seguros;Integrated Security=True"; //Classe para Abrir o Banco de Dados private SqlConnection AbrirBanco() { SqlConnection cn = new SqlConnection(conexao); cn.Open(); return cn; } //Classe para Fechar o Banco de Dados public void FecharBanco(SqlConnection cn) { if (cn.State==ConnectionState.Open) cn.Close(); } //Classe para execuo de comando public void ExecutarComando(string strQuery) { SqlConnection cn = new SqlConnection(); try { cn = AbrirBanco(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = strQuery.ToString(); cmd.CommandType = CommandType.Text; cmd.Connection = cn; cmd.ExecuteNonQuery(); } catch (Exception ex) { throw ex; } finally { FecharBanco(cn); } } //Classe que retorna um objeto DataSet public DataSet RetornarDataSet(string strQuery) { SqlConnection cn = new SqlConnection(); 21

try { cn = AbrirBanco(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = strQuery.ToString(); cmd.CommandType = CommandType.Text; cmd.Connection = cn; cmd.ExecuteNonQuery(); /* Declarado um dataadapter e um dataset passar o comando para o da (SqlDataAdapter) e carregar o dataset com resultado da busca */ SqlDataAdapter da = new SqlDataAdapter(); DataSet ds = new DataSet(); da.SelectCommand= cmd; da.Fill(ds); return ds; } catch (Exception ex) { throw ex; } finally { FecharBanco(cn); }

} //Classe para retornar um DataReader() public SqlDataReader RetornarDataReader(string strQuery) { SqlConnection cn = new SqlConnection(); try { cn = AbrirBanco(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = strQuery.ToString(); cmd.CommandType = CommandType.Text; cmd.Connection = cn; return cmd.ExecuteReader(); } catch (Exception ex) { throw ex; 22

} finally { FecharBanco(cn); }

} }

//Classe para retornar um Id Numrico public int RetornarIdNumerico(string strQuery) { SqlConnection cn = new SqlConnection(); try { cn = AbrirBanco(); SqlCommand cmd = new SqlCommand(); cmd.CommandText = strQuery.ToString(); cmd.CommandType = CommandType.Text; cmd.Connection = cn; SqlDataReader dr = cmd.ExecuteReader(); int codigo; if (dr.Read()) codigo = Convert.ToInt16(dr[0]) + 1; else codigo = 1; return codigo; } catch (Exception ex) { throw ex; } finally { FecharBanco(cn); } }

Concluso PAREI AQUI ... kkkkkkkkkkkkkkkkkkkkkkk 23

Nesse artigo foi apresentado a classe da camada 2 Camada Intermediaria que representa a lgica do controlador, classe essa que faz a interface entre a lgica de negcio e os dados no banco de dados. No prximo artigo ser apresentado as classes que compem a lgica de negcio, classes que possuem uma interface com a apresentada agora. Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte 3 - Exemplo prtico [Lgica de Negcios] Neste terceiro artigo sero apresentadas as classes que compe a regra de negcios do Sistema de Controle de Aplices de Seguro proposto no primeiro artigo. Desenvolvendo uma aplicao Multicamadas para Windows em C# Parte 3 )Camada Intermediria: Lgica de Negcios Introduo Este artigo o terceiro de uma srie de artigos que apresentam um exemplo prtico e simples abordando o desenvolvimento em camadas em C#. No primeiro artigo foi apresentado um cenrio para o desenvolvimento da aplicao e criado o Banco de Dados com as respectivas tabelas e o mapeamento Entidade Relacionamento entre elas. No segundo artigo dessa srie foi apresentada a classes da camada 2 Camada Intermediaria que representa a lgica do controlador, classe essa que faz a interface entre a lgica de negcio e os dados no banco de dados.

24

Figura

SEQ Figura \* ARABIC 1 - Lgica de Negcios

Neste terceiro artigo sero apresentadas as classes que compe a regra de negcios do Sistema de Controle de Aplices de Seguro proposto no primeiro artigo. A lgica de negcios na camada 2 apresentada impe as regras de negcio e garantem a confiabilidade dos dados, antes que o aplicativo servidor atualize o banco de dados ou apresente os dados para os usurios (negociao feita nessa camadas, pela classe que representa a lgica do controlador). As regras de negcio dizem como os clientes podem e no podem acessar os dados do aplicativo e como os aplicativos processam esses dados. 2 Camada Intermediaria: Lgica de Negcios A primeira classe que ser apresentada a classe clnClientes.cs, nesta classe sero definidos os campos membros, atributos/propriedades e mtodos. Como boa prtica de programao as variveis de instncia da classe estaro definida como PRIVATE, sendo acessveis apenas dentro da prpria classe pelas propriedades que utilizaremos atravs de seus mtodos de acesso para exibir ou ler os dados. (Mtodos Get e Set). Mo na Massa: 1) Com o aplicativo aberto Seguros_OO, d um clique com o boto direito do mouse sobre a pasta [Logica Negocios], selecione a opo ADD New Item e Adicione uma nova classe, com o nome clnClientes.cs. 25

Figura 2 Classe Clientes Nota do Autor: Procurei comentar ao mximo esta classe, para que facilite o entendimento, no entanto, caso algo no fique claro, podem-me escrever, sempre coloco o meu e-mail no final dos artigos. Nessa camada voc poderia implementar algumas regras que ao longo dos artigos no vou definir, pois o objetivo aqui no complicar o entendimento. Mas fique a vontade para incluir regras nessa camada, tais como checagem dos dados, consistncia de valores. Antes de digitar o cdigo, a classe clnClientes.cs a figura abaixo mostra como ela est definida:

26

Figura

SEQ Figura \* ARABIC 3 - Detalhes da Classe clnClientes.cs

Pronto agora s digitar, ou copiar, se assim o preferir: using using using using using System; System.Collections.Generic; System.Text; System.Data; System.Data.SqlClient;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { public class clnClientes { //1 - Campos privados a classe private int idCli; 27

private private private private private

string string string string string

nomeCli; enderecoCli; foneCli; faxCli; obsCli;

//2 - propriedades, acesso aos campos privados public int IdCli { get { return idCli; } set { idCli = value; } } public string NomeCli { get { return nomeCli; } set { nomeCli = value; } } public string EnderecoCli { get { return enderecoCli; } set { enderecoCli = value; } } public string FoneCli { get { return foneCli; } set { foneCli = value; } } public string FaxCli { get { return faxCli; } set { faxCli = value; } } public string ObsCli { get { return obsCli; } set { obsCli = value; } } //3 - mtodos da classe de Negcios (clnCliente.cs) //3.1 Buscar dados do cliente cujo codigo foi especificado public void Buscar() 28

string csql; csql = "Select * From tbCliente where idCli=" + IdCli; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; idCli = Convert.ToInt16(dados.GetValue(0)); nomeCli = Convert.ToString(dados.GetValue(1)); enderecoCli = Convert.ToString(dados.GetValue(2)); foneCli = Convert.ToString(dados.GetValue(3)); faxCli = Convert.ToString(dados.GetValue(4)); obsCli = Convert.ToString(dados.GetValue(5)); }

} //3.2 Buscar o prximo Id Numerico para //inclusao de um novo cliente. public int BuscarId() { string csql; csql = "Select Top 1 (IdCli) From TbCliente order by IdCli desc"; int IdBuscado; clsDados seguros = new clsDados(); IdBuscado=seguros.RetornarIdNumerico(csql); return IdBuscado; } //3.3 Mtodo para incluir um novo cliente no //Banco de dados public void Gravar() { StringBuilder csql = new StringBuilder(); csql.Append("Insert into tbCliente"); csql.Append("("); csql.Append("idCli,"); csql.Append("nomeCli,"); csql.Append("enderecoCli,"); csql.Append("foneCli,"); csql.Append("faxCli,"); 29

csql.Append("obsCli) Values("); csql.Append(idCli); csql.Append(",'" + nomeCli +"',"); csql.Append("'" + enderecoCli + "',"); csql.Append("'" + foneCli + "',"); csql.Append("'" + faxCli + "',"); csql.Append("'" + obsCli + "')"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString());

//3.4 Mtodo para atualizar (alterar um registro) public void Atualizar() { StringBuilder csql = new StringBuilder(); csql.Append("Update tbCliente "); csql.Append("set idCli="); csql.Append(IdCli); csql.Append(", nomeCli='"); csql.Append(nomeCli); csql.Append("', enderecoCli='"); csql.Append(enderecoCli); csql.Append("', foneCli='"); csql.Append(foneCli); csql.Append("', faxCli='"); csql.Append(faxCli); csql.Append("', obsCli='"); csql.Append(obsCli); csql.Append("' where idCli="); csql.Append(IdCli); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Mtodo para excluir um cliente do //Banco de dados public void Excluir() { StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbCliente "); csql.Append(" where idCli="); csql.Append(IdCli); 30

clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } } Concluso Nesse terceiro artigo foi apresentada a primeira classe que compe a regras de negcios do Sistema de Controle de Aplices de Seguro proposto. Como j apresentado a lgica de negcios na camada 2 impe as regras de negcio e garantem a confiabilidade dos dados, antes que o aplicativo servidor atualize o banco de dados ou apresente os dados para os usurios (acesso aos dados: tarefa da classe clnDados.cs lgica do controlador). Ao final dessa srie de artigos, disponibilizarei o cdigo dessa aplicao exemplo. No desafio ao leitor, criar as demais classes bsicas que compes a lgica de negcios. entando fica como }

No prximo artigo ser apresentado a camada de apresentao, onde sero criados o formulrio para cadastro de dados do cliente e o formulrio de pesquisa genrico que poder ser utilizado em toda a aplicao. Nota Importante: Neste exemplo no separamos as camadas em projetos diferentes dentro de uma soluo. Usamos apenas pastas (folders) para isso. Nada impede que voc adote essa prtica, projetos maiores ficam de forma melhor organizados com esse procedimento. A nica coisa que no pode-se esquecer de colocar as referncias aos projetos em uso. Ex: o projeto que conteriam as regras de negcio teriam que ter uma referencia adicionada ao projeto do controlador, e assim por diante. Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte 4 - Exemplo prtico [Camada de Apresentao] Neste quarto artigo ser apresentado a camada de apresentao, onde criaremos um formulrio para cadastro de dados dos clientes e um formulrio de pesquisa genrico que poder ser reutilizado em toda a aplicao.

Desenvolvendo uma aplicao Multicamadas para Windows em C# Parte 4 ) Camada Intermediria: Lgica de Negcios

31

Introduo Este artigo o quarto de uma srie de artigos que apresentam um exemplo prtico e simples abordando o desenvolvimento em camadas em C#, sabemos que a programao orientada a objetos (POO) possibilita uma abordagem simples para a utilizao de dados usando objetos. Aproveitando o comentrio do amigo Queiroz Como o seu objetivo abstrair algumas operaes com o banco de dados um nome que mais relacionado persistncia ficaria melhor sobre os artigos anteriores, diga-se por sinal que comentrio foi bem oportuno; importante destacar que as camadas nos dizem como agrupar os componentes j o modelo MVC apresenta a forma de interao entre essas. O nome dado a segunda camada (Intermediria) acredito que esteja bem adequado, no entanto a lgica do controlador, deve ser vista como a parte da camada que contm as classes com o conhecimento necessrio sobre como persistir objetos no banco de dados, como usei o referencial terico apresentado no artigo 1 (Deitel et al, 2002) esta persistncia encontra-se apresentada como lgica do controlador, traduo tcnica feita tambm na verso brasileira do Livro Como programar C#. importante que o leitor no confunda estes conceitos. Aqui no prprio devmedia, os amigos podem encontrar artigos interessantes demonstrando na prtica os conceitos de MVC que em projetos maiores uma boa prtica a realizao do mapeamento entre os objetos de domnio com o banco de dados. O leitor pode conhecer mais sobre esse mapeamento utilizando por exemplo o Nhibernate, aqui no portal com as vdeo aulas do Rodrigo. Link abaixo: http://www.devmedia.com.br/articles/viewcomp.asp?comp=7341&hl= Revisando No primeiro artigo foi apresentado um cenrio para o desenvolvimento da aplicao e criado o Banco de Dados com as respectivas tabelas e o mapeamento Entidade Relacionamento entre elas. No segundo artigo dessa srie foi apresentada a classes da camada 2 Camada Intermediaria que representa a lgica do controlador, classe essa que faz a interface entre a lgica de negcio e os dados no banco de dados. No terceiro artigo foi apresentada a classe clnClientes.cs que compe as regras de negcios do Sistema de Controle de Aplices de Seguro proposto no primeiro artigo. importante tambm destacar que o leitor pode acrescentar, como j foi dito, comportamentos a esta classe, coisa que aqui por questo de didtica deixei de incluir. Este Artigo Neste quarto artigo ser apresentado a camada de apresentao, onde criaremos um formulrio para cadastro de dados dos clientes e um formulrio de pesquisa genrico que poder ser reutilizado em toda a aplicao. 32

Lembrando que ao ao final dessa srie de artigos, disponibilizarei o cdigo dessa aplicao exemplo. Espero que vocs tenham enfrentado o desafio do artigo anterior.

Figura 1 - Camadas da Aplicao

3 Camada de Apresentao A camada de apresetao ou camada do cliente ou ainda camada superior a interface com o usurio, que neste caso so as janelas Winforms do nosso aplicativo exemplo. A camada do cliente interage com a camada intermediria para fazer pedidos e recuperar dados da camada de dados. Ento, a camada de apresentao exibe para o usurio os dados recuperados pela camada intermediria. Esta diviso em camadas certamente deixa o cdigo com uma leitura e controle mais fcil. Pois as regras esto em uma camada isolada. Supondo que nossa aplicao fosse cliente de uma aplicao Web Service em um servidor numa intranet, as regras poderiam estar nas classes desse nico servidor facilitando assim a manuteno, pois caso o cdigo venha a ser alterado, no necessrio compilar as alteraes nas mquinas clientes. Um bom trabalho poupado. Cenrio: Criaremos nesse momento o primeiro formulrio, que servir de interface com os dados do cliente. Onde o usurio poder, incluir, alterar, excluir e pesquisar por um determinado cliente. Nota, lembre-se que a idia criar um formulrio para pesquisa genrico que venha a servir em outros tipos de pesquisa, como por exemplo: aplices de seguro ou parcelas do cliente. 33

Mo na Massa: 1) Com o aplicativo aberto Seguros_OO, voc deve ter um formulrio Form1 na janela do solution explorer, arraste-o para dentro da Camada de Apresentao, pasta [Camada Apresentacao].

Figura 2 Form1.cs Caso voc no tenha esse formulrio, clique com o boto direito do mouse sobre a camada de apresentao e adicione um novo formulrio. Renomeie esse formulrio para FrmClientes.cs

34

Figura 3 - Formulrio renoemado. 2) Crie uma interface arrastando os objetos para a tela conforme abaixo e definindo o nome dos controles como apresentado em azul:

35

Figura 4 - Cadastro de Clientes 3) Altere as propriedades de todos os botes exceto (btnProcurar e btnSair), como abaixo: Controle btnIncluir btnAtualizar btnExcluir btnCancelar Propriedade Enabled Enabled Enabled Enabled Valor false false false false

O formulrio deve funcionar desta forma: Quando for carregado o foco deve estar no primeiro campo o controle txtidCli Quando o usurio sair desse controle, faremos uma busca no Banco de Dados para retornar o cdigo digitado, caso no tenha o cdigo ser habilitado a opo de incluir e caso contrrio ser habilitado o boto atualizar. 36

4) Selecione o controle txtidCli e na janela de eventos, veja Figura 5 - Janela para seleciona evento, e escolha o evento leave (para conhecedores do VB lostfocus), d um duplo clique nele e adicione o cdigo abaixo:

Figura 5 - Janela para selecionar evento 5) Cdigo do evento Leave: private void txtIdCli_Leave(object sender, EventArgs e) { int vidCli=0; if (txtIdCli.Text.Trim() != "") { vidCli = int.Parse(txtIdCli.Text); } clnClientes cliente = new clnClientes(); cliente.IdCli = vidCli; cliente.Buscar(); if (cliente.NomeCli == null) { //preparando para inclusao LimparTxt(groupBox1); txtIdCli.Text = ""; txtIdCli.Enabled = false; btnIncluir.Enabled = true; 37

} else {

btnCancelar.Enabled = true;

//preparando para alteracao LimparTxt(groupBox1); txtIdCli.Enabled = false; txtIdCli.Text = Convert.ToString(cliente.IdCli); txtnomeCli.Text = Convert.ToString(cliente.NomeCli); txtenderecoCli.Text = Convert.ToString(cliente.EnderecoCli); txtfoneCli.Text = Convert.ToString(cliente.FoneCli); txtfaxCli.Text = Convert.ToString(cliente.FaxCli); txtobsCli.Text = Convert.ToString(cliente.ObsCli); btnAtualizar.Enabled = true; btnCancelar.Enabled = true; btnExcluir.Enabled = true; } } necessrio que voc indique o local de armazenamento das classes nas declaraes de using. Neste caso indique: ... using System.Text; using System.Windows.Forms; using Seguros_OO.Camada_Intermediaria.Logica_Negocios; No cdigo anterior observe as linhas destacadas em negrito e itlico nos blocos if e else. Invoca-se um mtodo chamado LimparTxt passando como parmetro o objeto do tipo GroupBox chamado groupBox1. A idia que quando o cdigo for invocado ele limpe todas as caixas de textos que esto dentro do groupBox. 6) Acrescente o cdigo a seguir, logo acima ou abaixo do mtodo anterior. //Mtodo pblico para limpar caixas de texto public void LimparTxt(Control controles) { foreach (Control ctl in controles.Controls) { if (ctl is TextBox) ctl.Text = ""; } } 38

7) Na lista abaixo cdigo encontra-se o cdigo do boto incluir. Observe como este cdigo limpo. Lembre-se que as regras para gravao do cliente poderiam ter sido criadas na classe clnCliente no mtodo Gravar ou nos mtodos de escrita Set daquela classe. private void btnIncluir_Click(object sender, EventArgs e) { try { clnClientes cliente = new clnClientes(); //Dispara o mtodo para buscar o IdCli cliente.IdCli = cliente.BuscarId(); cliente.NomeCli = txtnomeCli.Text; cliente.EnderecoCli = txtenderecoCli.Text; cliente.FoneCli = txtfoneCli.Text; cliente.FaxCli = txtfaxCli.Text; cliente.ObsCli = txtobsCli.Text; cliente.Gravar(); string mensagem = "Registro Cliente: " + cliente.IdCli + "\nNome: " + cliente.NomeCli + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnIncluir.Enabled = false; btnCancelar.Enabled = false; txtIdCli.Enabled = true; txtIdCli.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } 8) Abaixo o cdigo do boto atualizar. private void btnAtualizar_Click(object sender, EventArgs e) { try { 39

clnClientes cliente = new clnClientes(); cliente.IdCli = int.Parse(txtIdCli.Text); cliente.NomeCli = txtnomeCli.Text; cliente.EnderecoCli = txtenderecoCli.Text; cliente.FoneCli = txtfoneCli.Text; cliente.FaxCli = txtfaxCli.Text; cliente.ObsCli = txtobsCli.Text; cliente.Atualizar(); string mensagem = "Registro Cliente: " + cliente.IdCli + "\nNome: " + cliente.NomeCli + "\nAlterado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtIdCli.Enabled = true; txtIdCli.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } 9) Abaixo o cdigo do boto Excluir. private void btnExcluir_Click(object sender, EventArgs e) { string pergunta; pergunta = "Deseja excluir o cliente: \n" + txtIdCli.Text + ": " + txtnomeCli.Text + " ?"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { clnClientes cliente = new clnClientes(); cliente.IdCli = int.Parse(txtIdCli.Text); cliente.NomeCli = txtnomeCli.Text; cliente.Excluir(); 40

string mensagem = "Registro Cliente: " + cliente.IdCli + "\nNome: " + cliente.NomeCli + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtIdCli.Enabled = true; txtIdCli.Focus(); } else {

MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information);

10) Abaixo o cdigo do boto cancelar. private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox1); btnIncluir.Enabled = false; btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtIdCli.Enabled = true; txtIdCli.Focus(); } Neste momento no ser colocado cdigo para o boto procurar. Retornaremos a este ponto em breve. 11) Abaixo cdigo do ltimo boto, o boto sair. A finalidade apenas sair do formulrio atual e no da aplicao, uma vez que esse no ser o formulrio principal deste nosso sistema exemplo. private void btnSair_Click(object sender, EventArgs e) { this.Close(); } 41

Bom, agora que j est pronto o formulrio: cadastro de clientes, o prximo passo criar um formulrio genrico de consulta. Este formulrio servir para pesquisa em todas as tabelas do banco. 12) Agora, adicione um novo formulrio a essa aplicao e renomei-o com o nome FrmPesquisa.cs, coloque (ou crie) esse formulrio dentro da pasta [Camada Apresentacao].

Figura 6 - Solution Explorer (FrmPesquisa.cs) Quem acompanhou a srie de artigos do desenvolvimento em camada para o Visual Basic, deve se lembrar deste formulrio. A idia aqui a mesma, s que em Csharp. Mas vale a pena relembrar. 13) Arraste para o formulrio FrmConsulta os seguintes objetos 02 groupboxs, 03 labels, 02 combobox, 01 textbox, 01 button e 01 datagrid. Conforme abaixo:

42

Figura 7 - Formulrio FrmPesquisa.cs

14) Altere as propriedades dos objetos do formulrio conforme quadro: 43

Objeto ComboBox1

Propriedade NAME DROPDOWNSTYLE ComboBox2 NAME DROPDOWNSTYLE TextBox1 NAME Button1 NAME DataGridView1 NAME Os controles do tipo GroupBox no propriedade NAME.

Valor cmbCampo DropDownList cmbParam DropDownList TxtBusca btnFiltrar Dgv1 precisam alterar a

15) Agora vamos retornar ao formulrio FrmClientes, para adicionar o cdigo que responde ao evento click no boto procurar. No entanto declare a biblioteca com o keyword using antes. ... using System.Windows.Forms; using Seguros_OO.Camada_Intermediaria.Logica_Negocios; using Seguros_OO.Camada_Apresentacao; 16) Agora sim. Vamos ao cdigo do boto procurar: private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados dos clientes"; f.Tag = "tbCliente"; //nome da tabela (macete) :) f.ShowDialog(); } 17) Alterne agora para o formulrio FrmPesquisa e declare as bibliotecas necessrias para instanciamento das classes (namespace). using Seguros_OO.Camada_Intermediaria.Logica_Negocios; 18) Neste momento adicione o cdigo para o evento Load do formulrio FrmPesquisa.

private void FrmPesquisa_Load(object sender, EventArgs e) { 44

string csql = "Select * From " + this.Tag.ToString(); clsDados geral = new clsDados(); DataSet ds = geral.RetornarDataSet(csql); dgv1.DataSource = ds.Tables[0]; ds.Tables[0].Columns[0].ColumnName.ToString(); cmbCampo.Items.Clear(); for (int i = 0; i < ds.Tables[0].Columns.Count; i++) cmbCampo.Items.Add(ds.Tables[0].Columns[i].ColumnName.ToString()); } O mtodo acima disparado quando o formulrio carregado, Inicialmente declaramos uma string chamada csql com a clusula select, cujo objetivo buscar no banco de dados todos os campos da tabela indicada na propriedade Tag do formulrio corrente. Veja que essa propriedade foi carregada com o nome da tabela indica no item 16, destacado como macete. Desta forma este formulrio pode ser reaproveitado em qualquer chamada a partir de outros formulrio, desde que voc indique na hora do instancimento do formulrio o nome da tabela desejada. Uma boa idia para voc melhorar mais tarde o funcionamento deste formulrio. Ainda nesse cdigo atravs de uma estrutura de repetio for, percorremos todas as colunas (campos) da tabela em questo e adicionamos o seu nome (nome do campo) ao controle cmbCampo. Agora vamos adicionar um cdigo, para que quando o usurio escolha um campo no controle cmbCampo, seja preechido o cmbParam com os tipos de busca possvel para o tipo de campo selecionado, ou seja, se o usurio escolher um campo tipo string o campo cmbParam deve ter as opes tipo: comeando com, terminando em, igual a, tem a palavra, e se for int deve der opes do tipo: >, <, etc. 19) Cdigo do cmbCampo (quando o usurio escolher um campo); private void cmbCampo_SelectedIndexChanged(object sender, EventArgs e) { int indiceCampo = cmbCampo.SelectedIndex; string tipocampo = this.dgv1.Columns[indiceCampo].ValueType.ToString(); if(tipocampo.Trim()=="System.Int32") { cmbParam.Items.Clear(); cmbParam.Items.Add("="); cmbParam.Items.Add(">"); cmbParam.Items.Add(">="); cmbParam.Items.Add("<"); cmbParam.Items.Add("<="); cmbParam.Items.Add("<>"); } 45

else if (tipocampo.Trim() == "System.String") { cmbParam.Items.Clear(); cmbParam.Items.Add("="); cmbParam.Items.Add("Comea com"); cmbParam.Items.Add("Termina em"); cmbParam.Items.Add("Tem a palavra"); } else { MessageBox.Show("Implemente Cdigo para outros tipos"); } } OBS do Autor: Veja que no implementei para todos os tipos de dados, apenas para os tipos mais comuns. Int e string, fica para voc implementar para os demais tipos usados. 20) Para finalizar o contedo desse artigo, vamos ao cdigo que responder ao evento click do Boto filtrar. private void btnFiltrar_Click(object sender, EventArgs e) { string campo = cmbCampo.Text; string parametro = cmbParam.Text; string valor = txtBusca.Text; int indiceCampo = cmbCampo.SelectedIndex; string tipocampo = this.dgv1.Columns[indiceCampo].ValueType.ToString(); //Para tipos String if(tipocampo=="System.String") { if(parametro=="Tem a palavra") { parametro= "Like "; valor = "'%" + valor + "%'"; } else if(parametro=="=") { parametro= "="; valor = "'" + valor + "'"; } else if(parametro=="Comea com") { parametro= "Like "; 46

} //Para tipos int no so necessrio ajustes. string csql = "Select * from " + this.Tag.ToString() + " where " + campo + " " + parametro + " " + valor; clsDados busca = new clsDados(); DataSet ds = busca.RetornarDataSet(csql); this.dgv1.DataSource = ds.Tables[0]; } Note que esse formulrio de pesquisa poder ser utilizado por qualquer formulrio de cadastro, sem alteraes. Voc pode melhorar o cdigo com o tratamento para os outros tipos de dados como data e hora por exemplo. Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte 5 - Exemplo prtico [Classes Auxiliares] Nesse artigo vamos criar a lgica de negcios e a respectiva camada de apresentao para as informaes auxiliares da aplice. Nessa ordem: Dano, Tipo de Sinistro, e Modelos de Carros. Desenvolvendo uma aplicao Multicamadas para Windows em C# (Parte 5) Introduo Este artigo o quinto de uma srie de sete artigos que apresentam um exemplo prtico e simples abordando o desenvolvimento em camadas em C#, sabemos que a programao orientada a objetos (POO) possibilita uma abordagem simples para a utilizao de dados usando objetos. Reviso No primeiro artigo foi apresentado um cenrio para o desenvolvimento da aplicao e criado o Banco de Dados com as respectivas tabelas e o mapeamento Entidade Relacionamento entre elas.

valor = "'" + valor + "%'"; } else if (parametro=="Termina em") { parametro = "Like "; valor = "'%" + valor + "'"; }

47

No segundo artigo dessa srie foi apresentada a classe da camada 2 Camada Intermediaria que representa a lgica do controlador (persistir dados), classe essa que fez a interface entre a lgica de negcio e os dados no banco de dados. No terceiro artigo foi apresentada a classe clnClientes.cs que possui as regras de negcios do Sistema de Controle de Aplices de Seguro proposto desde o primeiro artigo. No quarto foi apresentado a camada de apresentao, onde foram criados os formulrios para cadastro de dados de clientes e o formulrio de pesquisa genrico que ser utilizado em toda a aplicao. Nesse quinto artigo estudaremos mais sobre o Projeto de Aplice de Seguros, de forma geral. Iniciando o Estudo: Observe a Figura 1 - Diagrama ER Numerado.

Figura 1 - Diagrama ER Numerado A tabela de aplices sem dvida a mais importante do Sistema e para que possa ser feito o cadastro de uma nova aplice inicialmente temos que possuir dados nas tabelas de clientes (tbCliente) [no numerada pois nos artigos anteriores implementamos a funcionalidade para a mesma] temos que ter os dados j cadastrados na 48

tabela de modelo de carros (tbModelo) [6] e a partir da aplice cadastrada gerar as parcelas [5] para o pagamento por parte do cliente. J em relao aos sinistros ocorridos [2] para que possa ser cadastrado, inicialmente temos que ter tambm a aplice cadastrada [1] e previamente cadastrados os tipos de danos que podem ocorrer [3] e os tipos de sinistros j cadastrados. Nesse artigo vamos criar a lgica de negcios e a respectiva camada de apresentao para as informaes auxiliares da aplice. Nessa ordem: Dano, Tipo de Sinistro, e Modelos de Carros. Mo na Massa: 1) Com o aplicativo aberto adicione trs novas classes chamadas respectivamente: clnDanos.cs, clnTipos.cs, clnModelos.cs, conforme figura:

Figura 2 - Outras Classes 2) Agora adicione na Pasta [Camada Apresentacao] trs novos formulrios com os nomes respectivamente: FrmDanos.cs, FrmTipos.cs e FrmModelos.cs.

49

Figura 3 - Outros Formulrios Vamos montar a interface com o usurio nesses trs formulrios, para tanto acrescente os controles e modifique os nomes conforme solicitado: 3) Alterne para o formulrio FrmDados e crie essa interface, d o nome para os controles em azul.

Figura 4 - FrmDanos.cs Obs: Como boa prtica utilize os mesmo padro de nomes para os botes de comando. 4) Alterne para o formulrio FrmTipos e crie essa interface, d o nome para os controles em azul.

50

<!--[if !vml]--> Figura 5 - FrmTipos.cs 5) Alterne para o formulrio FrmModelos e crie essa interface, d o nome para os controles em azul.

Figura 6 FrmModelos Lgica de Negcios das classes criadas Como a lgica idntica a apresentada nos artigos anteriores. Aqui ser apresentado apenas o cdigo de cada classe. Acredita-se ser desnecessrio o detalhamento, pois considerado que o leitor tenha feito a aplicao at o presente. Abaixo classe: clnDados at com as declarao dos namespaces. Copie e cole o cdigo. Mas no deixe de analis-lo novamente. 51

using System; using System.Collections.Generic; using System.Text; using System.Data; namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { class clnDanos { //1 - Campos privados a classe private int idDano; private string descDano; //2 - propriedades, acesso aos campos privados public int IdDano { get { return idDano; } set { idDano = value; } } public string DescDano { get { return descDano; } set { descDano = value; } } //3 - mtodos da classe de Negcios (clnDanos.cs) //3.1 Buscar dados de danos cujo codigo foi especificado public void Buscar() { string csql; csql = "Select * From tbDano where idDano=" + IdDano; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; idDano = Convert.ToInt16(dados.GetValue(0)); descDano = Convert.ToString(dados.GetValue(1)); } } //3.2 Buscar o prximo Id Numerico para //inclusao de um novo tipo de dano. 52

public int BuscarId() { string csql; csql = "Select Top 1 (idDano) From tbDano order by idDano desc"; int IdBuscado; clsDados seguros = new clsDados(); IdBuscado = seguros.RetornarIdNumerico(csql); return IdBuscado; } //3.3 Mtodo para incluir um novo tipo de dano no //Banco de dados public void Gravar() { StringBuilder csql = new StringBuilder(); csql.Append("Insert into tbDano"); csql.Append("("); csql.Append("idDano,"); csql.Append("descDano) Values("); csql.Append(idDano); csql.Append(",'" + descDano + "')"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.4 Mtodo para atualizar (alterar um registro) public void Atualizar() { StringBuilder csql = new StringBuilder(); csql.Append("Update tbDano "); csql.Append("set idDano="); csql.Append(idDano); csql.Append(", descDano='"); csql.Append(descDano); csql.Append("' where idDano="); csql.Append(IdDano); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Mtodo para excluir um dano do //Banco de dados public void Excluir() { 53

StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbDano "); csql.Append(" where idDano="); csql.Append(IdDano); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.6 Mtodo Buscar todos os Danos public DataSet BuscarTodos() { string csql; csql = "Select * From tbDano order by descDano"; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); return ds; }

} }

Abaixo classe: clnTipos using using using using System; System.Collections.Generic; System.Text; System.Data;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { class clnTipos { //1 - Campos privados a classe private int idTipo; private string descTipo; //2 - propriedades, acesso aos campos privados public int IdTipo { get { return idTipo; } 54

set { idTipo = value; } } public string DescTipo { get { return descTipo; } set { descTipo = value; } } //3 - mtodos da classe de Negcios (clnTipos.cs) //3.1 Buscar dados de tipos cujo codigo foi especificado public void Buscar() { string csql; csql = "Select * From tbTipo where idTipo=" + IdTipo; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; idTipo = Convert.ToInt16(dados.GetValue(0)); descTipo = Convert.ToString(dados.GetValue(1)); } } //3.2 Buscar o prximo Id Numerico para //inclusao de um novo tipo. public int BuscarId() { string csql; csql = "Select Top 1 (idTipo) From tbTipo order by idTipo desc"; int IdBuscado; clsDados seguros = new clsDados(); IdBuscado = seguros.RetornarIdNumerico(csql); return IdBuscado; } //3.3 Mtodo para incluir um novo tipo no //Banco de dados public void Gravar() 55

StringBuilder csql = new StringBuilder(); csql.Append("Insert into tbTipo"); csql.Append("("); csql.Append("idTipo,"); csql.Append("descTipo) Values("); csql.Append(idTipo); csql.Append(",'" + descTipo + "')"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString());

} //3.4 Mtodo para atualizar (alterar um registro) public void Atualizar() { StringBuilder csql = new StringBuilder(); csql.Append("Update tbTipo "); csql.Append("set idTipo="); csql.Append(idTipo); csql.Append(", descTipo='"); csql.Append(descTipo); csql.Append("' where idTipo="); csql.Append(idTipo); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Mtodo para excluir um tipo do //Banco de dados public void Excluir() { StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbTipo "); csql.Append(" where idTipo="); csql.Append(idTipo); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.6 Mtodo Buscar todos os Tipos public DataSet BuscarTodos() { 56

string csql; csql = "Select * From tbTipo order by descTipo"; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); return ds; } } Abaixo classe: clnModelos using using using using System; System.Collections.Generic; System.Text; System.Data; }

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { class clnModelos { //1 - Campos privados a classe private int idModelo; private string descModelo; private string descMarca; //2 - propriedades, acesso aos campos privados public int IdModelo { get { return idModelo; } set { idModelo = value; } } public string DescModelo { get { return descModelo; } set { descModelo = value; } } public string DescMarca { get { return descMarca; } 57

set { descMarca = value; }

//3 - mtodos da classe de Negcios (clnModelos.cs) //3.1 Buscar dados de Modelos cujo codigo foi especificado public void Buscar() { string csql; csql = "Select * From tbModelo where idModelo=" + IdModelo; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; idModelo = Convert.ToInt16(dados.GetValue(0)); descModelo = Convert.ToString(dados.GetValue(1)); descMarca = Convert.ToString(dados.GetValue(2)); } } //3.2 Buscar o prximo Id Numerico para //inclusao de um novo modelo. public int BuscarId() { string csql; csql = "Select Top 1 (idModelo) From tbModelo order by idModelo desc"; int IdBuscado; clsDados seguros = new clsDados(); IdBuscado = seguros.RetornarIdNumerico(csql); return IdBuscado; } //3.3 Mtodo para incluir um novo modelo no //Banco de dados public void Gravar() { StringBuilder csql = new StringBuilder(); csql.Append("Insert into tbModelo"); csql.Append("("); csql.Append("idModelo,"); 58

csql.Append("descModelo,"); csql.Append("descMarca) Values("); csql.Append(idModelo); csql.Append(",'" + descModelo + "'"); csql.Append(",'" + descMarca + "')"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString());

//3.4 Mtodo para atualizar (alterar um registro) public void Atualizar() { StringBuilder csql = new StringBuilder(); csql.Append("Update tbModelo "); csql.Append("set idModelo="); csql.Append(idModelo); csql.Append(", descModelo='"); csql.Append(descModelo); csql.Append("', descMarca='"); csql.Append(descMarca); csql.Append("' where idModelo="); csql.Append(idModelo); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Mtodo para excluir um dano do //Banco de dados public void Excluir() { StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbModelo "); csql.Append(" where idModelo="); csql.Append(idModelo); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } } }

59

Camada de Apresentao Bom. Vamos agora a camada de apresentao. Seria interessante, voc copiar os cdigo para dentro de cada evento (um a um) ou se copiar o cdigo do formulrio no se esquea de instanciar os eventos na inicializao do formulrio. Siga minha dica depois confira com o cdigo aqui colocado. Formulrio: FrmDanos Abaixo cdigo completo com todos os eventos e mtodos declarados: using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; Seguros_OO.Camada_Intermediaria.Logica_Negocios;

namespace Seguros_OO.Camada_Apresentacao { public partial class FrmDanos : Form { public FrmDanos() { InitializeComponent(); } //Mtodo pblico para limpar caixas de texto public void LimparTxt(Control controles) { foreach (Control ctl in controles.Controls) { if (ctl is TextBox) ctl.Text = ""; } } private void btnIncluir_Click(object sender, EventArgs e) { 60

try { clnDanos dano = new clnDanos(); //Dispara o mtodo para buscar o IdDano dano.IdDano = dano.BuscarId(); dano.DescDano = txtdescDano.Text; dano.Gravar(); string mensagem = "Registro Dano: " + dano.IdDano + "\nDescrio: " + dano.DescDano + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnIncluir.Enabled = false; btnCancelar.Enabled = false; txtidDano.Enabled = true; txtidDano.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } private void btnAtualizar_Click(object sender, EventArgs e) { try { clnDanos dano = new clnDanos(); dano.IdDano = int.Parse(txtidDano.Text); dano.DescDano = txtdescDano.Text; string mensagem = "Registro Dano: " + dano.IdDano + "\nNome: " + dano.DescDano + "\nAlterado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; 61

btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidDano.Enabled = true; txtidDano.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } private void btnExcluir_Click(object sender, EventArgs e) { string pergunta; pergunta = "Deseja excluir o dado: \n" + txtidDano.Text + ": " + txtdescDano.Text + " ?"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { clnDanos dano = new clnDanos(); dano.IdDano = int.Parse(txtidDano.Text); dano.DescDano = txtdescDano.Text; dano.Excluir(); string mensagem = "Registro Dano: " + dano.IdDano + "\nDescrio: " + dano.DescDano + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidDano.Enabled = true; txtidDano.Focus(); } 62

else { MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information);

} }

private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox1); btnIncluir.Enabled = false; btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidDano.Enabled = true; txtidDano.Focus(); } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta Tipos de Danos"; f.Tag = "tbDano"; //nome da tabela (macete) :) f.ShowDialog(); } private void txtidDano_Leave(object sender, EventArgs e) { int vidDano = 0; if (txtidDano.Text.Trim() != "") { vidDano = int.Parse(txtidDano.Text); } clnDanos dano = new clnDanos(); 63

dano.IdDano = vidDano; dano.Buscar(); if (dano.DescDano == null) { //preparando para inclusao LimparTxt(groupBox1); txtidDano.Text = ""; txtidDano.Enabled = false; btnIncluir.Enabled = true; btnCancelar.Enabled = true; } else { //preparando para alteracao LimparTxt(groupBox1); txtidDano.Enabled = false; txtidDano.Text = Convert.ToString(dano.IdDano); txtdescDano.Text = Convert.ToString(dano.DescDano); btnAtualizar.Enabled = true; btnCancelar.Enabled = true; btnExcluir.Enabled = true; } } } Formulrio: FrmTipos Abaixo cdigo completo com todos os eventos e mtodos declarados: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Seguros_OO.Camada_Intermediaria.Logica_Negocios; namespace Seguros_OO.Camada_Apresentacao { 64 }

public partial class FrmTipos : Form { public FrmTipos() { InitializeComponent(); } //Mtodo pblico para limpar caixas de texto public void LimparTxt(Control controles) { foreach (Control ctl in controles.Controls) { if (ctl is TextBox) ctl.Text = ""; } } private void btnIncluir_Click(object sender, EventArgs e) { try { clnTipos tipo = new clnTipos(); //Dispara o mtodo para buscar o IdTipo tipo.IdTipo = tipo.BuscarId(); tipo.DescTipo = txtdescTipo.Text; tipo.Gravar(); string mensagem = "Registro Tipo: " + tipo.IdTipo + "\nDescrio: " + tipo.DescTipo + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnIncluir.Enabled = false; btnCancelar.Enabled = false; txtidTipo.Enabled = true; txtidTipo.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } 65

} private void btnAtualizar_Click(object sender, EventArgs e) { try { clnTipos tipo = new clnTipos(); tipo.IdTipo = int.Parse(txtidTipo.Text); tipo.DescTipo = txtdescTipo.Text; string mensagem = "Registro Dano: " + tipo.IdTipo + "\nNome: " + tipo.DescTipo + "\nAlterado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidTipo.Enabled = true; txtidTipo.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } private void btnExcluir_Click(object sender, EventArgs e) { string pergunta; pergunta = "Deseja excluir o tipo: \n" + txtidTipo.Text + ": " + txtdescTipo.Text + " ?"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { 66

clnTipos tipo = new clnTipos(); tipo.IdTipo = int.Parse(txtidTipo.Text); tipo.DescTipo = txtdescTipo.Text; tipo.Excluir(); string mensagem = "Registro Tipo: " + tipo.IdTipo + "\nDescrio: " + tipo.DescTipo + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidTipo.Enabled = true; txtidTipo.Focus(); } else {

MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information);

} } private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox1); btnIncluir.Enabled = false; btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidTipo.Enabled = true; txtidTipo.Focus(); } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } 67

private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta de Tipos de Sinistros"; f.Tag = "tbTipo"; //nome da tabela (macete) :) f.ShowDialog(); } private void txtidTipo_Leave(object sender, EventArgs e) { int vidtipo = 0; if (txtidTipo.Text.Trim() != "") { vidtipo = int.Parse(txtidTipo.Text); } clnTipos tipo = new clnTipos(); tipo.IdTipo = vidtipo; tipo.Buscar(); if (tipo.DescTipo == null) { //preparando para inclusao LimparTxt(groupBox1); txtidTipo.Text = ""; txtidTipo.Enabled = false; btnIncluir.Enabled = true; btnCancelar.Enabled = true; } else { //preparando para alteracao LimparTxt(groupBox1); txtidTipo.Enabled = false; txtidTipo.Text = Convert.ToString(tipo.IdTipo); txtdescTipo.Text = Convert.ToString(tipo.DescTipo); btnAtualizar.Enabled = true; btnCancelar.Enabled = true; btnExcluir.Enabled = true; } } 68

Formulrio: FrmModelos Abaixo cdigo completo com todos os eventos e mtodos declarados: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Seguros_OO.Camada_Intermediaria.Logica_Negocios; namespace Seguros_OO.Camada_Apresentacao { public partial class FrmModelos : Form { public FrmModelos() { InitializeComponent(); } //Mtodo pblico para limpar caixas de texto public void LimparTxt(Control controles) { foreach (Control ctl in controles.Controls) { if (ctl is TextBox) ctl.Text = ""; } } private void txtidModelo_Leave(object sender, EventArgs e) { int vidmodelo = 0; if (txtidModelo.Text.Trim() != "") { vidmodelo = int.Parse(txtidModelo.Text); } clnModelos modelo= new clnModelos(); modelo.IdModelo = vidmodelo; 69

modelo.Buscar(); if (modelo.DescModelo == null) { //preparando para inclusao LimparTxt(groupBox1); txtidModelo.Text = ""; txtidModelo.Enabled = false; btnIncluir.Enabled = true; btnCancelar.Enabled = true; } else { //preparando para alteracao LimparTxt(groupBox1); txtidModelo.Enabled = false; txtidModelo.Text = Convert.ToString(modelo.IdModelo); txtdescModelo.Text = Convert.ToString(modelo.DescModelo); txtdescMarca.Text = Convert.ToString(modelo.DescMarca); btnAtualizar.Enabled = true; btnCancelar.Enabled = true; btnExcluir.Enabled = true; } } private void btnIncluir_Click(object sender, EventArgs e) { try { clnModelos modelo = new clnModelos(); //Dispara o mtodo para buscar o idModelo modelo.IdModelo = modelo.BuscarId(); modelo.DescModelo = txtdescModelo.Text; modelo.DescMarca = txtdescMarca.Text; modelo.Gravar(); string mensagem = "Registro Modelo: " + modelo.IdModelo + "\nDescrio: " + modelo.DescModelo + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); 70

} catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } private void btnAtualizar_Click(object sender, EventArgs e) { try { clnModelos modelo = new clnModelos(); modelo.IdModelo = int.Parse(txtidModelo.Text); modelo.DescModelo= txtdescModelo.Text; modelo.DescMarca = txtdescMarca.Text; modelo.Atualizar(); string mensagem = "Registro Modelo: " + modelo.IdModelo + "\nNome: " + modelo.DescModelo + "\nAlterado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidModelo.Enabled = true; txtidModelo.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } 71

LimparTxt(groupBox1); btnIncluir.Enabled = false; btnCancelar.Enabled = false; txtidModelo.Enabled = true; txtidModelo.Focus();

private void btnExcluir_Click(object sender, EventArgs e) { try { string pergunta; pergunta = "Deseja excluir o modelo: \n" + txtidModelo.Text + ": " + txtdescModelo.Text + " ?"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { clnModelos modelo = new clnModelos(); modelo.IdModelo = int.Parse(txtidModelo.Text); modelo.DescModelo = txtdescModelo.Text; modelo.Excluir(); string mensagem = "Registro Dano: " + modelo.IdModelo + "\nDescrio: " + modelo.DescModelo + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidModelo.Enabled = true; txtidModelo.Focus(); } else { MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch(Exception ex) { MessageBox.Show("No foi possvel excluir, aconteceu " + " o seguinte erro: "+ ex.Message.ToString()); 72

private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox1); btnIncluir.Enabled = false; btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidModelo.Enabled = true; txtidModelo.Focus(); } private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta Tipos de Danos"; f.Tag = "tbModelo"; //nome da tabela (macete) :) f.ShowDialog(); } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } } } Concluso Como vimos. A tabela de aplices considerada a mais importante do Sistema e para que possa ser feito o cadastro de uma nova aplice, precisamos de alguns dados auxiliares. Estes dados podero ser cadastrados a partir das classes que representam a lgica de negcios e a respectiva camada de apresentao criadas durante este artigo. Respectivamente: Dano, Tipo de Sinistro, e Modelos de Carros. Gostaria de lembrar a todos que faltam apenas dois artigos, e ao final colocarei disponvel o cdigo, para que possveis erros cometidos durante as partes mo na massa no venham a prejudic-lo. 73

Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte 6 - Exemplo prtico [Outras Classes] Neste artigo vamos criar as classes que representam a lgica de negcios e a respectiva camada de apresentao para as informaes sobre a aplice e parcelas, nesta mesma ordem, ou seja, sero adicionadas as classes: clnApolices.cs e clnParcelas, veja Figura 2 - Classes Adicionadas. Desenvolvendo uma aplicao Multicamadas para Windows em C#
Parte 6) Introduo

Este artigo o sexto de uma srie de artigos que apresentam um exemplo prtico e simples abordando o desenvolvimento em camadas em C#, sabemos que a programao orientada a objetos (POO) possibilita uma abordagem simples para a utilizao de dados usando objetos. No ltimo artigo, criamos as classes de negcio: clnDanos, clnTipo e clnModelos. Observe a Figura 1 - Diagrama ER Numerado.

Figura 1 - Diagrama ER Numerado 74

Relembrando: A tabela de aplices sem dvida a mais importante do Sistema e para que possa ser feito o cadastro de uma nova aplice inicialmente temos que possuir dados nas tabelas de clientes (tbCliente), no est numerada pois nos artigos anteriores implementamos sua funcionalidade, precisamos ter os dados j cadastrados na tabela de modelo de carros (tbModelo) [6] e a partir da aplice, gerar as parcelas [5] para o pagamento por parte do cliente. J em relao aos sinistros ocorridos [2] para que possa ser cadastrado, inicialmente temos que ter a aplice cadastrada [1] e tambm termos previamente cadastrados os tipos de danos [3] e os tipos de sinistros. Neste artigo vamos criar as classes que representam a lgica de negcios e a respectiva camada de apresentao para as informaes sobre a aplice e parcelas, nesta mesma ordem, ou seja, sero adicionadas as classes: clnApolices.cs e clnParcelas, veja Figura 2 - Classes Adicionadas. Mo na Massa: 1) Com o aplicativo aberto adicione duas novas classes chamadas respectivamente: clnApolices.cs, clnParcelas.cs, conforme abaixo:

Figura 2 - Classes Adicionadas Vamos iniciar o detalhamento da classe clnApolices, que representa a lgica de negcios sobre as aplices de seguros no sistema. A classe composta pelos campos privados, propriedades de acesso e funes ilustradas na 75

Figura 3 - Classe: clnApolices.cs.

Figura 3 - Classe: clnApolices.cs 2) Abaixo cdigo completo da classe clnApolices.cs using using using using System; System.Collections.Generic; System.Text; System.Data;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios 76

public class clnApolices { //1 - Campos privados a classe private int idApolice; private int idCli; private int kmVeiApolice; private string numApolice; private DateTime dataApolice; private DateTime dataValApolice; private float valorApolice; private int idModelo; private bool sinistroApolice; private int idSinistro; //2 - propriedades, acesso aos campos privados public int IdApolice { get { return idApolice; } set { idApolice = value; } } public int IdCli { get { return idCli; } set { idCli = value; } } public int KmVeiApolice { get { return kmVeiApolice; } set { kmVeiApolice = value; } } public string NumApolice { get { return numApolice; } set { numApolice = value; } } public DateTime DataApolice { get { return dataApolice; } set { dataApolice = value; } } public DateTime DataValApolice 77

{ get { return dataValApolice; } set { dataValApolice = value; } } public int IdModelo { get { return idModelo; } set { idModelo = value; } } public float ValorApolice { get { return valorApolice; } set { valorApolice = value; } } public bool SinistroApolice { get { return sinistroApolice; } set { sinistroApolice = value; } } public int IdSinistro { get { return idSinistro; } set { idSinistro = value; } } //3 - mtodos da classe de Negcios (clnApolices.cs) //3.1 Buscar dados da apolice cujo codigo foi especificado public void Buscar() { string csql; csql = "Select * From tbApolice where idApolice=" + idApolice; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; idApolice = Convert.ToInt32(dados.GetValue(0)); idCli = Convert.ToInt32(dados.GetValue(1)); kmVeiApolice = Convert.ToInt32(dados.GetValue(2)); 78

numApolice = Convert.ToString(dados.GetValue(3)); dataApolice = Convert.ToDateTime(dados.GetValue(4)); dataValApolice = Convert.ToDateTime(dados.GetValue(5)); valorApolice = float.Parse(dados.GetValue(6).ToString()); idModelo = Convert.ToInt32(dados.GetValue(7)); sinistroApolice = Convert.ToBoolean(dados.GetValue(8)); idSinistro = Convert.ToInt32(dados.GetValue(9)); } } //3.2 Buscar o prximo Id Numerico para //inclusao de um nova aplice. public int BuscarId() { string csql; csql = "Select Top 1 (idApolice) From tbApolice order by idApolice desc"; int IdBuscado; clsDados seguros = new clsDados(); IdBuscado = seguros.RetornarIdNumerico(csql); return IdBuscado; } //3.3 Mtodo para incluir uma nova apolice no //Banco de dados public void Gravar() { StringBuilder csql = new StringBuilder(); //tratando float e datas: string floatvalor = Convert.ToString(valorApolice).Replace(",", "."); string vDataApolice = dataApolice.ToString("MM/dd/yyyy"); string vDataValApolice = dataValApolice.ToString("MM/dd/yyyy"); csql.Append("Insert into tbApolice"); csql.Append("("); csql.Append("idApolice,"); csql.Append("idCli,"); csql.Append("kmVeiApolice,"); csql.Append("numApolice,"); csql.Append("dataApolice,"); csql.Append("dataValApolice,"); csql.Append("valorApolice,"); csql.Append("idModelo,"); 79

csql.Append("sinistroApolice,"); csql.Append("idSinistro) Values("); csql.Append(idApolice); csql.Append("," + idCli + ","); csql.Append(kmVeiApolice + ","); csql.Append("'" + numApolice + "',"); csql.Append("'" + vDataApolice + "',"); csql.Append("'" + vDataValApolice + "',"); csql.Append("'" + floatvalor + "',"); csql.Append(idModelo + ","); csql.Append("'" + sinistroApolice + "',"); csql.Append(idSinistro + ")"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.4 Mtodo para atualizar (alterar um registro) public void Atualizar() { string vValorApolice = Convert.ToString(valorApolice).Replace(",", "."); string vDataApolice = dataApolice.ToString("MM/dd/yyyy"); string vDataValApolice = dataValApolice.ToString("MM/dd/yyyy"); StringBuilder csql = new StringBuilder(); csql.Append("Update tbApolice "); csql.Append("set idApolice="); csql.Append(idApolice); csql.Append(", idcli="); csql.Append(idCli); csql.Append(", kmVeiApolice="); csql.Append(kmVeiApolice); csql.Append(", numApolice='"); csql.Append(numApolice); csql.Append("', dataApolice='"); csql.Append(vDataApolice); csql.Append("', dataValApolice='"); csql.Append(vDataValApolice); csql.Append("', valorApolice='"); csql.Append(vValorApolice); csql.Append("', idModelo="); csql.Append(idModelo); csql.Append(", idSinistro="); 80

csql.Append(idSinistro); csql.Append(" where idApolice="); csql.Append(idApolice); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Mtodo para excluir um cliente do //Banco de dados public void Excluir() { StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbApolice "); csql.Append(" where idApolice="); csql.Append(idApolice); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } }

} 3) Agora, vamos montar a classe que representa a lgica de negcios do controle de parcelas pagas e a pagar do Sistema de Aplices de Seguros. Esta classe possui mtodos diferentes dos implementados at o momento que vale a pena ressaltar. Primeiro vamos conhecer a estrutura da classe clnParcelas, logo em seguida sero

81

explicadas as novidades nesta classe. Veja na Figura 4 - Classe: clnParcelas.cs.

Figura 4 - Classe: clnParcelas.cs 4) Cdigo completo da classe acima representada. using using using using using System; System.Collections.Generic; System.Text; System.Data; System.Data.SqlClient;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { public class clnParcelas 82

{ //1 - Campos privados a classe private int nroParcela; private int idApolice; private DateTime dataVenParcela; private float valParcela; private bool quitadaParcela; private DateTime quitadaData; //2 - propriedades, acesso aos campos privados public int NroParcela { get { return nroParcela; } set { nroParcela = value; } } public int IdApolice { get { return idApolice; } set { idApolice = value; } } public DateTime DataVenParcela { get { return dataVenParcela; } set { dataVenParcela = value; } } public float ValParcela { get { return valParcela; } set { valParcela = value; } } public bool QuitadaParcela { get { return quitadaParcela; } set { quitadaParcela = value; } } public DateTime QuitadaData { get { return quitadaData; } set { quitadaData = value; } } //3 - mtodos da classe de Negcios (clnParcelas.cs) 83

//3.1 Buscar dados da Parcela da Apolice cujo codigo foi especificado public DataSet Buscar() { string csql; //note que aqui estamos filtrando pelo nmero idApolice csql = "Select * From tbParcela where idApolice=" + idApolice; DataSet ds; clsDados seguros = new clsDados(); //Essa Busca retorna um objeto dataset //que vai preencer o grid de parcelas ds = seguros.RetornarDataSet(csql); return ds; } //3.2 Mtodo para incluir uma parcela public void Gravar() { string floatvalor = Convert.ToString(valParcela).Replace(",", "."); string vDataVenParcela = dataVenParcela.ToString("MM/dd/yyyy"); string vQuidataData = quitadaData.ToString("MM/dd/yyyy"); if (vQuidataData.Trim() == "01/01/0001") vQuidataData = ""; StringBuilder csql = new StringBuilder(); csql.Append("Insert into tbParcela"); csql.Append("("); csql.Append("nroParc,"); csql.Append("idApolice,"); csql.Append("dataVenParcela,"); csql.Append("valParcela,"); csql.Append("quitadaParcela,"); csql.Append("quitadaData) Values("); csql.Append(nroParcela); csql.Append("," + idApolice + ","); csql.Append("'" + vDataVenParcela + "',"); csql.Append("'" + floatvalor + "',"); csql.Append("'" + quitadaParcela + "',"); csql.Append("'" + vQuidataData + "')"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.3 Mtodo para atualizar (alterar um registro) 84

public void Atualizar() { string vQuidataData = quitadaData.ToString("MM/dd/yyyy"); string vdataVenParcela = dataVenParcela.ToString("MM/dd/yyyy"); StringBuilder csql = new StringBuilder(); csql.Append("Update tbParcela "); csql.Append("set nroParc="); csql.Append(nroParcela); csql.Append(", idApolice="); csql.Append(idApolice); csql.Append(", dataVenParcela='"); csql.Append(vdataVenParcela); csql.Append("', valParcela='"); csql.Append(valParcela.ToString().Replace(",",".")); csql.Append("', quitadaParcela='"); csql.Append(quitadaParcela); csql.Append("', quitadaData='"); csql.Append(vQuidataData); csql.Append("' where (idApolice="); csql.Append(idApolice); csql.Append(" and nroParc="); csql.Append(nroParcela); csql.Append(")"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.4 Mtodo para excluir uma parcela public void Excluir() { StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbParcela "); csql.Append(" where nr0Pac="); csql.Append(nroParcela + " and "); csql.Append(" idApolice=" + idApolice); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Novo Mtodo para Busca Especfica de Parcela public void BuscarParcEspec() { string csql; 85

csql = "Select * From tbParcela where idApolice=" + idApolice + " and nroParc=" + nroParcela; DataSet ds; clsDados seguros = new clsDados(); ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; nroParcela = Convert.ToInt32(dados.GetValue(0)); idApolice = Convert.ToInt32(dados.GetValue(1)); dataVenParcela = Convert.ToDateTime(dados.GetValue(2)); valParcela = float.Parse(dados.GetValue(3).ToString()); quitadaParcela = Convert.ToBoolean(dados.GetValue(4)); quitadaData = Convert.ToDateTime(dados.GetValue(5)); } } }

Camada de Apresentao 5) Uma vez montadas as classes, vamos alternar para a camada de apresentao e acrescentar dois novos formulrios tipo Winforms, chamados respectivamente: FrmApolices.cs e FrmParcelas.cs, veja Figura 5 - Novos Formulrios.

86

Figura 5 - Novos Formulrios. 6) O primeiro formulrio FrmApolices.cs deve possuir sua aparncia conforme mostra a Figura 6 - Manuteno de Aplices.

Figura 6 - Manuteno de Aplices Explicando o funcionamento do Formulrio de Manuteno de Aplices. Nesta tela o usurio poder incluir novas aplices, consultar aplices existentes, excluir e alterar dados das aplices. Funcionalidades estas, que j foram explicadas nos artigos anteriores. Apesar disso, como este formulrio pode ser considerado como um dos principais da aplicao, iremos comentar o cdigo na seqncia da execuo das aes por parte do usurio do sistema. Detalhando: Quando o formulrio for carregado ficaro apenas habilitados os botes Procurar, Parcelas, Sair e Ver 87

Sinistro. Ento modifique as propriedades enabled dos outros botes para false. Quando o usurio digitar o Cdigo da Aplice no Sistema, no momento em que o campo perder o foco, ser executado uma busca no sistema que trar os dados de aplice cadastrado ou apresentar a indicao que indica um nmero automtico para a nova aplice. 1) Abaixo o cdigo que representa esse procedimento, txtidApolice_Leave(...): private void txtidApolice_Leave(object sender, EventArgs e) { int vidApolice=0; if (txtidApolice.Text.Trim() != "") { vidApolice = int.Parse(txtidApolice.Text); } clnApolices apolice = new clnApolices(); apolice.IdApolice = vidApolice; apolice.Buscar(); if (apolice.IdCli == 0) { //preparando para inclusao LimparTxt(groupBox1); txtidApolice.Text = ""; txtidApolice.Enabled = false; btnIncluir.Enabled = true; btnCancelar.Enabled = true; } else { //preparando para alteracao LimparTxt(groupBox1); txtidApolice.Enabled = false; txtidApolice.Text = Convert.ToString(apolice.IdApolice); txtidCli.Text = Convert.ToString(apolice.IdCli); txtkmVeiApolice.Text = Convert.ToString(apolice.KmVeiApolice); txtnumApolice.Text = Convert.ToString(apolice.NumApolice); txtdataApolice.Text = apolice.DataApolice.ToShortDateString(); txtdataValApolice.Text = apolice.DataValApolice.ToShortDateString(); txtvalorApolice.Text = Convert.ToString(apolice.ValorApolice); txtidModelo.Text = Convert.ToString(apolice.IdModelo); if (apolice.SinistroApolice == true) optSim.Checked = true; 88

else optNao.Checked = true; txtidSinistro.Text = Convert.ToString(apolice.IdSinistro); btnAtualizar.Enabled = true; btnCancelar.Enabled = true; btnExcluir.Enabled = true; } } O prximo cdigo que explicado agora, trata da busca do dado: nome na tabela: clientes, assim que for digitado um cdigo para este. Quando ocorre uma mudana (TextChanged) na caixa de texto txtidCli instanciado um objeto cliente e feito a procura do nome, retornando-o para o label lblnomeCli ou deixando este vazio. 2) Cdigo do evento TextChanged do txtidCli abaixo: private void txtidCli_TextChanged(object sender, EventArgs e) { clnClientes cliente = new clnClientes(); if (txtidCli.Text.Trim() == "") { lblnomeCli.Text = ""; return; } cliente.IdCli = int.Parse(txtidCli.Text); cliente.Buscar(); if (cliente.NomeCli != null) lblnomeCli.Text = cliente.NomeCli; else lblnomeCli.Text = ""; } Da mesma forma ocorre quando a caixa de texto txtidModelo alterada. 3) Abaixo cdigo TextChanged da caixa de texto txtidModelo. private void txtidModelo_TextChanged(object sender, EventArgs e) { clnModelos modelo = new clnModelos(); if (txtidModelo.Text.Trim() == "") { 89

lbldescModelo.Text = ""; return; } modelo.IdModelo = int.Parse(txtidModelo.Text); modelo.Buscar(); if (modelo.DescModelo != null) lbldescModelo.Text = modelo.DescModelo; else lbldescModelo.Text = ""; } Voc deve ter percebido os botes com este texto [...]. Estes botes tem como finalidade chamar o formulrio de pesquisa genrico que criamos (artigos anteriores) passando o nome da tabela na propriedade tag, que j foi tambm explicado. 4) Abaixo cdigo do evento Click no boto btnBuscaCli. private void btnBuscaCli_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados dos clientes"; f.Tag = "tbCliente"; //nome da tabela (macete) :) f.ShowDialog(); } 5) Abaixo cdigo do evento Click no boto btnBuscaMod. private void btnBuscaMod_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados de Modelos Cadastrados"; f.Tag = "tbModelo"; //nome da tabela (macete) :) f.ShowDialog(); } 6) Abaixo cdigo do boto btnIncluir. Evento click. private void btnIncluir_Click(object sender, EventArgs e) { try { clnApolices apolice = new clnApolices(); 90

//Dispara o mtodo para buscar o idApolice apolice.IdApolice = apolice.BuscarId(); apolice.IdCli = int.Parse(txtidCli.Text); apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text); apolice.NumApolice = txtnumApolice.Text; apolice.DataApolice =Convert.ToDateTime(txtdataApolice.Text); apolice.DataValApolice = Convert.ToDateTime(txtdataValApolice.Text); apolice.ValorApolice = float.Parse(txtvalorApolice.Text); apolice.IdModelo = int.Parse(txtidModelo.Text); if (optSim.Checked == true) apolice.SinistroApolice = true; if (optNao.Checked == true) apolice.SinistroApolice = false; if (txtidSinistro.Text.Trim()!="") apolice.IdSinistro = int.Parse(txtidSinistro.Text); apolice.Gravar(); string mensagem = "Registro Aplice: " + apolice.IdApolice + "\nNome: " + lblnomeCli.Text + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnIncluir.Enabled = false; btnCancelar.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } 7) Abaixo cdigo do boto btnAtualizar. Evento click. private void btnAtualizar_Click(object sender, EventArgs e) { try { clnApolices apolice = new clnApolices(); apolice.IdApolice = int.Parse(txtidApolice.Text); 91

apolice.IdCli = int.Parse(txtidCli.Text); apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text); apolice.NumApolice = txtnumApolice.Text; apolice.DataApolice = DateTime.Parse(txtdataApolice.Text); apolice.DataValApolice = DateTime.Parse(txtdataValApolice.Text); apolice.ValorApolice = float.Parse(txtvalorApolice.Text); apolice.IdModelo = int.Parse(txtidModelo.Text); if (optSim.Checked == true) apolice.SinistroApolice = true; else apolice.SinistroApolice = false; if (txtidSinistro.Text.Trim() != "") apolice.IdSinistro = int.Parse(txtidSinistro.Text); apolice.Atualizar(); string mensagem = "Registro Aplice: " + apolice.IdApolice + "\nApolice: " + apolice.NumApolice + "\nNome: " + lblnomeCli.Text + "\nAlterada com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } }

8) Abaixo cdigo do boto btnExcluir. Evento click. private void btnExcluir_Click(object sender, EventArgs e) { 92

string pergunta; pergunta = "Deseja excluir a apolice de: \n" + lblnomeCli.Text + " N Registro: " + txtidApolice.Text + " ?"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { clnApolices apolice = new clnApolices(); apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Excluir(); string mensagem = "Registro Aplice de: " + lblnomeCli.Text + "\nN registro: " + apolice.IdApolice + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } else { MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information); } } 9) Abaixo cdigo do boto btnCancelar. Evento click. private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox1); btnIncluir.Enabled = false; btnAtualizar.Enabled = false; btnCancelar.Enabled = false; 93

btnExcluir.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } 10) Abaixo cdigo do boto btnSair. Evento click. private void btnSair_Click(object sender, EventArgs e) { this.Close(); } 11) Abaixo cdigo do boto btnProcurar. Evento click. private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados de Apolices"; f.Tag = "tbApolice"; //nome da tabela (macete) :) f.ShowDialog(); } J o evento do boto btnParcelas, merece alguns comentrios. Primeiramente instanciado uma varivel objeto que chamamos de parcela, a qual recebe o nmero da aplice digitada pelo usurio na caixa de texto txtidApolice. instanciado um novo formulrio e passado alguns valores para objetos pertencentes ao formulrio, que ainda criaremos, que o FrmParcelas.cs. Importante: voc s ter acesso aos objetos do formulrio instanciados se o modificador de acesso estiver como pblico, ou seja, a propriedade Modifiers de cada objeto deve estar como Public no formulrio FrmParcelas. 12) Abaixo cdigo do evento click desse boto. private void btnParcelas_Click(object sender, EventArgs e) { clnApolices apolice = new clnApolices(); if (txtidApolice.Text == "") { MessageBox.Show("Selecione uma Aplice"); return; } apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Buscar(); 94

FrmParcelas f = new FrmParcelas(); f.txtdataApolice.Text = apolice.DataApolice.ToShortDateString(); f.txtidApolice.Text = Convert.ToString(apolice.IdApolice); f.txtnomeCli.Text = Convert.ToString(lblnomeCli.Text); f.ShowDialog(); } Bom, terminamos o formulrio FrmApolices.cs. Antes de continuarmos, vou deixar o cdigo completo aqui para facilitar, caso voc queira copi-lo todo. Lembre-se depois de instanciar os eventos, caso contrrio d erro. using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; Seguros_OO.Camada_Intermediaria.Logica_Negocios;

namespace Seguros_OO.Camada_Apresentacao { public partial class FrmApolices : Form { public FrmApolices() { InitializeComponent(); } //Mtodo pblico para limpar caixas de texto public void LimparTxt(Control controles) { foreach (Control ctl in controles.Controls) { if (ctl is TextBox) ctl.Text = ""; } } private void txtidApolice_Leave(object sender, EventArgs e) { int vidApolice=0; if (txtidApolice.Text.Trim() != "") 95

{ vidApolice = int.Parse(txtidApolice.Text); } clnApolices apolice = new clnApolices(); apolice.IdApolice = vidApolice; apolice.Buscar(); if (apolice.IdCli == 0) { //preparando para inclusao LimparTxt(groupBox1); txtidApolice.Text = ""; txtidApolice.Enabled = false; btnIncluir.Enabled = true; btnCancelar.Enabled = true; } else { //preparando para alteracao LimparTxt(groupBox1); txtidApolice.Enabled = false; txtidApolice.Text = Convert.ToString(apolice.IdApolice); txtidCli.Text = Convert.ToString(apolice.IdCli); txtkmVeiApolice.Text = Convert.ToString(apolice.KmVeiApolice); txtnumApolice.Text = Convert.ToString(apolice.NumApolice); txtdataApolice.Text = apolice.DataApolice.ToShortDateString(); txtdataValApolice.Text = apolice.DataValApolice.ToShortDateString(); txtvalorApolice.Text = Convert.ToString(apolice.ValorApolice); txtidModelo.Text = Convert.ToString(apolice.IdModelo); if (apolice.SinistroApolice == true) optSim.Checked = true; else optNao.Checked = true; txtidSinistro.Text = Convert.ToString(apolice.IdSinistro); btnAtualizar.Enabled = true; btnCancelar.Enabled = true; btnExcluir.Enabled = true; } } private void btnIncluir_Click(object sender, EventArgs e) { 96

try { clnApolices apolice = new clnApolices(); //Dispara o mtodo para buscar o idApolice apolice.IdApolice = apolice.BuscarId(); apolice.IdCli = int.Parse(txtidCli.Text); apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text); apolice.NumApolice = txtnumApolice.Text; apolice.DataApolice =Convert.ToDateTime(txtdataApolice.Text); apolice.DataValApolice = Convert.ToDateTime(txtdataValApolice.Text); apolice.ValorApolice = float.Parse(txtvalorApolice.Text); apolice.IdModelo = int.Parse(txtidModelo.Text); if (optSim.Checked == true) apolice.SinistroApolice = true; if (optNao.Checked == true) apolice.SinistroApolice = false; if (txtidSinistro.Text.Trim()!="") apolice.IdSinistro = int.Parse(txtidSinistro.Text); apolice.Gravar(); string mensagem = "Registro Aplice: " + apolice.IdApolice + "\nNome: " + lblnomeCli.Text + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnIncluir.Enabled = false; btnCancelar.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } private void btnAtualizar_Click(object sender, EventArgs e) { try { clnApolices apolice = new clnApolices(); 97

apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.IdCli = int.Parse(txtidCli.Text); apolice.KmVeiApolice = int.Parse(txtkmVeiApolice.Text); apolice.NumApolice = txtnumApolice.Text; apolice.DataApolice = DateTime.Parse(txtdataApolice.Text); apolice.DataValApolice = DateTime.Parse(txtdataValApolice.Text); apolice.ValorApolice = float.Parse(txtvalorApolice.Text); apolice.IdModelo = int.Parse(txtidModelo.Text); if (optSim.Checked == true) apolice.SinistroApolice = true; else apolice.SinistroApolice = false; if (txtidSinistro.Text.Trim() != "") apolice.IdSinistro = int.Parse(txtidSinistro.Text); apolice.Atualizar(); string mensagem = "Registro Aplice: " + apolice.IdApolice + "\nApolice: " + apolice.NumApolice + "\nNome: " + lblnomeCli.Text + "\nAlterada com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } private void btnExcluir_Click(object sender, EventArgs e) { string pergunta; pergunta = "Deseja excluir a apolice de: \n" + 98

lblnomeCli.Text + " N Registro: " + txtidApolice.Text + " ?"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { clnApolices apolice = new clnApolices(); apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Excluir(); string mensagem = "Registro Aplice de: " + lblnomeCli.Text + "\nN registro: " + apolice.IdApolice + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); LimparTxt(groupBox1); btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); } else { MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox1); btnIncluir.Enabled = false; btnAtualizar.Enabled = false; btnCancelar.Enabled = false; btnExcluir.Enabled = false; txtidApolice.Enabled = true; txtidApolice.Focus(); 99

} private void btnSair_Click(object sender, EventArgs e) { this.Close(); } private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados de Apolices"; f.Tag = "tbApolice"; //nome da tabela (macete) :) f.ShowDialog(); } private void txtidCli_TextChanged(object sender, EventArgs e) { clnClientes cliente = new clnClientes(); if (txtidCli.Text.Trim() == "") { lblnomeCli.Text = ""; return; } cliente.IdCli = int.Parse(txtidCli.Text); cliente.Buscar(); if (cliente.NomeCli != null) lblnomeCli.Text = cliente.NomeCli; else lblnomeCli.Text = ""; } private void btnBuscaCli_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados dos clientes"; f.Tag = "tbCliente"; //nome da tabela (macete) :) f.ShowDialog(); } private void btnBuscaMod_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); 100

f.Text = "Consulta dados de Modelos Cadastrados"; f.Tag = "tbModelo"; //nome da tabela (macete) :) f.ShowDialog(); } private void txtidModelo_TextChanged(object sender, EventArgs e) { clnModelos modelo = new clnModelos(); if (txtidModelo.Text.Trim() == "") { lbldescModelo.Text = ""; return; } modelo.IdModelo = int.Parse(txtidModelo.Text); modelo.Buscar(); if (modelo.DescModelo != null) lbldescModelo.Text = modelo.DescModelo; else lbldescModelo.Text = ""; } private void btnParcelas_Click(object sender, EventArgs e) { clnApolices apolice = new clnApolices(); if (txtidApolice.Text == "") { MessageBox.Show("Selecione uma Aplice"); return; } apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Buscar(); FrmParcelas f = new FrmParcelas(); f.txtdataApolice.Text = apolice.DataApolice.ToShortDateString(); f.txtidApolice.Text = Convert.ToString(apolice.IdApolice); f.txtnomeCli.Text = Convert.ToString(lblnomeCli.Text); f.ShowDialog(); } } } Explicando o funcionamento do Formulrio de Manuteno de Parcelas. 101

1) O segundo formulrio, deste artigo, o FrmParcelas.cs, que deve possuir a aparncia conforme mostra a Figura 7 - Manuteno de Parcelas.

Figura 7 - Manuteno de Parcelas 2) Altere as propriedades enabled dos controles txtparcquit, dtDataQuit e btnOk, para false, ou seja, esses controles estaro desabilitados, a no ser que trate-se de uma quitao de parcelas. Fato que ocorrer quando o usurio clicar no boto btnQuitar. O formulrio ser carregado quando o usurio clicar no boto Parcelas do formulrio FrmApolices.cs. Ao ser carregado, ele recebe os valores passados atravs do outro form, como tambm vimos anteriormente. Estes valores recebidos, so tratados logo no evento Load do formulrio. 3) Abaixo o cdigo do evento Load do FrmParcelas.cs 102

private void FrmParcelas_Load(object sender, EventArgs e) { clnParcelas parcela = new clnParcelas(); parcela.IdApolice = int.Parse(txtidApolice.Text); this.dgParcelas.DataSource = parcela.Buscar().Tables[0]; int cont = this.dgParcelas.Rows.Count; if (cont == 0) { btnGerar.Enabled = true; btnQuitar.Enabled = false; } else { btnGerar.Enabled = false; btnQuitar.Enabled = true; txtnumGerar.Enabled = false; txtValorParcela.Enabled = false; txtVcto.Enabled = false; } O Bloco if acima (cont==0), ser executado quando no houver parcelas ainda cadastradas para a aplice recuperada. Tratamos os botes gerar e quitar respectivamente para ambos os casos, ou seja, se no houver parcelas cadastradas o boto gerar ser habilitado e o quitar desabilitado, caso contrrio, ocorre o oposto. baixo o cdigo para gerar parcelas. 4) Evento click do boto btnGerar. private void btnGerar_Click(object sender, EventArgs e) { clnParcelas parcela = new clnParcelas(); int numParcGerar = int.Parse(txtnumGerar.Text); if ((numParcGerar <= 0) || (numParcGerar > 12)) { MessageBox.Show("Nmero de parcelas entre 1 e 12"); return; } if(float.Parse(txtValorParcela.Text.Replace(",",".")) <= 0) { MessageBox.Show("Valor de Parcela Invlido"); return; } 103

try { DateTime data = Convert.ToDateTime(txtVcto.Text); string Mensagem; Mensagem = "Sero geradas " + txtnumGerar.Text + " parcelas, com a primeira data de vencimento " + "em " + data.ToShortDateString(); MessageBox.Show(Mensagem); //gerando parcelas. int i = 0; for (i = 0; i < numParcGerar; i++) { parcela.NroParcela = i + 1; parcela.IdApolice = int.Parse(txtidApolice.Text); parcela.DataVenParcela = data; data = data.AddDays(30); parcela.ValParcela = float.Parse(txtValorParcela.Text); parcela.Gravar(); } this.dgParcelas.DataSource = parcela.Buscar().Tables[0]; } catch (Exception ex) { MessageBox.Show("Ocorreu o erro: " + ex.Message); } } Alguns comentrios sobre esse evento. Inicialmente instanciamos a parcela. Verificamos se o nmero de parcelas est dentro da faixa possvel entre 1 e o nmero de parcelas que existir. E tambm verificamos se j no est quitada. Se as condies para gerar as parcelas forem atendidas, o bloco for responsvel pela insero de novas parcelas na tbParcela. E mais abaixo a propriedade DataSource do dgParcelas atualizada com as parcelas geradas sendo assim exibidas no grid. 5) Agora vamos ao cdigo que responder ao evento click no boto btnQuitar. private void btnQuitar_Click(object sender, EventArgs e) { this.txtparcquit.Enabled = true; this.dtDataQuit.Enabled = true; this.dtDataQuit.Value= DateTime.Now; btnOk.Enabled = true; this.txtparcquit.Focus(); 104

this.btnQuitar.Enabled = false; } Esse cdigo simples, apenas habilita os controles acima do grid para a digitao do nmero da parcela a quitar e a data respectiva da quitao. 6) Agora o cdigo que executa o lanamento de quitao de parcelas manualmente pelo usurio. Evento click do boto btnOk. private void btnOk_Click(object sender, EventArgs e) { try { int vnumParc = int.Parse(txtparcquit.Text); if (vnumParc > dgParcelas.Rows.Count || vnumParc<=0) { MessageBox.Show("Parcela Invlida"); return; } clnParcelas parcela = new clnParcelas(); parcela.IdApolice = int.Parse(txtidApolice.Text); parcela.NroParcela = vnumParc; parcela.BuscarParcEspec(); if (parcela.QuitadaParcela == true) { MessageBox.Show("Parcela j quitada"); return; } parcela.QuitadaParcela = true; parcela.QuitadaData = dtDataQuit.Value; parcela.Atualizar(); //atualiza o grid this.dgParcelas.DataSource = parcela.Buscar().Tables[0]; this.txtparcquit.Enabled = false; this.dtDataQuit.Enabled = false; btnOk.Enabled = false; this.btnQuitar.Enabled = true; MessageBox.Show("Quitao Registrada"); } catch (Exception ex) { MessageBox.Show("Ocorreu o erro: " + ex.Message); 105

} } Abaixo todo o cdigo desse formulrio: using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; Seguros_OO.Camada_Intermediaria.Logica_Negocios;

namespace Seguros_OO.Camada_Apresentacao { public partial class FrmParcelas : Form { public FrmParcelas() { InitializeComponent(); } private void btnGerar_Click(object sender, EventArgs e) { clnParcelas parcela = new clnParcelas(); int numParcGerar = int.Parse(txtnumGerar.Text); if ((numParcGerar <= 0) || (numParcGerar > 12)) { MessageBox.Show("Nmero de parcelas entre 1 e 12"); return; } if(float.Parse(txtValorParcela.Text.Replace(",",".")) <= 0) { MessageBox.Show("Valor de Parcela Invlido"); return; } try { DateTime data = Convert.ToDateTime(txtVcto.Text); string Mensagem; Mensagem = "Sero geradas " + txtnumGerar.Text + 106

" parcelas, com a primeira data de vencimento " + "em " + data.ToShortDateString(); MessageBox.Show(Mensagem); //gerando parcelas. int i = 0; for (i = 0; i < numParcGerar; i++) { parcela.NroParcela = i + 1; parcela.IdApolice = int.Parse(txtidApolice.Text); parcela.DataVenParcela = data; data = data.AddDays(30); parcela.ValParcela = float.Parse(txtValorParcela.Text); parcela.Gravar(); } this.dgParcelas.DataSource = parcela.Buscar().Tables[0]; } catch (Exception ex) { MessageBox.Show("Ocorreu o erro: " + ex.Message); } } private void FrmParcelas_Load(object sender, EventArgs e) { clnParcelas parcela = new clnParcelas(); parcela.IdApolice = int.Parse(txtidApolice.Text); this.dgParcelas.DataSource = parcela.Buscar().Tables[0]; int cont = this.dgParcelas.Rows.Count; if (cont == 0) { btnGerar.Enabled = true; btnQuitar.Enabled = false; } else { btnGerar.Enabled = false; btnQuitar.Enabled = true; txtnumGerar.Enabled = false; txtValorParcela.Enabled = false; txtVcto.Enabled = false; } 107

} private void btnQuitar_Click(object sender, EventArgs e) { this.txtparcquit.Enabled = true; this.dtDataQuit.Enabled = true; this.dtDataQuit.Value= DateTime.Now; btnOk.Enabled = true; this.txtparcquit.Focus(); this.btnQuitar.Enabled = false; } private void btnOk_Click(object sender, EventArgs e) { try { int vnumParc = int.Parse(txtparcquit.Text); if (vnumParc > dgParcelas.Rows.Count || vnumParc<=0) { MessageBox.Show("Parcela Invlida"); return; } clnParcelas parcela = new clnParcelas(); parcela.IdApolice = int.Parse(txtidApolice.Text); parcela.NroParcela = vnumParc; parcela.BuscarParcEspec(); if (parcela.QuitadaParcela == true) { MessageBox.Show("Parcela j quitada"); return; } parcela.QuitadaParcela = true; parcela.QuitadaData = dtDataQuit.Value; parcela.Atualizar(); //atualiza o grid this.dgParcelas.DataSource = parcela.Buscar().Tables[0]; this.txtparcquit.Enabled = false; this.dtDataQuit.Enabled = false; btnOk.Enabled = false; this.btnQuitar.Enabled = true; MessageBox.Show("Quitao Registrada"); } 108

catch (Exception ex) { MessageBox.Show("Ocorreu o erro: " + ex.Message); } } } } Concluso: Nesse artigo criamos as classes que representam a lgica de negcios e a respectiva camada de apresentao para as informaes sobre a aplice e parcelas, nesta mesma ordem, ou seja, foram adicionadas as novas classes: clnApolices.cs e clnParcelas e criados dois novos formulrios o FrmApolices.cs e o FrmParcelas.cs

Desenvolvimento Multicamadas em Csharp (C#(csharp)) - Parte FINAL - Exemplo prtico Neste ltimo artigo vamos criar a classe que representa a lgica de negcio e a respectiva camada de apresentao para as informaes sobre sinistros, ou seja, ser adicionada a classe: clnSinistros. Desenvolvendo uma aplicao Multicamadas para Windows em C# Parte Final) Introduo Bom. :-) Saudaes aos amigos que chegaram at aqui. Agradeo aos que adicionaram os meus artigos como seus favoritos, pois me motivaram a escrever mais. Gostaria de fazer apenas um pequeno esclarecimento antes de iniciar esta ltima parte. Gosto de escrever e no tenho inteno em cobrar por meus artigos aqui no devmedia, no tenho nada contra aos posts pagos, ao contrtio, acho importante que as pessoas recebam pelo trabalho que fazem. Porm o meu objetivo compartilhar conhecimento, trocar experincias e aprender com os demais colegas de profisso que comungam da mesma idia. Sempre compro posts dos meus autores favoritos. Mas acho que em parte limitam essa minha inteno. O importante que mais pessoas comecem a escrever e descobrir o quanto esta comunidade colabora com suas dvidas e principalmente crticas construtivas. Isto s contribui para os meus conhecimentos e aprendizado de todos. Feito a observao. Vamos a parte final. 109

Este artigo o ltimo de uma srie de sete artigos que apresentaram ao longo deste mtimo ms um exemplo prtico e simples abordando o desenvolvimento em camadas em C#. No artigo passado, nmero seis, criamos as classes de negcio que clnApolices e clnParcelas, alm dos formulrios que compem a camada de apresentao.

Veja novamente a Figura 1 - Diagrama ER Numerado.

Figura 1 - Diagrama ER Numerado Relembrando: A tabela de aplices sem dvida a mais importante do Sistema e para que possa ser feito o cadastro de uma nova aplice inicialmente temos que possuir dados nas tabelas de clientes (tbCliente), no est numerada pois nos artigos anteriores implementamos sua funcionalidade. Precisamos ter os dados j cadastrados na tabela de 110

modelo de carros (tbModelo) [6] e a partir da aplice gerar as parcelas [5] para o pagamento por parte do cliente. J em relao aos sinistros ocorridos [2] para que possa ser cadastrado, inicialmente temos que ter a aplice cadastrada [1] e termos tambm previamente cadastrados os tipos de danos [3] e os tipos de sinistros j cadastrados. Neste ltimo artigo vamos criar a classe que representa a lgica de negcio e a respectiva camada de apresentao para as informaes sobre sinistros, ou seja, ser adicionada a classe: clnSinistros. Tambm adicionaremos um formulrio de splash e um formulrio principal na camada de apresentao. Mo na Massa: 1) Com o aplicativo aberto adicione uma nova classe chamada clnSinistros.cs.

2) Abaixo cdigo da classe clnSinistro.cs, se voc tem acompanhado os artigos, no h funcionalidades difirentes das j implementadas. using using using using System; System.Collections.Generic; System.Text; System.Data;

namespace Seguros_OO.Camada_Intermediaria.Logica_Negocios { public class clnSinistros { //1 - Campos privados a classe 111

private private private private private

int idSinistro; DateTime dataSinistro; int idTipo; int idDano; string descSinistro;

//2 - propriedades, acesso aos campos privados public int IdSinistro { get { return idSinistro; } set { idSinistro = value; } } public DateTime DataSinistro { get { return dataSinistro; } set { dataSinistro = value; } } public int IdTipo { get { return idTipo; } set { idTipo = value; } } public int IdDano { get { return idDano; } set { idDano = value; } } public string DescSinistro { get { return descSinistro; } set { descSinistro = value; } } //3 - mtodos da classe de Negcios (clnSinistro.cs) //3.1 Buscar dados cujo codigo foi especificado public void Buscar() { string csql; csql = "Select * From tbSinistro where idSinistro=" + idSinistro; DataSet ds; clsDados seguros = new clsDados(); 112

ds = seguros.RetornarDataSet(csql); if (ds.Tables[0].Rows.Count > 0) { Array dados = ds.Tables[0].Rows[0].ItemArray; idSinistro = Convert.ToInt16(dados.GetValue(0)); dataSinistro = Convert.ToDateTime(dados.GetValue(1)); descSinistro = Convert.ToString(dados.GetValue(2)); idTipo = Convert.ToInt16(dados.GetValue(3)); idDano = Convert.ToInt16(dados.GetValue(4)); } } //3.2 Buscar o prximo Id Numerico para //inclusao de um novo sinistro. public int BuscarId() { string csql; csql = "Select Top 1 (idSinistro) From tbSinistro order by idSinistro desc"; int IdBuscado; clsDados seguros = new clsDados(); IdBuscado = seguros.RetornarIdNumerico(csql); return IdBuscado; } //3.3 Mtodo para incluir um novo sinistro no //Banco de dados public void Gravar() { string vdatasinistro = dataSinistro.ToString("MM/dd/yyyy"); StringBuilder csql = new StringBuilder(); csql.Append("Insert into tbSinistro"); csql.Append("("); csql.Append("idSinistro,"); csql.Append("dataSinistro,"); csql.Append("descSinistro,"); csql.Append("idTipo,"); csql.Append("idDano"); csql.Append(") Values("); csql.Append(idSinistro); csql.Append(",'" + vdatasinistro + "',"); csql.Append("'" + descSinistro + "',"); csql.Append(idTipo + ","); 113

csql.Append(idDano + ")"); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.4 Mtodo para atualizar (alterar um registro) public void Atualizar() { string vdatasinistro = dataSinistro.ToString("MM/dd/yyyy"); StringBuilder csql = new StringBuilder(); csql.Append("Update tbSinistro "); csql.Append("set idSinistro="); csql.Append(idSinistro); csql.Append(", dataSinistro='"); csql.Append(vdatasinistro); csql.Append("', descSinistro='"); csql.Append(descSinistro); csql.Append("', idTipo="); csql.Append(idTipo); csql.Append(", idDano="); csql.Append(idDano); csql.Append(" where idSinistro="); csql.Append(idSinistro); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } //3.5 Mtodo para excluir um cliente do //Banco de dados public void Excluir() { StringBuilder csql = new StringBuilder(); csql.Append("Delete From tbSinistro "); csql.Append(" where idSinistro="); csql.Append(idSinistro); clsDados seguros = new clsDados(); seguros.ExecutarComando(csql.ToString()); } }

3 ) Agora, alterne para a camada de apresentao, inclua um novo formulrio com o nome FrmSinistro.cs. 114

Figura 2 - FrmSinistros.cs

4) Acrescente os controles no formulrio e altere as propriedades conforme figura:

115

Figura 3 - Formulrios (FrmSinistros) 5) Altere as propriedades de todos os botes para enabled = false. 6) Declare os namespace. Conforme abaixo: using System; using System.Collections.Generic; using System.ComponentModel; 116

using using using using using

System.Data; System.Drawing; System.Text; System.Windows.Forms; Seguros_OO.Camada_Intermediaria.Logica_Negocios;

7) Inclua o mtodo para limpar as caixas de textos. //Mtodo pblico para limpar caixas de texto public void LimparTxt(Control controles) { foreach (Control ctl in controles.Controls) { if (ctl is TextBox) ctl.Text = ""; } } 8) Acrescente um mtodo publico sem retorno (void) chamado cancelar( ). private void cancelar() { groupBox2.Enabled = false; groupBox1.Enabled = true; txtidApolice.Text = ""; txtidApolice.Enabled = true; txtidApolice.Focus(); btnAtualizar.Enabled = false; btnIncluir.Enabled = false; btnExcluir.Enabled = false; btnCancelar.Enabled = false; } 9) Evento para o formulrio Load, assim que o formulrio for carregado, realizaremos duas tarefas. Instanciamos o objeto dadosDanos a partir da classe clnDanos( ) e o objeto dadosTipo a partir da classe clnTipos. Disparamos o mtodo BuscarTodos( ) com a finalidade de amarrar os combos, ou seja, o usurio ter no campo visual o contedo do campo descDano e descTipo respectivamente, mas o valor di item so os dipostos na propriedade DisplayMember de cada uma. Abaixo cdigo comentado. Private void FrmSinistros_Load(object sender, EventArgs e) { clnDanos dadosDanos = new clnDanos(); clnTipos dadosTipo = new clnTipos(); 117

DataSet dsDanos = dadosDanos.BuscarTodos(); DataSet dsTipos = dadosTipo.BuscarTodos(); //amarrando os combos. //Exibindos descries porm atrelamos o cdigo //para gravao. cmbTipoDano.DataSource = dsDanos.Tables[0]; cmbTipoDano.DisplayMember = descDano; cmbTipoDano.ValueMember= idDano; cmbTipoSinistro.DataSource = dsTipos.Tables[0]; cmbTipoSinistro.DisplayMember = descTipo; cmbTipoSinistro.ValueMember = idTipo; } 10) Evento TexChanged do campo txtidApolice. Ao alterar o contudo do campo, instanciamos o objeto apolice a partir da classe clnApolices( ) e o objeto cliente a partir da classe clnClientes. A finalidade do cdigo preencher os campos do tipo label. private void txtidApolice_TextChanged(object sender, EventArgs e) { clnApolices apolice = new clnApolices(); if (txtidApolice.Text.Trim() == "") { lblnomeCli.Text = ""; lbldescModelo.Text = ""; return; } apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Buscar(); clnClientes cliente = new clnClientes(); cliente.IdCli = apolice.IdCli; cliente.Buscar(); lblnomeCli.Text = cliente.NomeCli; clnModelos modelo = new clnModelos(); modelo.IdModelo = apolice.IdModelo; modelo.Buscar(); lbldescModelo.Text = modelo.DescModelo; if (lblnomeCli.Text == "") btnSinistro.Enabled = false; else btnSinistro.Enabled = true; } 118

11) Evento click do boto btnBuscar. private void btnBuscar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta dados das Aplices"; f.Tag = "tbApolice"; //nome da tabela (macete) :) f.ShowDialog(); } 12) Evento click do boto btnSinistro. private void btnSinistro_Click(object sender, EventArgs e) { groupBox2.Enabled = true; clnApolices apolice = new clnApolices(); apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Buscar(); if (apolice.IdSinistro != 0) { MessageBox.Show("Cliente j possui aplice, \n" + "Voc s poder alterar esses dados", "Aviso"); clnSinistros sinistro = new clnSinistros(); sinistro.IdSinistro = apolice.IdSinistro; sinistro.Buscar(); txtidSinistro.Text = Convert.ToString(sinistro.IdSinistro); txtdataSinistro.Text = sinistro.DataSinistro.ToString("dd/MM/yyyy"); txtdescSinistro.Text = sinistro.DescSinistro; clnDanos dano = new clnDanos(); dano.IdDano = sinistro.IdDano; dano.Buscar(); cmbTipoDano.Text = dano.DescDano; clnTipos tipo = new clnTipos(); tipo.IdTipo = sinistro.IdTipo; tipo.Buscar(); cmbTipoSinistro.Text = tipo.DescTipo; txtidSinistro.Enabled = false; txtdataSinistro.Focus(); btnAtualizar.Enabled = true; btnIncluir.Enabled = false; btnExcluir.Enabled = true; btnCancelar.Enabled = true; 119

} else { txtidSinistro.Text = ""; txtdataSinistro.Text = ""; txtdescSinistro.Text = ""; txtidSinistro.Enabled = false; txtdataSinistro.Focus(); btnAtualizar.Enabled = false; btnIncluir.Enabled = true; btnExcluir.Enabled = false; btnCancelar.Enabled = true; } groupBox1.Enabled = false; } No cdigo acima, vamos por parte. A primeira coisa que fizemos foi habilitar o groupbox2, conteiner onde se encontram os controles do cadastro de sinistros. Em seguida instanciamos um objeto apolice a partir da classe clnApolices( ), com a finalidade de verificar se houve sinistro para a aplice em questo. Se o valor do campo idSinistro for diferente de zero, indica que o cliente j possui aplice, sendo assim informamos ao mesmo que essa aplice s pode ser alterada, na verdade ela pode ser excluda, mas isso, no nos cabe orient-lo (usurio do sistema). Instanciamos o objeto dano e o objeto tipo para alimentar os campos combo com a descrio do sinistro localizado. O restante do cdigo j est bastante explorado. 13) Evento click do boto incluir. private void btnIncluir_Click(object sender, EventArgs e) { try { clnSinistros sinistro = new clnSinistros(); sinistro.IdSinistro = sinistro.BuscarId(); sinistro.DataSinistro = Convert.ToDateTime(txtdataSinistro.Text); sinistro.DescSinistro = txtdescSinistro.Text; sinistro.IdTipo = Convert.ToInt16(cmbTipoSinistro.SelectedValue); sinistro.IdDano = Convert.ToInt16(cmbTipoDano.SelectedValue); sinistro.Gravar(); //atualizar a tabela de aplice com o nmero do sinistro //e checar a apolice para sinistrada. clnApolices apolice = new clnApolices(); apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Buscar(); 120

apolice.SinistroApolice = true; apolice.IdSinistro = sinistro.IdSinistro; apolice.Atualizar(); //mostra mensagem string mensagem = "Sinistro: " + sinistro.IdSinistro + "\nCliente: " + lblnomeCli.Text + "\nGravado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, MessageBoxIcon.Information); //chamar metodo cancelar (apenas desabilita os botes) cancelar(); LimparTxt(groupBox2); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } No cdigo acima, tambm atualizamos a tabela de aplices com as informaes da ocorrncia de sinistro. Mais tarde alteraremos o cdigo do boto btnVer no formulrio de aplices que abrir o formulrio de sinistro para que possa ser verificado os dados do sinistro. 14) Evento do boto Atualizar. private void btnAtualizar_Click(object sender, EventArgs e) { try { clnSinistros sinistro = new clnSinistros(); sinistro.IdSinistro= int.Parse(txtidSinistro.Text); sinistro.DataSinistro = Convert.ToDateTime(txtdataSinistro.Text); sinistro.DescSinistro = txtdescSinistro.Text; sinistro.IdTipo = Convert.ToInt16(cmbTipoSinistro.SelectedValue); sinistro.IdDano = Convert.ToInt16(cmbTipoDano.SelectedValue); sinistro.Atualizar(); string mensagem = "Registro Sinsitro: " + sinistro.IdSinistro + "\nNome: " + lblnomeCli.Text + "\nAlterado com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, 121

MessageBoxIcon.Information); LimparTxt(groupBox2); cancelar(); } catch (Exception ex) { MessageBox.Show("Aconteu o erro: " + ex.Message, "Erro"); } } 15) Evento do boto excluir. private void btnExcluir_Click(object sender, EventArgs e) { string pergunta; pergunta = "Deseja excluir o Sinistro: " + txtidSinistro.Text + ", do cliente: " + lblnomeCli.Text + "\ndo Cadastro Atual. ?" + "\n\n\nLembre-se essa ao dever ocorrer " + "\nsomente em caso de ESTORNO"; int ret = Convert.ToInt16(MessageBox.Show(pergunta, "Ateno", MessageBoxButtons.YesNo, MessageBoxIcon.Question)); if (ret == 6) { //primeiro devemos fazer a atualizao na //tabela de apolice. clnApolices apolice = new clnApolices(); apolice.IdApolice = int.Parse(txtidApolice.Text); apolice.Buscar(); apolice.SinistroApolice = false; apolice.IdSinistro = 0; apolice.Atualizar(); //agora excluir da tabela de sinistro clnSinistros sinistro = new clnSinistros(); sinistro.IdSinistro = int.Parse(txtidSinistro.Text); sinistro.Excluir(); string mensagem = "Registro Sinistro: " + sinistro.IdSinistro + "\nNome: " + lblnomeCli.Text + "\nExcludo com sucesso"; MessageBox.Show(mensagem, "Sucesso", MessageBoxButtons.OK, 122

MessageBoxIcon.Information); LimparTxt(groupBox2); cancelar(); } else { MessageBox.Show("Operao Cancelada", "Cancelada", MessageBoxButtons.OK, MessageBoxIcon.Information); } } No cdigo do evento excluir tambm atualizamos a tabela de aplices alterando os campos sinistroApolice para falso, indicando que no houve sinistro. Esta funo dever ser realizada no caso de estorno. No nossa inteno implementar outras regras para excluso de sinistros, mas em um caso real, com certeza teria que ser ampliada estes conjunto de regras. 16) Evento do boto cancelar. private void btnCancelar_Click(object sender, EventArgs e) { LimparTxt(groupBox2); cancelar(); } 17) Evento do boto procurar. private void btnProcurar_Click(object sender, EventArgs e) { FrmPesquisa f = new FrmPesquisa(); f.Text = "Consulta Sinistros"; f.Tag = "tbSinistro"; //nome da tabela (macete) :) f.ShowDialog(); } 18) Evento do boto sair private void btnSair_Click(object sender, EventArgs e) { this.Close(); } 123

19) Altere a propriedade modifiers do controle txtidApolice para public. 20) Agora alterne para o formulrio de Aplices (FrmApolices.cs) para que possamos codificar o boto btnVer. Abaixo o cdigo para o evento click do boto. private void btnVer_Click(object sender, EventArgs e) { FrmSinistros f = new FrmSinistros(); f.txtidApolice.Text = this.txtidApolice.Text; f.ShowDialog(); txtidApolice_Leave(sender, e); //mtodo deve ser public } Camada de Apresentao: Finalizando A inteno aqui no criar formulrios cheios de detalhes, pelo contrrio sero simples apenas para finalizar o nosso exemplo. Voc poder melhor-los assim como todo o projeto. FrmSplash. ) Adicione na Camada de Apresentao um novo Formulrio do tipo splash chamado FrmSplash. Clique com o boto direito do mouse sobre o nome do projeto e escolha ADD >> New Item >> WindowsForm d o nome FrmSplash.cs. 2) Altere as propriedades do formulrio FrmSplash conforme abaixo: FormBorderStyle = none; Size = 553; 379 3) Coloque um controle picture e acrescente uma imagem de fundo com o tamanho acima.

124

Figura 4 - FrmSplash.cs 4) Adicione agora os seguintes controles: 01 progressbar; 01 timer.

Figura 5 - Controles Adicionados 125

Aqui, depois adicionaremos o cdigo. 5 ) Agora acrescente um novo formulrio chamado FrmPrincipal. Esse formulrio dever conter um menu conforme a figura.

Figura 6 - FrmPrincipal.cs 6) Altere a propriedade WindowState do formulrio para Maximized.

Funcionamento: Colocaremos o nosso projeto para ser iniciado pelo formulrio de splash, e em trs segundo ser disparado o formulrio principal, para que possamos acessar os formulrios anteriormente criados. 1) Para isso no Solution Explorer d um duplo clique no arquivo Program.cs para acessar essa classe e faa a alterao conforme abaixo: 126

2) Agora alterne para o formulrio FrmSplash, defina a propriedade enabled do timer para true. Em seguida coloque o cdigo abaixo para o evento. private void timer1_Tick(object sender, EventArgs e) { if (progressBar1.Value >= 100) { timer1.Enabled = false; FrmPrincipal f = new FrmPrincipal(); this.Hide(); f.ShowDialog(); this.Close(); } else { progressBar1.Value += 10; } } 3) Assim que a barra de progresso ter o seu valor maior ou igual a 100, o formulrio oculto (hide), disparamos o formulrio principal, e quando este for fechado a aplicao ser encerrada. Para finalizar essa aplicao, basta acrescentar os cdigos nos menus para chamar os formulrios que criamos. Altere a propriedade IsMdiConteiner do FrmPrincipal para true, assim podemos acessar os formulrios internos dentro do form principal. Veja a aparncia at o momento. 127

Vou incluir a funcionalidade para chamar o cadastro de clientes. As demais, s voc seguir este exemplo: private void clientesToolStripMenuItem_Click(object sender, EventArgs e) { FrmClientes f = new FrmClientes(); //indicamos que a janela pai o form atual f.MdiParent = this; //Carregamos o formuladio dentro do form pai. f.Show(); }

128

Você também pode gostar