Olá pessoal, começo aqui mais uma série de artigos criando aplicações simples em Windows Forms usando a linguagem

C# e o banco de dados SQL Server. Desta vez iremos criar um sistema de um consultório médico, com cadastro de pacientes, médicos e consultas. Faço este artigo com base nas videoaulas de Windows Forms de Luciano Pimenta, do Portal Linha de Código. Acompanhem o passo-a-passo: Começe abrindo o SQL Server e crie um novo database com o nome Consultorio. Após isso crie as tabelas de Pacientes, Médicos e Consultas, conforme mostra a imagem abaixo:

Agora é preciso criar os relacionamentos entre as tabelas. Para isso, no Solution Explorer, clique com o botão direito na tabela Consulta recém criada, clique em Design, depois nos botões do menu clique em Relationships, como mostra a imagem:

Na janela que surge, clique no botão Add, abra a aba Tables and Columns Specification e clique no botão ao lado:

Na janela que abre, em Primary key table, faça os relacionamentos, escolhendo a Coluna Medico e abaixo relacione o IDMedico da tabela Medico com o IDMedico da tabela Consulta. Faça isso também com a tabela Pacientes:

Após isso, salve a tabela, irá aparecer uma mensagem avisando que as alterações feitas se aplicarão nas demais tabelas, clique em Sim e aguarde. Agora abra o Visual Studio, crie um novo projeto Windows Forms e dê o nome de Consultas:

Será gerado um formulário, ele será nosso form principal, clique nele, abra a janela Properties (CTRL+W+P) altere as seguintes propriedades: - Text – coloque o nome Consultas - (Name) – altere para frmPrincipal - WindowState – altere para Maximized, para abrir sempre maximizado - MaximizeBox – false - MinimizeBox – false – para que só apareça o botão de fechar no form - KeyPreview – true, para ativar o uso do teclado nos eventos do form Agora abra a janela Toolbox (CTRL+W+X) e arraste da aba Menus & Toolbars um Toolstrip, que nada mais é do que uma barra de controles para seu form. Clique no botão ao lado dele, selecione o controle Button, clique com o botão direito nele e clique em DisplayStyle >ImageAndText. Seu form deverá ficar assim:

altere o nome do seu DataSet se quiser e clique em Finish. se estiver com dúvidas quanto a isso. clique em Next e aguarde. Essa parte do exemplo é bem parecida com a que ensinei na 1ª parte do artigo de Acesso á Dados.Agora vamos adicionar um novo Data Source. criado anteriormente. Na janela que aparece. o servidor local do seu pc. selecione o Database Consultorio. postada dias atrás. para isso. selecione em Server Name. clique em Tables. apenas digite (local)\SQLEXPRESS (lembrando que este exemplo usa a versão Express do SQL Server). em Next. Clique em New Connection. Na próxima tela será perguntado quais objetos você deseja adicionar ao seu DataSet. clique no menu Data > Add New Data Source. altere o nome de sua connectionstring para strConsultorio. selecione Database e clique em Next. . clique em OK.

mais se você abrir a janela Solution Explorer(CTRL+W+S) ou clicar em Data > Show Data Sources (SHIFT+ALT+D) verá que nosso DataSet foi criado com sucesso: No Solution Explorer. repare que nossas tabelas trazem os controles adequados a elas. parece que nada aconteceu. clique no nosso projeto com o botão direito e clique em Add > Windows Form. Dê o nome de frmMedico e clique em OK.Á primeira vista. Altere a proprieade Text para Cadastro de Médicos e na janela Data Sources que vemos na imagem acima. como por .

dê dois cliques no controle ToolStrip que adicionamos a ele ou aperte F7 para ir ao evento toolStripButton1_Click e insira o seguinte código: . etc. se você expandir a tabela Medico. Agora arraste a tabela Medico para nosso form que ele cria automaticamente a estrutura necessária para inserir dados em nosso form. e clicar em IDMedico verá que podemos usar um Textbox. um Label. Faça os ajustes necessários nos campos como mostra a imagem: Agora volte ao formulário principal.exemplo. ele mapeia os dados que vem do banco SQL e nos mosta quais os controles mais adequados à cada coluna: Altere o controle Label para o campo IDMedico como mostra a imagem acima. Isso é feito automaticamente pelo próprio Visual Studio.

Agora compile o projeto e veja o resultado: Experimente inserir. Agora clique no formulário e aperte F7 para ir à página de código e note que. para ativar o uso do teclado nos eventos do form Seu form deverá ficar com propriedades iguais ao do form principal. salvar e excluir registros. pare a compilação e compile de novo e note que os registros são salvos no banco e estão disponíveis para posterior consulta.MaximizeBox – false .KeyPreview – true. o Visual Studio automaticamente adicionou também códigos ao nosso form: . Assim.FormBorderStyle – altere para FixedSingle para que o form não possa ser redimensionado . ou seja.O que fiz no código acima foi instanciar o formulário médico e fazer a chamada a ele por meio do método ShowDialog().Text – na seleção de registros of {0} altere para de {0} . Iremos aplicar algumas configurações que serão padronizadas. a partir do momento em que foi adicionado o DataSet e seus demais controles. encerramos aqui a 1ª parte da série de artigos de Windows Forms com acesso à dados. Abra a janela Properties (CTRL+W+P ou F4) e altere as propriedades: . Nesta parte iremos criar o Cadastro de Pacientes e o Cadastro de Consultas e aplicaremos algumas configurações nestes forms e nos demais.Start Position – coloque CenterScreen para que o form abra no meio da tela .MinimizeBox – false – para que só apareça o botão de fechar no form . Acompanhem: Abra seu projeto no Visual Studio e abra o modo design do Cadastro de Médicos. serão aplicadas à todos os forms para que sigam um determinado padrão.

Neste form. aplique as configurações padronizadas que definimos no começo do artigo. Dê o nome de Cadastro de Pacientes à esse novo form. na janela propriedades do form Medico. abra a janela Data Sources (SHIFT + ALT + D). Cadastro de Pacientes – Vamos criar agora um novo form. quando o usuário apertar a tecla ESC.Vamos fazer uma verificação simples para que. Se não. se foi. clique no botão ao lado de Paciente e troque o formato dele para Details. vá nos eventos e dê dois cliques no evento KeyDown. Agora abra o evento KeyDown deste form e aplique o mesmo código do anterior. Vamos configurar nosso data source. Para isso. automaticamente o form é fechado. nela insira o código abaixo: No código acima fiz a verificação se a tecla digitada foi ESC. Na Solution Explorer. Para isso. Simples. clique com o botão direito no projeto. nada acontece. clique em Add > Windows Form e dê o nome frmPacientes. Irá se abrir a tela de códigos. se o usuário apertar a tecla ESC. feche o formulário. para que. como mostra imagem a seguir: . o form feche automaticamente.

arraste a tabela Paciente para o form recémcriado: Altere algumas propriedades de seu form para que o mesmo fique padronizado como os outros.Expanda a tabela Paciente e troque o formato do IDPaciente para Label. parecido com o da imagem abaixo: . da mesma forma como fizemos no artigo anterior. Após isso.

clique com o botão direito nele e clique em DisplayStyle > Text. No form principal. Agora no form de Cadastro de Médicos. clique nele e clique em Button. abra as propriedades do seu form. como mostra a imagem abaixo: . por meio das opções do ToolStripButton e. adicionar outro botão para fazer a chamada à este form que criamos. mais um botão. Agora clique neste botão. neste novo botão. clique no botão de Cadastro de Médicos. Experimente adicionar alguns registros para testar as funcionalidades que o Visual Studio nos fornece com apenas alguns cliques. vá a propriedade Text e digite Fechar. irá aparecer outro botão ao lado. como a figura abaixo nos mostra: Dê o nome ao Button de Cadastro de Pacientes. como se pode ver.Agora vamos ao form principal. adicione um separador (Separator). e clique em DisplayStyle > ImageAndText. não é nada muito complexo de ser feito. Agora clique com o botão direito no botão recém criado. Dê um duplo clique neste botão para fazer a chamada nele ao form de Pacientes: O que fiz acima foi o mesmo feito no botão do Cadastro de Médicos: instanciei o formulário paciente e usei o método ShowDialog para exibir o formulário no evento Click do botão.

ela servirá para controle interno. arraste a tabela Consulta para o form recém-criado: . IDMedicotroque para um ComboBox para que o usuário possa escolher qual médico será mostrado no momento da consulta e faça o mesmo para a coluna IDPaciente. Após isso. para sabermos se tal consulta está ativa ou não. como fizemos anteriormente. Cadastro de Consultas – Crie um novo form e dê o nome de frmConsulta. porque não precisaremos mostrar esta coluna ao usuário. como mostra a imagem abaixo: Faça isso aos demais formulários. deixe como None. mantendo aquela idéia de criar uma padronização aos forms. Abra a janela Data Sources (SHIFT + ALT + D).Dê dois cliques neste botão e insira o método Close. Agora expanda a tabela Consulta e troque o formato do IDConsulta para Label. clique no evento KeyDown do form e insira novamente o código para que o form se feche quando o usuário teclar ESC. clique no botão ao lado de Consulta e troque o formato dele para Details. E na coluna Ativo. Aplique as configurações padronizadas que definimos no início do artigo.

No textbox Observações.Altere as propriedades do form para que fique igual ao da imagem abaixo: No combo Nome do Médico e Nome do Paciente. altere a propriedade Multiline para True. para que o usuário não possa digitar nos combos. Agora volte ao form principal. altere a propriedade DropDownStyle para DropDownList. Nos combos Início e Término. adicione um novo botão. dê dois cliques nele e faça a chamada ao formulário de Consulta por meio do código seguinte: Agora. altere a propriedade Format para Custom e a propriedadeCustomFormat para HH:mm. para deixá-lo com várias linhas para inserir as observações. No combo Data. veremos que o form de Consulta não nos retorna absolutamente nada nos combos de Médico e Paciente. altere a propriedade Format para Custom e a propriedade CustomFormat para dd/MMM/yyyy. . As demais configurações seguem o padrão dos outros forms. se compilarmos nosso sistema. Assim você coloca um valor personalizado tanto para data quanto para hora.

podemos clicar ao lado do combo. abra a janela Data Sources (SHIFT + ALT + D) e arraste a tabela Médicos para o seu respectivo combo. ou esse: . Para fazer isso. na setinha e percebermos que ele arrasta os dados referentes ao médico para este combo: Agora rode o sistema e tente adicionar uma nova consulta.Isso acontece porque não relacionamos as respectivas tabelas aos combos.Poderá ocorrer dois erros. Faça o mesmo com a tabela Paciente. Após isso.

onde foi criado nossas tabelas. Independente do primeiro erro. Para arrumar é só abrir o SQL Server. devemos realizar a alteração também em nosso DataSet. como mostra a imagem abaixo: Ainda não terminou! É importante salientar que. quando é feita alguma alteração no banco de dados. dê dois cliques no seuConsultorioDataSet. clique na coluna Ativo. Para isso. para arrumar isso. abra o Solution Explorer. clicar com o botão direito na tabela Consultas. como essa que fizemos.A imagem à esquerda mostra o erro. salve. na opção Allow DBNull. troque para True: . obrigatoriamente irá ocorrer o erro abaixo: Dizendo que a coluna Ativo não permite valores nulos. que diz que a data não permite valores nulos. volte ao Visual Studio. clicar emDesign e selecionar o checkbox na coluna Allow Nulls do campo Ativo. selecionando o campo combo e clicando no quadrado vermelho. abra a janela Properties e. é só inserir a data como mostra à imagem a direita.

rode seu projeto e adicione um novo registro: Ok pessoal. com alta performance simulando um sistema comercial para pequenas e médias empresas. Falaremos também sobre os conceitos deProgramação Orientada à Objetos. do Portal Linha de Código. Na próxima parte de nosso artigo. termina aqui mais um artigo da série que estou fazendo baseado nas videoaulas de Luciano Pimenta. Acompanhem: . Nesta parte iremos finalizar nossa padronização no sistema aplicando algumas configurações personalizadas ao formulário principal. iremos finalizar a padronização de nosso sistema alterando o formulário principal e iremos nos aprofundar nas características principais daProgramação Orientada à Objetos.Salve. Assim conseguiremos projetar um sistema melhorado.

no menu Propriedades. se não tiver dado nome a eles. Podemos alterar nosso menu de navegação para que fique. Agora pesquise no Google Imagens as respectivas imagens para cada botão. como mostra a imagem abaixo: Ok. Se a imagem não ficar transparente. Por meio da propriedade Dock podemos fazer isso. nosso formulário está pronto. clique no botão ao lado do atributo Image e clique em Import. A princípio. salve em seu pc. Pacientes e Consultas. mais se preferir pode alterar a propriedadeDock como mostrou a imagem. clique nos botões do menu. por exemplo. Com cadastros e funcionalidades simples. Após inserir as imagens clique no atributo ImageScaling e o deixe como None para a imagem ficar com o tamanho real. .De início. no meu exemplo vou deixá-lo no topo mesmo. à esquerda de nossa janela e não em cima. Para isso. clique em cada botão e. vamos alterar as imagens dos menus do form principal. abra o form. nos deu uma boa visão de como é fácil trabalhar com os controles do Visual Studio. é só alterar a propriedade ImageTransparentColor para a cor da sua imagem. aproveite e já dê o nome de Médicos. como mostra a imagem abaixo: Use de preferência imagens com tamanho máximo de 48×48.

KeyPreview – true.MinimizeBox – false – para que só apareça o botão de fechar no form . Seguindo este conceito. utilizando alguns conceitos da Programação Orientada à Objetos.MaximizeBox – false . Comecemos então nosso formulário base principal que será o “formulário pai”: Clique em Add > Windows Form. no cadastro pacientes.Agora imagine o seguinte cenário: uma aplicação dessa feita para a vida real onde. Teremos também um formulário de pesquisa.FormBorderStyle – altere para FixedDialog para que o form não possa ser redimensionado . que é o conceito de implementar detalhes e parâmetros ao sistema de acordo com as necesssidades do cliente. Vamos trabalhar também em nosso sistema com o conceito de Parametrização. não teremos mais um formulário como o de Pacientes. dê o nome de frmBase e clique em OK. para ativar o uso do teclado nos eventos do form . abra a janela Properties (F4) e altere as seguintes propriedades: . pois quando abrirmos o form de Pacientes. Será feito assim em todos os formulários. concordam? Por isso digo que até o momento montamos um sistema o mais simples possível. A herança é usada com a intenção de reaproveitar o código e assim garantir uma alta produtividade em nosso sistema. por exemplo? Iriamos de um em um? Ficaria complicado. para um potencial cliente. Como ficaria se precisarmos navegar no registro 999.Start Position – coloque CenterScreen para que o form abra no meio da tela . por meio do conceito de Herança. como a Herança. Será gerado nosso formulário. De forma simplista o conceito de Herança significa que uma ou mais classes filhas herdam atributos e métodos da classe pai (conhecida também como classe base). clique nele. não queremos ver todos os Pacientes e sim ver determinado Paciente. A partir de agora iremos mudar nosso foco e simular uma aplicação de verdade. não são 5 nem 10 nem 100 e sim 1000 registros. com os botões avançar e retroceder os registros.

Altere também a propriedade Design dos botões para podermos identificá-los mais facilmente quando formos usá-los na programação. Localizar e Fechar conforme mostra a imagem abaixo: Altere a propriedade DisplayStyle para Image and Text dos botões. ou quando estiver localizando. 1 separador e mais 1 botão. nessa ordem referentes aos botões Novo. se por exemplo o usuário estiver inserindo. Excluir. dê o nome delblMensagem e deixe a propriedade Text em branco para que possamos configurar via código uma mensagem ao usuário quando ele realizar determinada ação. Nela. Navegando e Editando. Clique com o botão direito no seu form e clique em View Code ou simplesmente aperte F7para ir a página de códigos. devemos desabilitar o botão de excluir. a propriedade ImageScaling para None e insira imagens para os botões referentes como fizemos no form anterior. com os itens Inserindo. btnExcluir. nele adicione um StatusStripLabel. Na ordem altere para btnNovo.btnSalvar. Arraste uma ToolStripde nossa Toolbox para o form e insira 4 botões. Salvar.Agora vamos inserir os controles que serão padrões nos demais forms. devemos desabilitar o botão de salvar. btnLocalizar e btnFechar. e criaremos uma variável privada deste enumerador para sabermos qual é o status do sistema. A imagem abaixo mostra nosso código: . Adicione o controle StatusStrip a seu form. vamos criar um enumerador. Desta forma estaremos otimizando nosso código e evitando erros do usuário.

Na próxima parte de nosso artigo. Devemos ter a preocupação de.cs e crie um novo método do tipo private com o nome LimpaControles que não irá nos retornar nada.Vamos voltar ao nosso form. Primeiro dê dois cliques em cima do botão de fechar e chame o método Close(). depois que o usuário gravar um registro por exemplo. Usando esse conceito de Herança em nosso sistema. clique nos Eventos. selecione o evento KeyDown. os controles usados. textbox e outros. como mostra a imagem abaixo: . iremos continuar a codificação de nosso formulário base implementando os métodos que iremos usar na herança do mesmo. abra a janela de propriedades do mesmo. o que melhora nosso desempenho e temos facilidade se precisarmos dar manutenção. no modo visual e implementar o código para o botão Fechar. como parte de nosso exemplo. Para isso devemos criar um método que limpa os campos após a gravação de um registro qualquer. Depois. como combobox. sejam limpados automaticamente. volte ao form. dê dois cliques nele e insira o código abaixo para que o form se feche ao apertar ESC. Abra o frmBase. só utilizaremos este código acima apenas uma vez e os demais herdarão as funcionalidades do formulário base. Nesta parte vamos continuar com a codificação de nosso formulário base implementando os métodos que iremos usar na herança visual dos demais.

Continuando com nosso conceito de trabalhar com Herança. como Label e Button. iremos criar os métodos Salvar. poupando assim o retrabalho de ter que digitar o mesmo método diversas vezes. E assim faço com os demais. A primeira verificação. foi pra saber se existe um textbox em meu form e. não tem necessidade de serem limpos. como mostrou nosso último if da imagem acima. e iremos fazer a chamada desses métodos nos demais formulários.Forms) com o objetivo de ser feita uma “varredura” em meu formulário. Lembrando que em alguns controles. devemos fazer outro foreach. . por exemplo. se existir. Conforme você for precisando adicionar ou substituir um controle por outro é só adicionar o tipo dele em nosso foreach. Iremos começar criando o método Salvar. Se precisarmos fazer o mesmo a um controle do tipo CheckedListBox. Excluir e Localizar apenas neste formulário base. ele será limpado. percorrendo todos os controles existentes dentro do meu form.Acima fiz um laço do tipo foreach na classe nativa Control (pertencente ao namespace Windows.

como você pode perceber na imagem: . devemos configurar nosso enum para Navegando. o usuário terá que localizar o mesmo por meio do respectivo botão. ou seja. ou que o registro foi gravado ou que deu erro. como mostra a imagem a seguir: Devemos também dentro desses métodos fazer a chamada a outro que iremos criar para que os controles sejam habilitados ou desabilitados. Em minhas verificações coloquei o método LimpaControles. Faço o mesmo com os métodos Excluir e Localizar. em nosso botão Salvar. se desejar um registro específico. Depois de salvo um registro. se foi ele limpa os controles e exibe a mensagem ao usuário. Agora vamos criar os métodos para os botões Novo e Localizar que são iguais com os dos botões Salvar e Excluir.Acima criei o método do tipo booleano passando como retorno o valor false. Se o usuário salvou o registro ou excluiu. ele só me retornará true quando o registro for salvo no banco. Agora vá ao modo design do formulário base e dê dois cliques nos botões Salvar e Excluir. isso dependendo do que acontecer em nosso sistema. Dentro deles insira o seguinte código: O que fiz foi chamar os métodos referentes aos respectivos botões e dependendo da resposta do método entro no meu if ou no meu else. por exemplo. pois ele irá entrar verificar se o registro foi gravado. eles são automaticamente limpados. Vamos agora implementar o enum que criamos no artigo anterior. Uma característica que será implementada é a de que quando forem abertos os formulários sempre virão registros vazios. por exemplo.

como a imagem abaixo nos mostra: O que fiz foi um foreach. . Crie um novo método do tipo public virtual como os anteriores só que ele será do tipo void. a função dele será a de retornar os dados parametrizados do banco e carregar meus controles. ou seja. que será o CarregaValores. que percorre todos os meus controles. vou dizer que.Lembrando que após criarmos nosso método que habilita/desabilita os controles do form devemos implementá-lo aos botões Novo e Localizar. Só que aqui ele faz um if pra verificar se o controle é um Toolstrip. Agora dentro deste mesmo método. não terá retorno algum. faço as verificações em meus botões para habilitá-los ou desabilitá-los. parecido com os do métodoLimpaControles. ele habilita nossa variável bValue que foi passada como parâmetro em nosso método. se for ele continua. se não for. Faça a chamada a este método no botão Localizar. por exemplo. Vamos criar um método que será implementado nos formulários que herdarão de meu formulário base. Crie também o método para habilitar / desabilitar os controles no form. o campotxtNome irá vir carregado com a coluna de nomes do meu banco e assim por diante.

o Novo. insira os seguintes códigos: . passo meu método com o valortrue. No fim atribui que o botão Fechar sempre estará habilitado. Abaixo um exemplo do botão Localizar: Finalizando. Assim. vá ao modo Design de nosso form e dê dois cliques no form para ir ao eventoLoad do mesmo. passo o valor false ao meu método porque já exclui. dependendo da ação do usuário o botão específico estará habilitado ou desabilitado (com exceção do Fechar que terá valor fixo). Nele. no primeiro botão. porque quero habilitar os controles para que o usuário insira um novo registro.Acima fiz o seguinte: passei o status de cada botão. no botão novo. já no botão excluir. dependendo de cada situação. atribui à ele que o status será o Navegando e assim fiz com os demais. Agora é só aplicar os métodos aos respectivos botões passando os valores. não preciso mais que os controles sejam habilitados e assim sucessivamente. true ou false. Por exemplo. por exemplo.

Com isso ganharemos e muito em performance em nosso sistema.ShowInTaskbar – false. dê o nome de lblMensagem e deixe a propriedade Text em branco para que possamos mostrar ao usuário qual foi a quantidade de registros retornados após ele ter feito uma pesquisa. pois este será o nosso formulário base de Pesquisa.MinimizeBox – false – para que só apareça o botão de fechar no form . serão montadas as telas herdadas que forem necessárias no decorrer de nossos artigos. ou pela descrição. nos retornará apenas o que pesquisarmos e não toda a nossa base de dados. para ativar o uso do teclado nos eventos do form .Fazendo isso. abra a janela Properties (F4) e altere as seguintes propriedades: . clique nele. clique aqui. que será parametrizada. o que em uma aplicação real nos traria muita dor de cabeça se não fosse usado o recurso de parametrização que estamos implementando. Dê a ele o nome defrmPesquisaBase. com os controles limpos e com o método HabilitaDesabilitaControles como false. para não mostrarmos o form no taskbar Adicione o controle StatusStrip a seu form (da mesma forma como fizemos no formulário base) . estou disponibilizando para download o que fizemos até esta parte do artigo em nosso sistema. como mostra a imagem a seguir: . permitindo ao usuário praticidade e performance na hora de navegar nos formulários. nele adicione um StatusStripLabel. Assim inicializamos os métodos em nosso form de uma forma prática e sem erros.FormBorderStyle – altere para FixedSingle (faça o mesmo nas propriedades do formulário Base) . a partir dela. Abra sua solution e clique em Add > New Windows Form. Será gerado nosso formulário. Nesta parte vamos montar nossa tela base de pesquisa. Montaremos a tela padrão e. toda vez que o form for carregado ele iniciará com o status Navegando. Para quem se interessar.MaximizeBox – false .KeyPreview – true. ou seja.Start Position – coloque CenterScreen para que o form abra no meio da tela . Para baixar. Nossa tela de pesquisa será também genérica. Nosso formulário terá duas formas de pesquisar: ou pelo código do usuário. Vamos adicionar um GroupBox ao nosso form e dar o nome de Tipo de Pesquisa.

Deixe seu form como o da imagem abaixo: . Adicione também. Altere o ID de cada um deles para rbtCodigo e rbtDescricao. para que o form sempre inicialize com ele checado. um TextBox e um Button. um Label.Agora dentro dele adicione dois RadioButton com as propriedades Text Código e Descrição. para que o usuário possa digitar no campo a descrição referente ao usuário. que é o mais comum de se pesquisar. respectivamente e deixe a propriedade Checked do RadioButton Descrição setada para True. txtPesquisar e btnPesquisar. Altere o ID deles paralblDescricao. ao lado do GroupBox.

Dê dois cliques no Fechar e chame o método Close. Sete o valor do DialogResult para Cancel. como mostra a imagem abaixo: . quando o usuário pressionar ESC ou ENTER. respectivamente. A esses botões sete a propriedade DialogResult de cada um como OK e Cancel. como mostra a imagem a seguir: Agora abra o evento KeyDown do seu form e coloque aquela verificação para que.Agora adicione dois botões no canto inferior direito do seu form. um que é o botão OK e outro o botão Fechar. o form se feche.

seu ListView deve estar parecido com o da imagem a seguir: . altere a propriedade View para Details e abra a opção Columns para adicionar duas colunas ao nosso ListView. Altere a propriedade FullRowSelect para True para que. Finalizando o design de nosso ListView. Altere para True também a propriedade GridLines. porque queremos que seja selecionado apenas uma linha de nosso grid e não várias. por exemplo. faça o mesmo na próxima.Agora vamos implementar um ListView ao nosso formulário. Redimensione sua coluna Descrição se desejar. quando o usuário clique no campo Descrição. Clique em Add e altere a propriedade Text para Código. para que nosso ListView fique com as linhas do Grid. seja selecionado toda a linha e não só o campo clicado. arraste um controle ListView ao form e dê a propriedade ID o nome lstPesquisa. Ainda nas propriedades. Então abra a Toolbox. altere a propriedadeMultiSelect pra False. dê o nome Descrição e clique em OK. Se você alterou as propriedades como descrito.

No evento DoubleClick do ListView devemos usar o código para preencher nossa variável e adicionarmos o método Close e o DialogResult com o valor OK.Vamos implementar as funcionalidades de nosso ListView entrando na página de códigos do formulário. A imagem a seguir mostra nosso método: . Vamos criar uma classe pública do tipo string e a inicializaremos com um valor vazio. como fizemos no evento KeyDown do formulário anteriormente. como quando o usuário escolher um código em nossa Grid e clicar em OK ou mesmo quando ele der dois cliques no Grid. para que ela seja preenchida em outras partes de nosso código. Vejamos o código: Agora volte ao modo Design do form e dê dois cliques no botão OK. Insira o seguinte código: O que fizemos no botão OK tivemos que fazer também no evento SelectedIndexChanged do ListView só que usamos um Try/Catch para tratar um erro que não é da aplicação e sim do próprio controle.

este será o botão padrão de nosso form. na propriedadeAcceptButton. Ou seja. seja no botão OK. seja quando o foco está na pesquisa do usuário. Seja no clique duplo no resultado da pesquisa. Agora vamos ao modo Design de nosso formulário. capturamos praticamente todas as opções que o usuário tem no momento em que vai pesquisar. Para quem se interessar. Para isso. escolhemos nosso btnPesquisar. como a pesquisa de clientes. como a imagem abaixo nos mostra: . clique aqui. Para baixar. Iremos também criar um novo DataSet e deixarmos de lado o criado nos artigos anteriores. por exemplo. clicamos em nosso form e. Ou seja. no arquivo de códigos de nosso formulário de Pesquisa crie um método do tipo público virtual e que não irá ter retorno(void).Dessa forma. Vamos começar criando nosso método de Pesquisa. estou disponibilizando para download o que fizemos até esta parte do artigo em nosso sistema. em cada formulário de pesquisa terá uma implementação diferente. Não iremos implementar nada neste método. Nesta parte vamos criar os métodos para que o ListView nos retorne o que o usuário digitar no campo de Pesquisa. Quero que meu botão de Pesquisa seja chamado quando o usuário digitar algo na caixa de pesquisa e der um ENTER. já que serão implementados apenas nos formulários herdados.

como mostrado na imagem abaixo: Além das implementações citadas acima. uma que habilita o botão OK de nosso form se a propriedade Count for maior que 0. assim o usuário pode navegar entre os registros usando as setas do teclado. faz com que nosso ListView ganhe o foco. adicionamos mais duas verificações. dando duplo clique para ver determinado registro por exemplo e assim estaremos evitando ao máximo possível erros do usuário. se o botão OK estiver habilitado. que será implementado em nossos formulários que herdarão do formulário base. e a outra que. como você pode ver na imagem. ou seja. Agora vamos criar um método que irá carregar o retorno de nossa pesquisa da base de dados em nosso ListView. que criamos anteriormente. Crie o método do tipo público void e que terá como parâmetro um DataTable. No evento Click desse botão chame o método Pesquisar. Veja o método a seguir: . Esta última é necessária porque. se nosso ListView nos retornar ao menos 1 registro em nossa pesquisa. faça a configuração de nossaStatusStrip.Dê dois cliques no botão Pesquisar para voltarmos à página de códigos de nosso form. para retornar ao usuário quantos registros foram encontrados em cada pesquisa que for feita e adicione outras implementações.

Lembrando que para cada formulário de pesquisa. clique nos Radio Buttons Código e Descrição. vá ao evento Click. Escolha no menuCategories a opção Data. melhorando assim a eficiência de seu sistema e a usabilidade do mesmo.Com este método. clique em seu projeto com o botão direito e clique em Add > New Item. dê dois cliques e insira o seguinte código: Apenas para que o usuário tenha uma maneira rápida e fácil de pesquisar. iremos criar um novo DataSet e deixaremos de lado o que foi criado em artigos anteriores. dê o nome dsConsulta e clique em OK. no menu Templates escolha DataSet. teremos dois tipos de pesquisa: por código ou por descrição. . Dito isto. finalizamos nossos métodos do formulário de Pesquisa. pois nele usamos as facilidades do Visual Studio para criá-lo. tendo como base o conceito de Programação Orientada à Objetos. agora volte ao modo Design. Com isso em mente. já nesse estamos usando um outro tipo de abordagem. abra a Solution Explorer (CTRL+W+S).

Seu DataSet deverá ficar como o da imagem abaixo: Vamos customizar a tabela de médico para criar mais duas pesquisas. escolha a 1ª opção e clique em Next. Neste caso. a diferença é que desta vez não iremos usar o menu DataSources para arrastar as tabelas. assim ele criará para nós cada DataTable eDataAdapter referentes às respectivas tabelas para que possamos customizá-las. Vamos arrastar diretamente do banco por meio do Server Explorer. uma por código e outra por nome/descrição. expanda seu Database Consultorio. Então abra o Server Explorer (CTRL+W+L). por meio da criação de uma Stored Procedure ou por meio do uso de uma Stored Procedure existente. Irá abrir um wizard que nos perguntará como nossa query irá acessar o banco. clique com o botão direito no MedicoTableAdapter da tabelaMedico e clique em Add Query.Será um DataSet igual ao nosso criado nas primeiras aulas. existem três opções: por meio de instruções SQL. . seu menu Tables arraste as tabelas para o DataSet recém criado. Para isso.

que insere os dados. Escolha a 1ª opção e siga em frente. se iremos usar a instrução DELETE.Na próxima tela. devemos informar qual tipo de consulta iremos realizar dentre cinco opções: se será por meio de um SELECT que retornará vários registros. que atualiza os dados. que apaga os dados ou se será por meio da instruçãoINSERT. . se será por um SELECT quer retornará apenas 1 registro. se iremos usar a instrução UPDATE.

Como a nossa consulta será parametrizada. Note o botão Query Builder. volte a instrução SQL e altere a instrução passando o parâmetro como mostra a imagem a seguir: .Aqui ele já me traz a instrução SQL pronta. com o uso de Join. com ele podemos fazer instruções mais complexas. Group By. etc.

Podemos usar os dois. Fill a DataTable. como o próprio nome diz. mais neste exemplo (como estou seguindo à risca as videoaulas de Luciano Pimenta) iremos escolher somente a 1ª opção e dar o nome de PesquisaID.Return a DataTable. devemos escolher quais métodos devemos usar em nosso TableAdapter. preenche o DataTable e a 2ª opção. A 1ª opção. .Nesta tela. apenas retorna o DataTable preenchido.

já que nesse pesquisaremos pelo nome. Perceba na imagem abaixo que foi criada nossa query parametrizada.A próxima tela mostra que o Wizard gerou a instrução SQL e o método de preenchimento. ou seja. como a imagem abaixo nos mostra: . ela pede como parâmetro o ID do Médico: Agora crie um Wizard igual esse que criamos. Como podemos pesquisar por apenas uma parte do nome. Clique em Finish. use a cláusula Like. apenas mude nossa instrução SQL.

fiz a chamada ao método PesquisaID. que seria o 1º registro e nome da coluna. nesse caso o 1. por meio dele. que é a instância de meu DataTable e chamei o método Rows. agora temos as duas consultas criadas. instanciei o MedicoTableAdapter. instanciei o MedicoDataTable. referente à pesquisa criada passando como parâmetro meu MedicoDataTable e um valor inteiro qualquer. selecione o método Fill e dê o nome PesquisaNome. para isso usei o dt.cs e adicione o seguinte código: Fiz a chamada a meu DataSet por meio do using e.Na próxima tela. que foi na onde criei minhas duas pesquisas e. dê um Build Solution (F6) na sua aplicação. passando como parâmetro o índice 0. Primeiramente. Por meio do meu método Rows. que . Pronto. no método Load do meu formulário. Agora abra o Form1. tenho acesso a coluna da minha tabela Medico. Agora vamos fazer um teste.

estou disponibilizando para download o que fizemos até esta parte do artigo em nosso sistema. vamos criar um TableAdapter. já que isso nos serviu apenas de exemplo para implementarmos nas consultas e pesquisas dos outros formulários. Nesta parte iremos continuar a customização de nossas tabelas e sobrescrever os métodos para o formulário de Cadastro de Pacientes. Para quem se interessar. Finalizando. . vamos escolher a outra opção. apague estes códigos do método Load desse form. Return a DataTable. Para baixar.neste caso éID_MEDICO. como mostra a imagem abaixo e clique em Next: Na próxima tela. já a outra consulta que criamos usaremos em nosso formulário de Pesquisa. Acompanhe: Como feito no artigo anterior. Altere a instrução SQL da consulta por ID. depois em Finish. como no form de Medicos. clique aqui. só que desta vez para a tabela de Pacientes. Faça isso com os dois tipos de pesquisa. clique com o botão direito no TableAdapter da tabela Paciente e clique em Add Query. Escolha e clique em Next. ao invés de escolhermos a opção Fill a DataTable. com o nome PesquisaID para vermos as diferenças. Esse exemplo iremos usar em nosso Cadastro. Iremos fazer basicamente isso em nossas outras consultas. Então. por ID e por Paciente.

só altere a instrução SQL. como a da imagem a seguir: .Agora crie outra query e faça o mesmo que a query anterior.

Pronto. Salve e dê um Build Solution (F6) no seu projeto para ter certeza de que o mesmo não está com erros. nosso DataSet está concluído.Escolha o método Return a DataTable e dê o nome de PesquisaNome. que . Não iremos adicionar um Windows Form normal e sim um Inherited Form. Agora clique com o botão direito no seu projeto e clique em Add > New Item. Agora vamos criar os formulários que herdarão dos formulários base que foram criados.

No modo design dê o nome lblCodigo à ele. herdará de outro formulário. No exemplo dei o nome frmPacienteHerdado. o que precisamos fazer no momento é adicionar alguns controles. escolha o frmBase.traduzindo seria um Formulário Herdado que. pois ele será preenchido com os dados que vierem do banco. Dê um nome sugestivo a ele e que não seja o mesmo nome dos formulário já criados. Adicione 4 labels e 2 textboxs. que é o que tem todas as características que precisamos. Como você pode notar abaixo. Deixe seu formulário como o da imagem abaixo: . temos os mesmos controles do frmBase. neste caso do Paciente. txtNome e txtTelefone aos textboxs. Irá aparecer outra janela perguntando de qual form iremos herdar. deixe o label que ficará em cima do textbox sem nome. como o próprio nome diz. e clique em OK.

instancio o PacienteTableAdapter e agora preciso chamar meu enumerador sStatus. Excluir. Agora sim. foram declarados comovirtual. no formulário base. como você pode perceber na imagem a seguir: Chame o método Salvar e exclua o return base.Salvar(). Após isso. valor padrão. Aqui iremos chamar nosso DataSet criado anteriormente. Para isso. Como meu método espera um valor booleano. Localizar e Carregar Valores. antes disso declare-o por meio do using. o VS já nos traz todos os métodos que podemos utilizar do outro form. aperte F7 nofrmBase para ir a página de códigos. complete o método abaixo. Quando digitamos public override e damos um espaço. se lembra dele? Mais aqui tem um problema: como ele foi declarado como private. como o Salvar.Agora precisamos sobrescrever os métodos que. pois não iremos usá-lo. altere o modificador dele para public. eu preciso declarar uma variável do tipo bool e deixá-la como false. veja a imagem com os comentários do que foi feito: . incluindo os que criamos. Para isso. O Visual Studio nos dá uma grande ajuda quando queremos sobrescrever métodos já criados. já que ele é privado a sua classe. não consigo chamá-lo aqui.

Esta verificação é para quando estiver inserindo. GetData(). de meu PacienteTableAdapter. clicarmos com o botão direito em Fill. Porque ele está pegando todos os campos de minha tabela e está tentando comparar com os campos do meu método. o método Update vai dar erro porque ele espera ao menos 5 parâmetros a serem preenchidos. Mais. Para alterarmos isso. e quando o registro já foi inserido e quero apenas atualizá-lo? Para isso. faço como na imagem a seguir (ainda dentro do meu método Salvar): Como você pode perceber. e clicarmos em Configure. como mostra a imagem: . temos que ir ao DataSet.

. Next. Next e Finish. Volte ao método Update e note que agora não irá mais dar erro. como você pode ver abaixo: De OK.Agora clique em Advanced Options e desmarque as opções Use optimistic concurrency eRefresh the data table. Veja como deve ficar método completo abaixo.

referente ao código do paciente. substituindo pelo lblCodigo. Agora. Agora chame o método CarregaValores e dentro dele coloque o seguinte código: . Assim. todos os meus cadastros herdarão essa variável. que representa o código respectivo de cada cliente de meu consultório. Agora vamos sobrescrever o método Excluir.Dê um Build Solution (F6) apenas para ter certeza que sua solução está sem erros e salve o projeto. vá a página de código e declare o código: Desta forma. vamos criá-la no nosso formulário base. antes de chamar o método que carrega os itens vamos imaginar o seguinte: já que em meus métodos eu preciso passar meu lblCodigo. já que não precisamos usá-lo mais. Abra o frmBase. posso usá-la nos métodos Localizar. Faça como o anterior: Apenas chame o método Localizar.Excluir e Salvar. Por enquanto vamos deixar como está. não seria melhor se eu declarasse uma variável que fosse a responsável por este código? Pensando assim. já que não vamos implementá-lo agora.

Aqui usamos aquela consulta que filtra pelo ID do Paciente. minha variável nCodGenerico receberá o valor de sCdCodigo. que criamos anteriormente em nosso DataSet. passamos a variável bLocalizar o valor daquela variável sCdCodigo (que é a responsável pelo código da pesquisa no formulário base). se o usuário escolheu algum registro no formulário e clicou em OK e. Após isso eu verifico. verifiquei se o DialogResult desse form foi igual a OK como configurado no formulário base. Para isso. ou seja. se o DataTable retornou algum registro. diferente de vazia. lembrando que o Localizar que irá chamar meu método CarregaValores. clique em Add e escolha o frmPesquisaBase. declarei o DataTable e o TableAdapter e fiz com que o DataTable retornasse meu TableAdapter com o método PesquisaID passando como parâmetro minha variável nCodGenerico. Se isso for verdade. instanciei o formulário herdado de Paciente. que herdará do de Pesquisa. Volte ao formulário que estávamos. Digite o seguinte código: O que fiz foi. Vá na Solution. dê o nome de PesquisaPaciente. clique emAdd > New Item. Lembrando que esse CarregaValores será implementado em cada formulário específico. em Categories escolha Windows Forms. ou seja. escolha o template Inherited Form. Acima fiz também . já que nosso form criado herdará dele. se a variável bLocalizar obtiver algum registro. porque agora vamos implementar o método Localizar. que será preenchida pelo método Localizar. Após isso. se sim. Vamos criar agora um novo formulário. preencho os controles de tela. fazemos outra verificação.

dê dois cliques no botão Paciente e altere o código para chamar nosso formulário. podemos utilizar esta variável nCodGenerico em outros locais para substituir meu código. nosso cadastro esteja completo usando os . Para baixar. Exemplo: o usuário está navegando entre os registros. que na verdade é o código escolhido. do tipo int. No método CarregaValores já estamos usando ela. assim. Ele é diferente de vazio? é. Para quem se interessar. pois a variável sCdCodigo é do tipo string e a nCodGenerico. Quando isso acontece. do formulário de Pesquisa. faço estas verificações. Neste momento meu DialogResult é “setado” para OK. Agora será chamado nosso formulário herdado.um int. decide escolher um e clica em OK. vá ao Form1. Faça como a imagem abaixo nos mostra: Salve seu projeto e compile para testar se tudo saiu OK. clique aqui. então foi preenchido. Simples né?! A partir de agora. Vamos fazer o mesmo no método Excluir e no método Salvar: Nosso formulário de Cadastro está implementado. referente aoCadastro de Pacientes para que. anCodGenerico irá receber o sCdCodigo. Nesta parte iremos implementar o método Pesquisar.Parse para converter. Finalizando nosso artigo. estou disponibilizando para download o que fizemos até esta parte do artigo em nosso sistema. o que significa que minha outra variável. o bLocalizar recebe o valor de sCdCodigo.

. precisamos então acessar o formulário base e alterá-lo para público (public). como mostra a imagem: Faça o mesmo com os RadioButtons Código e Descrição e aperte F6 para dar um Build Solution. o modificador de acesso dos controles é do tipo privado (private). como mostra a seguir: Após isso. Toda vez que você precisar acessar um controle herdado desta forma. dentro do método criado. Iremos começar também uma simulação do padrão MVC(Model View Controller) em nosso sistema. é preciso alterar o modificador para public no formulário base.conceitos de Herança Visual de formulários. vamos fazer o seguinte: de acordo com o tipo de pesquisa que o usuário escolher (por ID ou Descrição). que se chama txtPesquisa. iremos utilizar um dos métodos criados anteriormente em nosso DataSet. Confira: No formulário de Pesquisa. tente acessar o campo de pesquisa. por padrão. Abra o formulário frmPesquisaPaciente e sobrescreva o método Pesquisar. herdado do formulário base. Isso acontece porque. Você verá na imagem abaixo que não será possível o acesso ao mesmo.

. Clique em Pacientes e deverá aparecer a tela de Cadastro de Paciente. preciso declará-lo em meu código. Altere o nome de seu formulário de pesquisa para Pesquisar Paciente e volte ao código. passo ao DataTable o método PesquisaID. da cláusula Like (que irei abordar mais a frente no curso de SQL do meu blog). pois com esse parâmetro de porcentagem. ele irá me retornar o nome Carlos no ListView. Agora salve e compile sua aplicação. por exemplo e digitar no campo rlo. Se eu tiver no banco um nome Carlos. Senão. Clique em Novo. que significa que ele irá procurar uma parte do nome.Agora volte ao formulário de pesquisa e note que você terá acesso ao textbox de pesquisa e aos radiobuttons. digite um nome e um telefone qualquer e clique em Salvar. ou seja. para ser pesquisado o ID que o usuário digitar no campo de pesquisa. Como meu DataSet não aceita/entende o parâmetro %. e uso a porcentagem (%) entre o campo de pesquisa. criado no DataSet anteriormente. se o usuário selecionar o RadioButton Descrição passo ao DataTable o método PesquisaNome. faça o seguinte código: O que fiz acima foi uma verificação simples. Se o usuário selecionar o RadioButton Código. ele irá procurar por partes referentes ao nome pesquisado. Dentro do método sobrescrito Pesquisar.

Agora clique no botão Localizar para ir ao formulário de Pesquisa: .

ele já me retornou o nome completo e o ID. o correto seriam os Status Editando e Inserindo. Você verá o resultado da pesquisa: .Acima digitei uma parte do nome. está habilitado o Status Navegando e Inserindo. os botões de Salvar e de Localizar estão desabilitados. Arrume os botões como mostra a imagem a seguir: Salve e compile seu projeto. Se você der dois cliques em cima do nome. falha minha. adicione também oEditando e o Inserindo. vá ao método HabilitaDesabilitaControles e perceba que no botão Localizar só esta habilitado o Status Navegando. Digite um nome qualquer na caixa de busca ou a deixe em branco e tecle ENTER. ele trará a tela de Cadastro com o Nome e o ID preenchido: Como você perceber na imagem acima. precisamos alterar algumas configurações para que os botões sejam habilitados. E abaixo me mostrou quantos registros foram retornados com essa parte do nome. Para isso. Clique em Pacientes e no botão Localizar. vá ao formulário Base. No botão Salvar.

Se quisermos com que. não consegui fazer funcionar. entre no botão Excluir. no evento KeyDown. abra-o e clique em Excluir. Agora escolha um registro qualquer. O interessante seria perguntarmos ao usuário se ele realmente deseja excluir o registro. mantendo assim uma certa padronização em formulários. Se alguém descobrir o porque. a exclusão é feita em poucos segundos. dê dois cliques e adicione o seguinte código: PS: tentei fazer este método com a tecla ENTER. vá a janela de Propriedades e. clique em cima do ListView. quando o usuário teclarESPAÇO sobre um dos resultados.Clique em um dos resultados da pesquisa. Como você pode perceber. por favor poste nos comentários. o formulário de pesquisa se feche e abra o respectivo registro. podemos implementar isso fazendo o seguinte: Abra o formulário de Pesquisa Base. e altere o código para que fique desta forma: . Para isso. mais por uma razão desconhecida. vá ao formulário Base.

nada acontecerá. clique em Add > Class e dê o nome AcessoDados a sua classe. que já foi implementado anteriormente e o usuário verá um MessageBox avisando que o registro foi excluído. que serão as classes que farão a abstração dos dados da Model e irá fazer a “ponte” com a View.org/wiki/MVC http://www.microsoft.linhadecodigo. que irá implementar alguns métodos e criaremos as classes que herdarão estes métodos. com essas classes poderemos abstrair os dados do nosso DataSet e onde faremos a implementação dos métodos que os formulários irão chamar. .com.htm http://msdn. Precisamos criar agora o Controller. Salve o projeto. onde nosso DataSet será o Model e os formulários são o nosso View.br/Artigo.com/pt-br/magazine/cc337884. ele entrará no método Excluir. Na Solution Explorer.aspx http://www. acesse os links abaixo: http://pt.net/vbn_mvc.macoratti. clique para excluir um registro e veja as modificações. Simples. Se ele disser sim. compile. Para mais informações sobre o padrão MVC. No decorrer dos artigos iremos verificar o que está faltando ou até os erros que possam vir a ocorrer para que assim possamos alterá-los/modificá-los e nosso sistema fique com o menor número de inconsistências possíveis. Se ele clicar em não.aspx?id=1602 http://imasters. Vamos começar a partir de agora uma simulação do padrão MVC (Model View Controller).uol.wikipedia.br/artigo/12139/asp/asp_net_mvc_compreendendo_models_views_ e_controllers/ Começaremos criando a classe de acesso a dados.com. ou seja.Acima fiz apenas a pergunta ao usuário se deseja excluir o registro com o uso de MessageBox.

o método Salvar recebe um parâmetro booleano. seguindo nossa lógica do sistema. onde a partir dela serão criados outras classes que herdarão os métodos provenientes dela. se o registro está sendo inserido ou alterado. Como fiz nos outros métodos do tipo bool. para que ela possa ser acessada pelas classes herdadas e crie o método virtual de Salvar. que receberá como parâmetro um valor do tipo int. Após isso. Agora vamos criar um método do tipo DataTable para pesquisar por ID.Data. Aqui iremos ter os métodos para Salvar.Lembrando o conceito de Herança. para que possamos usar o tipo DataTable. Pesquisa por ID e Pesquisa por Nome. Crie também um método virtual booleano com o nome Delete. é preciso declarar o namespace System. que será sobrescrito depois. Como você pode perceber. dependendo do status. que irá indicar. faça o seguinte método: . Este método não terá nenhum parâmetro. inicializarei este método com o valor false como retorno. No nome da sua classe acrescente um public antes. para Excluir. já que função é apenas de excluir um registro. Antes disso. esta classe será nossa classe Base.

Para baixar. parecido com o método anterior. sem parâmetro). como mostra a imagem a seguir: . estou disponibilizando para download o que fizemos até esta parte do artigo em nosso sistema. clique aqui. Desta forma tenho várias formas de pesquisar em meu sistema. que receberá o nome pesquisado. para pesquisar pelo ID. precisamos usar o Refactor do Visual Studio (ou você pode fazer na mão). Confiram: Crie a classe AcessoDadosPaciente.Faça também um método do tipo DataRow. Assim podemos fazer pesquisas que irão retornar somente uma linha e também pesquisas que irão retornar diversas linhas. Excluir. que irá me retornar somente uma linha. clico em Refactor > Encapsulate Field e dou um nome diferente a ela (geralmente seria o nome quase igual da propriedade privada apenas sem o underline). A diferença deste é que irá me retornar um DataRow e não um DataTable. Declare a propriedade privada _nCodPaciente: Para que ela se torne um campo. posso declarar dois métodos com o mesmo nome. Agora vou mapear os campos da minha tabela como propriedades dessa minha classe herdada. Para isso clico com o botão direito em cima dessa propriedade privada. que herdará da nossa classe de acesso a dados. só que com o retorno e parâmetro diferente (ou nesse caso. Nesta parte iremos criar as classe e os métodos que herdarão da minha classe de acesso a dados. Pesquisar por ID e Pesquisar por Nome. Desta forma. que terá um parâmetro do tipo string. Assim teremos métodos para Salvar. faça um método do tipo DataTable para pesquisar por nome. Finalizando. Para quem se interessar. passando como parâmetro um valor do tipo int.

sNomePaciente e sNumTelefone. O resultado final será esse: Agora vamos implementar os métodos criados anteriormente na classe de Acesso a Dados.O que me resultará no campo abaixo: Faça o mesmo com mais duas propriedades. Logo abaixo chame o método de Salvar (lembrando que usamos o override para sobrescrever os métodos virtuais de acesso a dados): .

Update. comente o código do botão de Salvar do formulário e faça o seguinte código: . Após isso. faço a comparação descrita na imagem acima: se estiver gravando no banco. então chamo o ta. ou seja. se for maior que 0. o número do telefone e o código do paciente. só que passo 3 parâmetros: o nome do paciente. Vamos experimentar usar o método de nossa classe de Acesso a Dados. Se não estiver gravando no banco. Fazendo desta forma. Para isso. faço a mesma coisa. está atualizando. Assim declaro minha variável bSalvar. Como teste. passando os parâmetros declarados em nossa classe. declarei oConsultas. crio o método Salvar.Antes de fazer o método sobrescrito de Salvar. Lembrando: preciso preencher essas propriedades antes de chamar esse método de Inserção e/ou Atualização. referentes ao nome do paciente e ao numero do telefone. chamo o ta.dsConsultaTableAdapters. Uso no final o maior que 0 apenas para dizer que minha variável bSalvar será gravada/atualizada somente se houver algum registro. meus formulários não precisam acessar diretamente o TableAdapterpara obter os dados. muito parecido com o que foi feito em outras páginas do projeto. só que a diferença será que agora a nossa classe de Acesso a Dados que irá abstrair esse método. instancio o TableAdapter. já que minha classe de Acesso a Dados fará isso. abra o formulário Paciente Herdado e vá ao método Salvar.Insert.

quaisquer validações que precisarmos fazer. fiz o mesmo método. logo abaixo do método Salvar. além é claro do TableAdapter) e insira o seguinte código: .Comentei todo o código que usávamos para Salvar e. não precisaremos mais chamar o TableAdapter em nosso form como chamamos atualmente: Vamos agora sobrescrever os outros métodos. uso o conceito de MVC. já que dessa forma meu formulário não precisa usar os métodos de acesso a dados diretamente. quando formos implementar essa forma de trabalhar com MVC nos outros métodos. validando o que precisa. é só fazer nas classes de dados. Assim não precisaremos se preocupar em ir. preenchendo as propriedades e passando os parâmetros. chame o método Delete e insira o seguinte código (muito parecido com o código do método Salvar): Chame agora o método PesquisaID (o que tem parâmetro). Mais pra frente. Outro ponto importante a se destacar é o fato de que. apenas instanciando a classe de Acesso a Dados. Além de economizar linhas de código. Ele apenas chama a classe responsável por isso. Volte a classe de Acesso a Dados e. só fazemos uma única vez. que é parecido com o método Delete (a diferença é que nele usamos o parâmetro nCodGenerico e precisamos instanciar o DataTable. formulário a formulário. no caso a de Acesso a Dados.

que é praticamente igual ao PesquisaID (com parâmetro). quando for Pesquisa. etc. e o método: Pronto. que fizemos anteriormente. Temos situações em que. Como este método não possui parâmetros.Chame o PesquisaID. por exemplo. os métodos estão sobrescritos. Confira: . Simples né? Agora vamos ao PesquisaNome. apenas retorno o DataTable PesquisaID. sem receber nenhum parâmetro nem valor. que é string. só precisamos trocar o parâmetro. precisamos passar todos os campos. ou o nome e telefone. em que posso passar apenas o código. devemos sobrescrever o construtor da minha classe. etc. vamos chamar os atributos declarados no início de nossa classe. referentes as colunas de nossa tabela. em branco. outras em que precisamos passar o nome e o telefone. Para não ter o trabalho de sempre ter de preencher todas as propriedades. analisando aquelas situações descritas acima. Insira o seguinte código: Como o método é do tipo DataRow. que indica que quero pegar o 1º índice (ou 1ª linha) de meu DataRow. Agora. desta forma: Desta forma. crio outros construtores. outros em que preciso passar somente o código. e passo o comando Rows[0].

O método Localizar não iremos alterar neste form. Abra esse form. são repassados às propriedades criadas no começo do código. teremos 4 construtores: um que não terá parâmetro algum. pois o que antes gastávamos 4 linhas. hoje gastamos apenas 2.Assim não terei o trabalho de instanciar as classes. Pode parecer pouco. para quando precisarmos fazer Pesquisas por ID. criado na classe. já que precisamos alterá-lo no form dePesquisa. tenho uma produtividade no código. que é preenchido pelo Localizar e o usaremos para Excluir o registro. como fizemos com o método Salvar acima. que tem como parâmetro o código. pois nossa classe de Acesso a Dados que é a responsável por se conectar ao banco. Isso aumenta e muito a produtividade e a facilidade de dar manutenção. mais imagina em um sistema grande. Vamos então fazer as modificações necessárias nos outros métodos de nosso formulárioPaciente Herdado. quando for atualização. um que terá o código do paciente. Os valores que são passados como parâmetros. já meu construtor servirá pra isso. o nome e o telefone. por exemplo. quando for uma inserção. comente (ou exclua) o using acima. um que passo o código. Vá ao método CarregaValores e insira o seguinte código: . caso ocorra algum erro. Finalizando apenas retorno o método Delete. chamar as propriedades e preenchê-las. então passamos o _nCodGenerico. já que não iremos mais utilizar o DataSet nessa página. e um construtor que passarei somente o nome e o telefone. com milhares de páginas e linhas de código. Dessa forma. Em resumo. usamos o 2º construtor que criamos. abra o método Delete e faça o digite o seguinte código: Primeiramente. Agora instanciamos a classe. Assim percebam que podemos customizar nossas classes de acordo com nossas necessidades.

vá ao método Pesquisar e insira o seguinte código: . atribuídas aos valores do formulário. passo a ele a classe instanciada chamando o método PesquisaID. passo como parâmetro o _nCodGenerico. aquele método sem parâmetro.Aqui eu instancio minha classe. Senão passaria o outro método. se o DataRow for diferente de nulo. do tipo DataTable. instancio um DataRow(que retorna apenas uma linha). Depois verifico. usando as propriedades declaradas na classe. já que quero apenas retornar uma linha. da mesma forma que o método Excluir. preencho os campos que desejo. Abra agora o formulário Pesquisa Paciente.

vamos testar o projeto. então houve um erro! . Salve tudo e compile. quem faz isso é minha classe de Acesso a Dados. A diferença é que antes meu DataTablerecebia um TableAdapter. Clique em Pacientes. que chamava os métodos de Pesquisa. Se o seu projeto está igual o meu.Perceba que nesse método pouca coisa mudou. Novo. Agora não. digite um nome e um telefone e clique em Salvar.

e excluirmos somente o lblCodigo. Para que implementem o Cadastro de Médicos. clique em Localizar. Para baixar. devemos fazer a seguinte alteração (lembrando que estamos no método Salvar. altere-o no if). estarei disponibilizando o código-fonte completo do Cadastro de Médicos. Para isso. estou disponibilizando para download o que fizemos até esta parte do artigo em nosso sistema. não há essa necessidade. Se for inserção.Este erro aponta que meu lblCodigo está vazio ou em um formato incorreto. Finalizando. deixo um desafio a vocês. Porque ainda não temos o código do Paciente. temos que ir ao formulário base. exclua o registro e perceba que o código não foi excluído. Como não podemos simplesmente ir ao método Excluir e apagar o label manualmente (até podemos. Para quem se interessar. irmos ao método LimpaControles. já que não precisamos ir toda vez no método Excluir. os métodos e o formulário de Cadastro de Consultas. com algumas diferenças em relação ao Cadastro de Pacientes e alguns métodos a mais. Agora dê dois cliques no resultado da busca. iremos criar a classe. que é o nome de nosso label (se o label de seu form tiver outro nome. teste a busca. preciso preencher o código do Paciente. fazermos um if no controle do tipo Label. No final do próximo artigo. Agora compile. e sim apenas uma vez no método LimpaControles. do formulário Paciente Herdado): Faço uma simples verificação. clique aqui. se o status for Editando. vá ao formulário Base e insira o seguinte código: Assim utilizamos facilmente o conceito de Herança. Usaremos também LINQ em nossos métodos. abordados nos artigos anteriores. mais não é correto!). e principalmente os conceitos de MVC. Para isso. grave um novo registro. Não perca! . Na próxima parte de nossa série de artigos. já que temos rótulos diferentes. deverá estar funcionando corretamente. dentro do foreach dos controles. usando esses conceitos de Herança Visual.

o nome é dsConsulta) e clique com o botão direito noConsultaTableAdapter. na classe de Acesso a Dados 2 novos métodos. que será disponibilizado ao fim deste artigo. para criarmos os métodos da mesma forma como fizemos anteriormente. Acompanhem: Como dito no fim do artigo anterior. mais a frente. implementando os métodos da classe de Acesso a Dados para que o mesmo funcione. pois terá. vamos criar o Cadastro de Consultas. o que irá Pesquisar pelo nome do Paciente e a Pesquisa pelo nome d Médico. e clique em Add Query. Primeira modificação a ser feita é em nosso DataSet. já que devemos implementar os tipos de consultas que iremos fazer.Nesta parte iremos criar o Cadastro de Consultas. com a inclusão de 2 novos métodos. segue o Cadastro de Médicos incluso no código-fonte. Como feito anteriormente. pelo nome do paciente e/ou pelo nome do médico. Este 1º método será o de Pesquisa por ID da Consulta. seguindo o padrão dos outros cadastros. pelo código da consulta. LINQ. Abra seu DataSet (no meu caso. Dito isto. no final deste. Ele será um pouco diferente dos outros Cadastros. Outra diferença é que usaremos. clique em Next para aparecer esta tela: . clique em Use SQL Statements e SELECT which returns rows. para fazermos estas pesquisas.

Clique nele e.Devemos alterar esta instrução SQL. já que queremos retornar o ID da Consulta. Para fins didáticos (e seguindo a videoaula) vamos usar o Query Builder. Nome do Medico. Data da Consulta e Hora Inicial. adicione as tabelas Medico e Paciente. selecione os seguintes campos e execute a instrução: . clique com o botão direito na parte branca ao lado da tabela Consulta e clique emAdd Table. na tela que aparece. Iremos também fazer um INNER JOIN (ligação entre duas ou mais tabelas) com as tabelas Medico e Paciente. Nome do Paciente.

Nossa instrução SQL ficará da seguinte forma: Só que ainda não está pronta. Altere sua instrução para que fique desta forma: . Vamos usar dois filtros. para retornarmos as consultas parametrizadas pelo ID e pesquisarmos as consultas apenas que estiverem ativas.

dê o nome de PesquisaID para ele. Nosso campo Ativo está com o valor nulo (NULL). Deverá aparecer esta mensagem: Que apenas indica que a instrução SQL usada nos retorna dados diferentes das outras consultas. se o deixarmos assim. sem problemas. No SQL Server. Abra o SQL Server e confirme: Para que funcione. deixe selecionado a 1ª opção. clique em Next e em Finish. execute a seguinte instrução: .Clique em Next e na próxima tela. nossa query recém criada não irá funcionar. Fill a DataTable. devemos alterar este valor do campo Ativo.

Agora sim. só altere a instrução SQL para a de baixo: Clique em Next. Faça o mesmo procedimento que o método anterior. Para testar. nossa query irá funcionar. Faça o mesmo para o próximo método. clique com o botão direito em cima da query e clique em Preview Data. alterando a instrução SQL para nos retornar o nome do médico e dando o nome de PesquisaNomeMedico: . já que nosso campo Ativo está com o valor 1 (True). coloque o valor parametrizado de nossa consulta. dê o nome de PesquisaNomePaciente e clique em Finish. selecione apenas a 1ª opção. que no caso é referente ao campo IdConsulta e clique em Preview: Nosso próximo método será pelo Nome do Paciente. Na janela que surge.

assim como as outras. irá herdar de AcessoDados e terá os mesmos métodos da classe base e mais os 2 métodos que implementamos a pouco: .Assim nossa tabela Consulta terá 3 pesquisas diferentes: Agora vamos a classe AcessoDados para criarmos a classe de AcessoDadosConsulta que.

Como você pode perceber, implementei os métodos PesquisaNomePaciente ePesquisaNomeMedico, o resto são os métodos sobrescritos de minha classe baseAcessoDados. Não implementei estes 2 últimos métodos da classe base, pois os métodos da classe base são genéricos a todas as outras classes. Estes últimos são específicos para esta classe. Estou disponibilizando para download o que fizemos até esta parte do artigo. Para baixar,clique aqui. Na próxima parte de nossa série de artigos iremos implementar os métodos referentes aos criados na classe AcessoDadosConsulta. Não perca!

Nesta parte iremos criar os códigos referentes aos métodos criados anteriormente da classe de Consulta. Após isso, criaremos também um novo formulário, que será o de Pesquisa das Consultas. Acompanhem: Abra o DataSet de Consulta, para que modifiquemos o método Fill, doConsultaTableAdapter. Vamos alterá-lo para que sejam retornadas apenas as consultas que estiverem ativas. Para isso, clique com o botão direito em cima do método Fill doConsultaTableAdapter e clique em Configure. Altere a instrução SQL que aparece para a seguinte:

Nessa mesma tela, clique no botão Advanced Options e, na tela que aparece, desmarque as duas últimas opções, como mostra a imagem a seguir:

Desmarcando essas opções, não iremos ter vários parâmetros em nosso método, dessa forma estaremos evitando o uso de concorrência. Dê OK, clique em Next, Next na próxima tela também e Finish. Assim iremos retornar somente as consultas que estiverem ativas. Agora vamos criar em nossa classe de Acesso a Dados o método Pesquisar, que será responsável por realizar todas as pesquisas. Então crie o método, como mostra abaixo: PS: A partir de agora irei colocar em meus artigos desta série (como já faço com artigos deASP.NET e SQL Server) o código em si e não mais prints do código, apenas com o intuito de não poluir com muitas imagens os artigos.

01 02

public DataTable Pesquisar()

03 04

{

05 06

try

07 08

{

09 10

//instancio o TableAdapter e o DataTable

11 12

ConsultaTableAdapter ta = new ConsultaTableAdapter();

13

dsConsulta.ConsultaDataTable dt = new dsConsulta.ConsultaDataTable();

14

15 16

//uso o método Fill do TableAdapter, passando como parâmetro o DataTable

17 18

ta.Fill(dt);

19 20

//retorno o DataTable preenchido

21 22

return dt;

23 24

}

25 26

catch (Exception ex)

27 28

{

29 30

throw new Exception(ex.Message.ToString());

31 32

}

33 } A implementação dos outros métodos é parecida com a das outras classes de Acesso a Dados. bem parecido com o método das outras classes: . set. } 15 public bool bAtivo { get. } 13 14 public string sObservacao { get. set. podemos criar a pública e já declarar direto o get e set. } 11 12 public DateTime dHrFim { get. set. set. } 09 10 public DateTime dHrInicio { get. set. } 07 08 public DateTime dDtConsulta { get. Vamos criar as propriedades relativas aos campos do banco nesta classe como feito anteriormente. set. Vamos implementar o código do método Salvar. Ao invés de criarmos as propriedades privadas e públicas. } Lembrando que esse recurso está disponível a partir da versão 2008 do Visual Studio. poupando assim código. mais desta vez faremos de uma forma otimizada. } 03 04 public int nCodMedico { get. Veja: 01 02 public int nCodConsulta { get. } 05 06 public int nCodPaciente { get. set. set.

passando como parâmetro as propriedades criadas no começo da classe 20 . se estiver inserindo. que será retornada preenchida no fim do método 15 16 bool bSalvar = false. minha variável bSalvar recebe o método Insert 18 19 //do TableAdapter. 17 //verifico.01 02 public override bool Salvar(bool bInsert) 03 04 { 05 06 try 07 08 { 09 10 //instancio o TableAdapter 11 12 ConsultaTableAdapter ta = new ConsultaTableAdapter(). 13 14 //crio uma variável auxiliar.

dDtConsulta. nCodPaciente. true) > 0). uso o método Update e passo a propriedade bAtivo como parâmetro do método 32 33 34 else 35 36 { 37 bSalvar = (ta. dHrFim. .Insert(nCodMedico. nCodPaciente. 29 30 } 31 //senão.21 22 if (bInsert) 23 24 { 25 26 bSalvar = (ta. 27 28 dHrInicio. bAtivo. sObservacoes. dDtConsulta. sObservacoes. nCodConsulta) > 0). dHrInicio. 38 39 40 dHrFim.Update(nCodMedico.

ToString()). nem preciso usar a variável auxiliar. ou seja. 45 46 } 47 48 catch (Exception ex) 49 50 { 51 52 throw new Exception(ex. Veja: 01 02 public override bool Delete() 03 { . preciso passar a propriedade bAtivo. 53 54 } 55 } Neste código. O método Delete é bem simples. já que posso ter a situação do usuário estar querendo alterar o status de Ativo para Inativo. se o método for Insert. Já no método Update. irá gravar a consulta com o status Ativo. passo como parâmetro as propriedades criadas anteriormente e o valor true.Message. sempre que for gravar. como padrão. por isso devo passá-la.41 42 } 43 44 return bSalvar.

04 05 06 try 07 08 { 09 10 //instancio o TableAdapter 11 12 ConsultaTableAdapter ta = new ConsultaTableAdapter().Delete(nCodConsulta) > 0). 13 14 //retorno o método Delete passando a propriedade nCodConsulta como parâmetro 15 16 return (ta. .Message. 17 18 } 19 20 catch (Exception ex) 21 22 { 23 throw new Exception(ex.ToString()).

15 //uso o método PesquisaID.ConsultaDataTable dt = new dsConsulta. passando como parâmetro o dt e a variável nCodGenerico .ConsultaDataTable(). 12 13 14 ConsultaTableAdapter ta = new ConsultaTableAdapter().24 25 26 } 27 } Os próximos dois métodos PesquisaID serão iguais aos métodos das classes anteriores. Confira: 01 02 public override DataTable PesquisaID(int nCodGenerico) 03 04 { 05 06 try 07 08 { 09 10 //instancio o DataTable e o TableAdapter 11 dsConsulta.

19 20 //retorno o DataTable preenchido 21 22 return dt.Message.16 17 18 ta. 31 32 } 33 34 } 35 public override DataRow PesquisaID() .ToString()).PesquisaID(dt. nCodGenerico). 23 24 } 25 26 catch (Exception ex) 27 28 { 29 30 throw new Exception(ex.

36 37 38 { 39 40 try 41 42 { 43 44 //retorno apenas a primeira linha de minha consulta 45 46 return this. 47 48 } 49 50 catch (Exception ex) 51 52 { 53 54 throw new Exception(ex.ToString()).Message.Rows[0].PesquisaID(nCodConsulta). 55 } .

será pesquisado todos os nomes que contenham essas letras.ConsultaDataTable dt = new dsConsulta. só mudara que usarei os caracteres coringas (%) como filtro de pesquisa. 01 02 public DataTable PesquisaNomePaciente(string sDsNomePaciente) 03 04 { 05 06 try 07 08 { 09 10 //instancio o DataTable e o TableAdapter 11 dsConsulta. passando como parâmetro o dt . 12 13 14 ConsultaTableAdapter ta = new ConsultaTableAdapter(). 15 16 //uso o método PesquisaNomePaciente. ou seja. quando o usuário digitar por exemplo ton.56 57 } Os métodos PesquisaNomePaciente e PesquisaNomeMedico serão também praticamente iguais em sua estrutura.ConsultaDataTable().

concatenados com a variável sDsNomePaciente 19 20 ta.ToString()). 33 34 } 35 36 } . "%" + sDsNomePaciente + "%").PesquisaNomePaciente(dt. 25 26 } 27 28 catch (Exception ex) 29 30 { 31 32 throw new Exception(ex. 21 22 //retorno o DataTable preenchido 23 24 return dt.17 18 //e os caracteres coringas.Message.

ConsultaDataTable(). concatenados com a variável sDsNomeMedico 55 56 ta.PesquisaNomeMedico(dt. 48 49 50 ConsultaTableAdapter ta = new ConsultaTableAdapter(). . passando como parâmetro o dt 53 54 //e os caracteres coringas. "%" + sDsNomeMedico + "%").37 38 public DataTable PesquisaNomeMedico(string sDsNomeMedico) 39 40 { 41 42 try 43 44 { 45 46 //instancio o DataTable e o TableAdapter 47 dsConsulta.ConsultaDataTable dt = new dsConsulta. 51 52 //uso o método PesquisaNomePaciente.

69 70 } 71 } Pronto. GridView e dos dois Buttons. Agora vá ao frmPesquisa. Precisamos então ir ao frmBase e alterar o modificador de acesso de alguns controles parapublic (repare no frmPesquisa que estão como private com um cadeado. Então. Como já disse. vá ao frmBase. 61 62 } 63 64 catch (Exception ex) 65 66 { 67 68 throw new Exception(ex. nossa classe está implementada. escolha o frmBase. na Solution Explorer. só que como ele é herdado do formulário base. terá três tipos de pesquisas: pelo Código. por Código e Descrição. clique em Add > Windows Forms. pelo Nome do Médico e pelo Nome do Paciente. adicione umRadioButton com o text Nome do Médico para que fique dessa forma: . Após fazer isso. nos trouxe apenas os dois padrões. não é possível movê-los ou redimensioná-los). dê o nome de frmPesquisa a ele e clique em OK. Então.Message. selecione o templateInheritedForm. diferente dos outros. Na tela que surge perguntando de qual form você irá herdar. altere a propriedade Modifiers doGroupBox. dê um Build Solution (F6). esse formulário terá três tipos de pesquisas. Agora vamos criar nosso formulário de Pesquisaque.ToString()).57 58 //retorno o DataTable preenchido 59 60 return dt.

Em nosso form precisamos sobrescrever o método Pesquisar. Para isso. criado no formulário base. faça o seguinte: 01 02 public override void Pesquisar() 03 04 { 05 06 try 07 08 { .

Checked) 27 28 { .Checked) 19 20 { 21 22 dt = acesso.Text)).PesquisaID(int. 15 //verifico qual RadioButton está checado. dependendo de qual for. chamo o método adequado 16 17 18 if (rbtCodigo.Parse(txtPesquisa. 23 24 } 25 26 else if (rbtDescricao.09 10 //instancio a Classe e o DataTable 11 12 AcessoDadosConsulta acesso = new AcessoDadosConsulta(). 13 14 DataTable dt = new DataTable().

Text + "%"). 45 46 } 47 48 catch (Exception ex) .PesquisaNomeMedico("%" + txtPesquisa.PesquisaNomePaciente("%" + txtPesquisa.29 30 dt = acesso.Text + "%").Checked) 35 36 { 37 38 dt = acesso. 31 32 } 33 34 else if (rbtNomeMedico. 39 40 } 41 42 //crio um novo método para carregar os itens no ListView 43 44 Carregar(dt).

Clear(). . a diferença desse método com o do form frmPesquisaPaciente.Items.Message. já que o mesmo usa apenas as 2 colunas do ListView e no nosso form usaremos mais do que isso.ToString()). por exemplo.49 50 { 51 52 throw new Exception(ex. Então vamos criar o método que foi chamado acima (que terá como diferença o número de colunas apenas): 01 02 private void Carregar(DataTable dt) 03 04 { 05 06 try 07 08 { 09 10 //limpo os registros do ListView 11 lstPesquisa. é que não iremos usar o método CarregarItens. 53 54 } 55 } Como você pode ver acima.

Add(dr["NOMEMEDICO"]. adiciono os itens e subitens. insiro uma linha no ListView 21 22 //instancio o ListViewItem. 31 item.ToString().Text = dr["IDCONSULTA"].Rows) 17 18 { 19 20 //para cada linha de meu DataTable. . 27 28 item.ToString()).Add(dr["NOMEPACIENTE"]. referentes 23 24 //aos campos que estou pesquisando em meu ListView 25 26 ListViewItem item = new ListViewItem().12 13 14 //carrego os dados no ListView 15 16 foreach (DataRow dr in dt.SubItems. 29 30 item.SubItems.ToString()).

Items.ToString()).SubItems.Add(dr["DATACONSULTA"]. 43 44 } 45 46 } 47 48 catch (Exception ex) 49 50 { 51 throw new Exception(ex.Add(dr["HORAINICIO"].32 33 34 item.ToString()).ToString()).SubItems.Message. 35 36 item. 37 38 //aqui adiciono a varíavel instanciada item 39 40 //carregada com o item e subitem ao ListView 41 42 lstPesquisa. .Add(item).

Nela. Nele adicione três colunas. Então vá ao frmPesquisaBase e abra na SmartTag do ListView a opção Edit Columns. como mostra a imagem: Dê OK. Antes disso.52 53 54 } 55 } Ok. um Build Solution para atualizar o projeto e volte ao frmPesquisa. altere a propriedade das colunas para public. para que o ListView fique como na imagem a seguir: . agora temos que adicionar estas colunas a mais em nosso ListView. precisamos alterar o modificador de acesso das colunas que já existem para public.

EventArgs e) 03 04 { 05 06 //frmConsulta consulta = new frmConsulta().ShowDialog().cs (o form principal) e altere o botão que chama as Consultas: 01 02 private void toolStripButton3_Click(object sender.ShowDialog().Vamos testar o form. 07 08 //consulta. abra o Form1. 09 10 frmPesquisa pesquisa = new frmPesquisa(). Antes de rodá-lo. 11 12 pesquisa. 13 } .

criado anteriormente funcione corretamente e começar a criação do Cadastro de Consultas implementando os métodos necessários para que o mesmo funcione. Nesta parte iremos fazer algumas alterações em nosso DataSet para que nosso formulário de Pesquisas. adicionando tratamento de erros nos métodos relevantes e assim deixando o código mais limpo. clique aqui. devemos realizar algumas alterações em nosso DataSet para que nosso formulário de Pesquisas criado na parte anterior funcione. Clique no botão Consultas para ver o resultado: Estou disponibilizando para download o que fizemos até esta parte do artigo. Se ao executarmos o formulário de Pesquisas e tentarmos realizar uma pesquisa. Acompanhem: Como dito anteriormente. Dei uma revisada em todo o projeto.Salve e compile o projeto. antes de criarmos o Cadastro de Consultas. Para baixar o projeto. será disparado o seguinte erro: .

Cole a query que você copiou. Crie o TableAdapter usando a mesma string de conexão que os outros. como na hora da inserção de um novo registro neste TableAdapter. pois vamos usá-la no TableAdapter que iremos criar. estamos tentando retornar o Nome do Médicoe o Nome do Paciente que estão em outras tabelas. podem dar outros erros. Faça o mesmo com os métodos PesquisaNomeMedico e PesquisaNomePaciente doTableAdapter de Consulta s. clique em Advanced Options e desmarque as três opções. por isso está dando este erro de constraint. ou seja. do TableAdapter de Consultas e clique em Configure. Copie a query que aparece. Para resolvermos isso. já que nossa query será apenas para consulta: Na próxima tela desmarque a opção Return a DataTable e na opção Fill a DataTable dê o nome de PesquisaID. Clique com o botão direito em cima do método PesquisaID. Se deixarmos assim. crie métodos em nosso novoTableAdapter e cole essas query’s.Este erro acontece porque em nossos métodos de Pesquisa do TableAdapter de Consulta do nosso DataSet estamos retornando mais campos do que temos em nosso TableAdapter: Como você pode perceber pela imagem acima. já que os valores Nome do Médico e Nome do Pacientenão pertencem a este TableAdapter. O resultado final de nosso TableAdapter será este: . copie a query deles. Irá aparecer os campos de consulta em nossoTableAdapter. clique em Next e Finish. vamos criar um TableAdapter exclusivo para as Pesquisas.

teremos alguns erros na classe de Acesso a Dados. específico para isso. pois devemos alterar nosso DataTable e o TableAdapter. devemos criar outro TableAdapter. usaremos este TableAdapterapenas para pesquisas. para cadastros o uso do TableAdapter é excelente (neste tipo de exemplo simples).Apenas clique com o botão direito em cima da coluna IDCONSULTA e clique em Delete Keypara excluirmos a chave primária. que nos retornará todas as pesquisas. como já dissemos. de Consultas para Pesquisas. vamos adicionar uma nova query no TableAdapter Consultas. Exclua os métodos que copiamos. com o status Ativo = 1. ou seja. Se fizermos uma consulta que contenha mais colunas que o nosso TableAdapter (como nesse exemplo). já que. do TableAdapter de Consultas e dê um Build Solution (F6) em sua aplicação. A diferença é que esta query irá nos retornar as consultas que estiverem ativas. já para consultas devemos analisar bem a situação. Podemos concluir que. Voltando ao DataSet. Agora volte a classe de Acesso a Dados e altere o método Pesquisar para o seguinte: 01 public DataTable Pesquisar() .

02

03 04

{

05 06

try

07 08

{

09 10

//instancio o TableAdapter e o DataTable

11

dsConsulta.PesquisasDataTable dt = new dsConsulta.PesquisasDataTable();

12

13 14

PesquisasTableAdapter ta = new PesquisasTableAdapter();

15 16

//uso o método Fill do TableAdapter, passando como parâmetro o DataTable

17 18

ta.Pesquisar(dt);

19 20

//retorno o DataTable preenchido

21

return dt;

22

23 24

}

25 26

catch (Exception ex)

27 28

{

29 30

throw new Exception(ex.Message.ToString());

31 32

}

33

}

Somente trocamos o DataTable e TableAdapter, como feito nos outros métodos, e chamamos o método Pesquisar, que acabamos de criar. Compile a aplicação, clique emConsultas, teste o formulário e você verá que agora está funcionando corretamente:

Para deixarmos 100% nosso formulário, vamos formatar nossos campos de Data e Horausando um recurso importante de formatação do .NET, que é o string.Format (mais sobre manipulação de strings em C# aqui). Vá ao frmPesquisa.cs e, no método Carregar, use o string.Format para que o campoDATACONSULTA exiba somente a data no formato dd/MM/yyyy e o campo HORAINICIOexiba a hora no formato HH:mm, como o código abaixo nos mostra:

1

item.SubItems.Add(string.Format("{0:dd/MM/yyyy}", dr["DATACONSULTA"]));

2

3

item.SubItems.Add(string.Format("{0:HH:mm}", dr["HORAINICIO"]));

Perceba que tirei o ToString() do final dos campos, já que o string.Format espera um objeto (onde está meu dr[“DATACONSULTA”] por exemplo) e se eu passar o ToString() ele reconhece como um simples texto e não aplica a formatação correta no campo. Salve e compile para ver o resultado:

Adicione alguns labels. Agora sim vamos criar o Cadastro de Consultas. nossa tabela de Consultas tem chaves estrangeiras. ou seja. a partir de nosso form de Cadastro de Consultas o usuário irá escolher o nome ou código do Médico e fará o mesmo com o Paciente. Podemos perceber em nosso TableAdapter de Pesquisas que temos o Nome do Medico e oNome do Paciente. ou seja. o template Inherited Form (que indica que nosso form será herdado de outro) e dê o nome a ele de frmConsultaHerdado. Em nosso form não podemos colocar textboxes para o usuário digitar o nome do Médico e do Paciente. Na tela que aparece para selecionar o formulário que herdaremos. muito menos os respectivos ID’s deles. Dessa forma como podemos ter a certeza que o cadastro de uma consulta será vinculada a um Médico e a um Paciente? Por meio de consultas auxiliares. já que. formulário finalizado. Escolha a categoria Windows Form.Pronto. vamos criar um novo form. escolha o frmBase e clique em OK. Vá na Solution Explorer (CTRL + W + S). clique com o botão direito na solução e clique em Add > New Item. não temos a garantia de que o usuário irá digitar o nome ou ID correto. para que seu form fique como o da imagem a seguir: . eliminando o trabalho de criar duas telas novas com novos controles e tudo mais. textboxes e buttons. Assim iremos reaproveitar as telas de Pesquisa que já temos. referente as tabelas Medico e Paciente. Com essa idéia em mente.

dtHrInicio e dtHrFim. depois alteraremos para uma imagem para demonstrar ao usuário que esses botões servirão para pesquisar os pacientes e médicos. No formulário base temos uma variável pública. criar duas variáveis que serão responsáveis por armazenar os códigos de Paciente e de Médico. lblHrFim e lblObservacoes. Datetimepicker – dtConsulta. o selecionarmos na pesquisa. temos que fazer o mesmo. Agora volte ao formulário e dê dois cliques nos botões para chamar o evento Click dos mesmos. Textboxes – txtNomePaciente. Assim. Altere também a propriedade Custom Format do dtConsulta para dd/MM/yyyy e altere a propriedade Format para Custom. este último com a propriedade Multiline para True. responsável por armazenar um código genérico. em nossos cadastros dePaciente e de Médico quando fazemos a gravação dos dados usamos esta variável para receber o ID da gravação. Por enquanto deixaremos com este texto btn. faça o seguinte código para chamar os formulários responsáveis por pesquisar Paciente e Médico. 3 public int _nCodMedico. Neles. colocando no Custom Format o valor HH:mm. que é visível em todo o formulário que herda deste form. pesquisarmos pelo Paciente e/ou Médico. Nesse momento nossas variáveis receberão os códigos respectivos de cada formulário. Faça o mesmo com os outros datetimepicker.Os ID’s e propriedades dos controles são: Labels – lblNomePaciente. lblHrInicio. estes dois com a propriedade ReadOnly = True (que indica que nossos textboxes serão somente leitura) e com texto em negrito. txtNomeMedico. e txtObservacoes. lblDtConsulta. clicarmos em OK e voltarmos ao nosso form. respectivamente: . Em nosso cadastro de consulta. Buttons – btnConsultarPaciente e btnConsultarMedico. lblNomeMedico. Ela será preenchida no momento em que clicarmos nos botões que criamos. Por enquanto vá à página de códigos de nosso form e declare as variáveis responsáveis por receber estes códigos: 1 2 public int _nCodPaciente.

17 18 } 19 20 } .ShowDialog() == DialogResult.sCdCodigo != string.Empty) 13 14 { 15 16 _nCodPaciente = int.01 02 private void btnConsultarPaciente_Click(object sender.OK) 09 10 { 11 12 if (frmPesquisaPaciente.sCdCodigo). EventArgs e) 03 04 { 05 frmPesquisaPaciente frmPesquisaPaciente = new frmPesquisaPaciente().Parse(frmPesquisaPaciente. 06 07 08 if (frmPesquisaPaciente.

EventArgs e) 25 26 { 27 28 frmPesquisaMedico frmPesquisaMedico = new frmPesquisaMedico().Parse(frmPesquisaMedico.ShowDialog() == DialogResult.sCdCodigo != string.21 22 } 23 24 private void btnConsultarMedico_Click(object sender. 39 40 } . 29 30 if (frmPesquisaMedico.Empty) 35 36 { 37 38 _nCodMedico = int.sCdCodigo).OK) 31 32 { 33 34 if (frmPesquisaMedico.

Para baixar. mais nosso textbox não será preenchido com o registro selecionado. 7 8 frmConsulta. Vamos testar nosso form agora. Estou disponibilizando para download o que fizemos até esta parte.ShowDialog(). realizando alterações no formulário e criando os métodos Salvar. Vá ao formulário principal de Consultas. Agora clique em Novo e clique em um dos botões que criamos para ver que será aberto o form de Pesquisa. voltaremos ao nosso form. Localizar eCarrega Valores. Nesta parte iremos continuar as alterações em nosso Cadastro de Consultas. clique aqui. Assim nossas variáveis serão preenchidas com os códigos vindos do registro pesquisado pelo usuário nos forms. dê dois cliques no botão Consultas e altere o código do mesmo para o de baixo: 1 2 private void toolStripButton3_Click(object sender. Dessa forma estamos reaproveitando código e melhorando o desempenho de nossa aplicação. usaremos os métodos já criados em nossa classe de Acesso a Dados. EventArgs e) 3 4 { 5 6 frmConsultaHerdado frmConsulta = new frmConsultaHerdado(). Seguindo essa linha de reaproveitamento de código. pois não precisamos criar novas telas para fazer isso. feitas na parte 12.41 42 } 43 } Percebam que estes códigos são iguais aos do botão Localizar dos forms de cadastro de Paciente e Médico. Selecione um registro e clique em OK. Acompanhem: . 9 } Salve e compile. Clique no botão Consultas para que nosso form se abra. Excluir. pois falta implementarmos o método que pesquisará o Médico e o Paciente.

temos em nossos botões já implementados a consulta de Médico e Paciente. selecione na propriedade ImageList o controle que arrastamos pro form. clique em Abrir e dê OK. uma que irá retornar o nome do Paciente e outra que retornará o nome doMédico. como você pode ver abaixo: A imagem escolhida estará disponível para download ao final do artigo. que irá fazer duas consultas no banco. para Magenta. juntamente com o projeto. não estávamos retornando o nome do Paciente nem do Médico em nosso formulário. Altere a propriedadeTransparentColor. como a imagem abaixo ilustra: No artigo anterior. do ImageList. dentro da classe pai de Acesso a Dados. e na propriedade ImageKeyselecione a imagem que adicionamos ao ImageList. iremos ver ambos a seguir: Modo 1 – Aqui iremos criar um método nas classes AcessoDadosPaciente eAcessoDadosMedico. Para resolvermos isso. arraste o controle ImageList para o formulário e clique na opçãoChoose images.Voltando ao nosso frmConsultaHerdado. podemos fazer de dois modos. vá às respectivas classes e faça o seguinte método: 01 02 public string PesquisaNome(int nCodGenerico) . escolha a imagem. Agora vá nas propriedades dos botões do form. limpe a propriedade Text. Vamos adicionar uma imagem a eles. Clique em Add. a fim de deixar a imagem transparente. abra a ToolBox. Para isso. apenas armazenamos os ID’s deles nas variáveis _nCodPaciente e _nCodMedico. Para isso.

que recebe meu método PesquisaID 07 08 DataTable dt = PesquisaID(nCodGenerico). 10 11 //Exibindo a primeira linha e a coluna com o nome do Paciente. 15 16 if (dt.Count > 0) 17 18 { 19 20 return PesquisaID(nCodGenerico).ToString(). se tiver retorno o método PesquisaID. 21 22 } . 12 13 14 //Se não tiver linhas retorno uma string vazia.03 04 { 05 06 //Crio um DataTable.Rows[0]["NOMEPACIENTE"].Rows. convertido para string. 09 //Verifico se meu DataTable contém linhas.

crie o mesmo método para a classe AcessoDadosMedico. Agora volte ao frmConsultaHerdado. vá ao método referente aos eventos click dos botões de Paciente e Médico (coloquei os códigos dentro de métodos para facilitar o tratamento de erros e só fiz a chamada ao método nos botões) e altere a codificação deles para a seguinte: 01 02 private void ConsultarPaciente() 03 04 { 05 06 AcessoDadosPaciente objPaciente = new AcessoDadosPaciente(). 07 frmPesquisaPaciente frmPesquisaPaciente = new frmPesquisaPaciente().Empty.23 24 else 25 26 { 27 28 return string. 08 09 try . 29 30 } 31 } Seguindo esta lógica.

sCdCodigo != string.Empty) 19 20 { 21 22 _nCodPaciente = int.10 11 12 { 13 14 if (frmPesquisaPaciente.Parse(frmPesquisaPaciente.PesquisaNome(_nCodPaciente). 25 26 //passando como parâmetro a variável _nCodPaciente 27 28 txtNomePaciente. 23 24 //Meu txtNomePaciente recebe o objPaciente chamando o método PesquisaNome. 29 } .OK) 15 16 { 17 18 if (frmPesquisaPaciente.sCdCodigo).ShowDialog() == DialogResult.Text = objPaciente.

41 42 } 43 } Perceba que agora estou usando o método da classe de Acesso a Dados.ToString()). clique nesses botões para consultar o Médico e o Paciente e veja que agora os campos texto são preenchidos: .Message. que implementei anteriormente. Seguindo esta lógica. aperte F5 para compilar o projeto. faça o mesmo com o método ConsultarMedico.30 31 32 } 33 34 } 35 36 catch (Exception ex) 37 38 { 39 40 throw new Exception(ex. Métodos implementados.

no construtor da classe: .Perceba que desta forma estamos fazendo consultas ao banco duas vezes. ao invés de fazer duas consultas ao banco. só precisamos criar outra variável no frmPesquisaBase que irá receber o nome do usuário pesquisado. em que temos apenas duas colunas em nosso ListView. Então. iremos trabalhar com a “passagem” de variáveis entre formulários. Aproveite também para inicializar esta variável com o valor vazio. Usaremos o frmPesquisaBase. que já contém uma variável auxiliar (com o nome sCdCodigo) que recebe o código da consulta quando pesquisado por um Médico ou Paciente. Veja da outra forma como isso é diferente: Modo 2 – Aqui. uma para pesquisarmos o nome e.sCdCodigo). Lembrando que este exemplo serve para este caso. abra o frmPesquisaBase e declare uma variável do tipo string que receberá o nome pesquisado em nossa consulta (perceba que ela é declarada logo abaixo da variávelsCdCodigo): 1 2 //Declaramos as variáveis públicas do tipo string 3 4 public string sCdCodigo. outra para retornarmos o nome do Médico ou Paciente.Parse(frmPesquisaPaciente. Dito tudo isto. 5 public string sDsNome. dentro dela. Se você notar a codificação dos métodos para Consultar Médico e Consultar Pacienteperceberá que está variável já é usada em nosso formulário para consultarmos o ID do usuário pesquisado: 1 _nCodPaciente = int.

11 12 sDsNome = string. 13 } Dentro do evento Click do botão OK.Empty.01 02 public frmPesquisaBase() 03 04 { 05 06 InitializeComponent().Empty) 05 06 { 07 //se estiver vazia e o foco estiver no ListView preencho as variáveis . 07 08 //Inicializamos as variáveis com valor vazio 09 10 sCdCodigo = string. altere o código para o seguinte: 01 02 //faço a verificação se a variável sCdCodigo está vazia 03 04 if (sCdCodigo == string.Empty.

15 16 sDsNome = lstPesquisa. Insira esta linha também no evento DoubleClick e também nos eventosKeyDown e SelectedIndexChanged.Focused) 11 12 { 13 14 sCdCodigo = lstPesquisa. do ListView.Text.SubItems[1]. . E é ela que passaremos ao frmCadastroHerdado. Assim nossa variável sDsNome será preenchida sempre que consultarmos um usuário neste formulário.08 09 10 if (lstPesquisa. altere-o para o seguinte: 01 02 private void ConsultarPaciente() 03 04 { 05 frmPesquisaPaciente frmPesquisaPaciente = new frmPesquisaPaciente().SelectedItems[0]. Volte novamente a este formulário e.Text.SelectedItems[0]. no método ConsultarPaciente. 17 18 } 19 } Perceba no código acima que estou passando a variável recém-criada para ser preenchida pelo ListView.

23 24 } 25 } .ShowDialog() == DialogResult.sDsNome.OK) 13 14 { 15 16 if (frmPesquisaPaciente.Parse(frmPesquisaPaciente.sCdCodigo).Text = frmPesquisaPaciente. 21 22 txtNomePaciente.sCdCodigo != string.Empty) 17 18 { 19 20 _nCodPaciente = int.06 07 08 try 09 10 { 11 12 if (frmPesquisaPaciente.

26

27 28

}

29 30

catch (Exception ex)

31 32

{

33 34

throw new Exception(ex.Message.ToString());

35 36

}

37

}

Veja que assim, não precisaremos usar a classe de Acesso a Dados e, consequentemente, não faremos duas consultas ao banco, ganhando assim em performance. Só fazer a mesma alteração no método ConsultarMedico. Aperte F5 e faça uma consulta para ver se está tudo OK:

Vá à classe de Acesso a Dados, e na classe AcessoDadosConsulta, crie o seguinte construtor:

1 2

public AcessoDadosConsulta(int nCodConsulta)

3 4

{

5 6

this.nCodConsulta = nCodConsulta;

7

}

Com este construtor criado não teremos problemas ao retornar registros de consultas em nosso formulário, quando criarmos o método CarregaValores. Seguindo as videoaulas que originaram este artigo, vamos agora criar os métodos Salvar,Excluir, Localizar e Carrega Valores, bem parecidos com os métodos de outros formulários. Veja a codificação de cada um a seguir: Salvar –

01 02

public override bool Salvar()

03

{

04

05 06

try

07 08

{

09 10

bool bSalvar = false;

11 12

//Instancio a classe de Acesso a Dados

13

AcessoDadosConsulta objConsulta = new AcessoDadosConsulta(_nCodGenerico);

14

15

//Se estiver editando, minha variável nCodConsulta, da classe de Acesso a Dados recebe o _nCodGenerico

16

17 18

if (sStatus == StatusCadastro.scEditando)

19 20

{

21 22

objConsulta.nCodConsulta = _nCodGenerico;

dDtConsulta = dtConsulta.dHrFim = DateTime.Value. 31 32 objConsulta.Text.nCodPaciente = _nCodPaciente. 34 35 objConsulta.Parse(dtHrFim.dHrInicio = DateTime.Salvar(sStatus == StatusCadastro.Parse(dtHrInicio.Value.sObservacoes = txtObservacoes. 29 30 objConsulta. 36 37 38 objConsulta.Value.23 24 } 25 26 //Preencho os valores do form 27 28 objConsulta.ToShortTimeString()). 39 bSalvar = (objConsulta.ToShortTimeString()). 40 41 return bSalvar.nCodMedico = _nCodMedico. 33 objConsulta.scInserindo)). .

42 43 44 } 45 46 catch (Exception ex) 47 48 { 49 50 throw new Exception(ex.ToString()).Message. 51 52 } 53 } Excluir – 01 02 public override bool Excluir() 03 04 { 05 06 try 07 08 { .

11 12 return objConsulta.09 10 AcessoDadosConsulta objConsulta = new AcessoDadosConsulta().ToString()). 21 22 } 23 } Localizar – 01 02 public override bool Localizar() 03 04 { 05 try . 13 14 } 15 16 catch (Exception ex) 17 18 { 19 20 throw new Exception(ex.Delete().Message.

OK) 19 20 { 21 22 bLocalizar = (frmPesquisa. 11 12 frmPesquisa frmPesquisa = new frmPesquisa().06 07 08 { 09 10 bool bLocalizar = false. 23 24 //verifico agora se meu bLocalizar retornou algum registro 25 if (bLocalizar) . se o usuário clicar em OK 15 16 //minha variável bLocalizar recebe o sCdCodigo 17 18 if (frmPesquisa.ShowDialog() == DialogResult.sCdCodigo != string.Empty). 13 14 //faço abaixo uma verificação.

Parse(frmPesquisa. 45 } .sCdCodigo). 31 32 } 33 34 } 35 36 return bLocalizar.Message. 37 38 } 39 40 catch (Exception ex) 41 42 { 43 44 throw new Exception(ex.ToString()).26 27 28 { 29 30 _nCodGenerico = int.

15 16 //Se o DataRow for diferente de nulo.46 47 } Carrega Valores – 01 02 public override void CarregaValores() 03 04 { 05 06 try 07 08 { 09 //Instancio a classe e o DataRow. que recebe o método PesquisaID de minha classe 10 11 AcessoDadosConsulta objConsulta = new AcessoDadosConsulta(_nCodGenerico).PesquisaID(). preencho as propriedades 17 if (dr != null) . 12 13 14 DataRow dr = objConsulta.

Parse(dr["DATACONSULTA"].ToString()). 29 30 } 31 32 } 33 34 catch (Exception ex) 35 36 { 37 throw new Exception(ex.Value = DateTime.Value = DateTime.Text = dr["OBSERVACOES"]. 25 26 dtHrFim. 23 24 dtHrInicio.Parse(dr["HORAINICIO"].18 19 20 { 21 22 dtConsulta.Value = DateTime.ToString().ToString()). 27 28 txtObservacoes.Parse(dr["HORAFIM"].ToString()).Message.ToString()). .

ao clicarmos no botão Localizar. Agora nos surge um problema. como também os métodos criados acima. . incluindo assim novos campos para que. Não perca! Disponibilizo o código-fonte do projeto clicando aqui.38 39 40 } 41 } Se apertarmos F5 e para compilar teremos um erro no frmPesquisa. alterando não só o DataSet. o mesmo não irá carregar o nome do médico e o nome do paciente em nossa tela. Se clicarmos no botão Localizar do frmCadastroHerdado. É isso que faremos na próxima parte do nosso Consultório. já que agora ele “espera” um valor do tipo intcomo parâmetro. pois teremos que alterar a chamada à classe AcessoDadosConsulta. Para resolver é só passar o valor 0 e compilar a aplicação sem problemas. ele nos retorne os nomes do médico e do paciente. Para resolvermos isso teremos que alterar nosso DataSet.

Sign up to vote on this title
UsefulNot useful