C# - Cadastro Básico com TableAdapter usando os recursos RAD - III


Continuando a segunda parte do artigo vamos definir o código do formulário frmCadastro.cs que é o coração da aplicação.

O formulário de Cadastro, na visualização da tabPage1 - Cadastrar Alunos - tem o seguinte leiaute:

Vamos nos concentrar nas funcionalidades que desejamos para nossa aplicação.

Quando arrastamos os datasets para o formulário já foram criadas as funcionalidades para navegação nos registros, inclusão , alteração e exclusão dos dados da tabela Alunos;

Se você espiar o código do formulário vai notar que o assistente já gerou o código necessário para realizar tais operações.

Então está tudo pronto !!!

Sim, está , mas vamos dar uma arrumada no código para melhorar a interação com o usuário.

Vamos começar definindo os namespaces usados no formulário frmCadastro:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

Em seguida vamos definir as variáves que deverão ser visíveis por todo o código do formulário:

//variaveis publicas usadas pelos relatorios
String RelatorioTitulo="Relação de Alunos - ";
int paginaAtual = 1;
DataTable dtClientes = null;
static int li=0;

No evento Load vamos mover o código gerado para uma rotina chamada carregaDados pois vamos usar esta rotina mais de uma vez no formulário; Abaixo vemos a chamada da rotina no evento Load e a rotina com o código gerado pelo assistente:

private void Form1_Load(object sender, EventArgs e)
{
     carregaDados();
}

private void carregaDados()
{
    //código gerado pelo assistente
    this.cursosTableAdapter.Fill(this.cadastroDataSet.Cursos);
    this.alunosTableAdapter.Fill(this.cadastroDataSet.Alunos);
}

No evento Click do botão Salvar do controle BindingNavigator vamos mover o código gerado pelo assistente para a rotina atualizaDados() pois queremos realizar algumas validações antes de salvar os dados na tabela e avisar o usuário quando os dados forem salvos com sucesso.

private void alunosBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
     atualizaDados();
}
  
private void atualizaDados()
{
    if (nomeTextBox.Text == string.Empty || emailTextBox.Text == string.Empty || idadeTextBox.Text == string.Empty || cursoidComboBox.Text==string.Empty)
    {
           MessageBox.Show("Dados inválido(s) !", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
    {
              //código gerado pelo assistente
  
           this.Validate();
              this.alunosBindingSource.EndEdit();
              this.cursosBindingSource.EndEdit();
              this.tableAdapterManager.UpdateAll(this.cadastroDataSet);
              MessageBox.Show("Dados salvos com sucesso !", "Salvar", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

Agora vamos fazer outra alteração, desta vez no evento Click do botão Deletar do BindingNavigator pois desejamos exibir uma mensagem de confirmação ao usuário antes de excluir o registro selecionado.

   private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
   {
            DialogResult resultado = MessageBox.Show("Confirma Exclusão do registro?",
                                    "Excluir",
                                    MessageBoxButtons.YesNo,
                                    MessageBoxIcon.Question);

            if (resultado == DialogResult.Yes)
            {
                atualizaDados();
            }
            else
            {
                carregaDados();
            }
  }

Note que se o usuário confirmar a exclusão chamamos a rotina atualizaDados(), caso contrário chamamos a rotina carregaDados para carregar o formulário novamente.

Finalmente no evento Click do botão Imprimir temos o código para imprimir as informações dos alunos. Estamos usando o objeto PrintDocument.

     private void btnImprimir_Click(object sender, EventArgs e)
        {
                RelatorioTitulo = "Clientes - ";
                //define os objetos printdocument e os eventos associados
                System.Drawing.Printing.PrintDocument pd = new System.Drawing.Printing.PrintDocument();

                //IMPORTANTE - definimos 3 eventos para tratar a impressão : PringPage, BeginPrint e EndPrint.
                pd.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.pdRelatorios_PrintPage);
                pd.BeginPrint += new System.Drawing.Printing.PrintEventHandler(this.Begin_Print);
                pd.EndPrint += new System.Drawing.Printing.PrintEventHandler(this.End_Print);

                //define o objeto para visualizar a impressao
                PrintPreviewDialog objPrintPreview = new PrintPreviewDialog();
                try
                {
                    //define o formulário como maximizado e com Zoom
                    {
                        objPrintPreview.Document = pd;
                        objPrintPreview.WindowState = FormWindowState.Maximized;
                        objPrintPreview.PrintPreviewControl.Zoom = 1;
                        objPrintPreview.Text = "Parcelas";
                        objPrintPreview.ShowDialog();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
        }

A seguir temos os eventos para tratar a impressão:

 private void Begin_Print(object sender, System.Drawing.Printing.PrintEventArgs e)
 {
            paginaAtual = 1;
 }

 private void End_Print(object sender, System.Drawing.Printing.PrintEventArgs byvale)
 {
   }

O evento principal que vai imprimir o relatório é dado a seguir:

 private void pdRelatorios_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            //Variaveis das linhas
            float LinhasPorPagina = 0;
            float PosicaoDaLinha = 0;
            int LinhaAtual = 0;
    
            string alunoid = null;
            string nome = null;
            string idade = null;
            string email = null;
            string cursoid = null;
            string sexo = null;

            //Variaveis das margens
            float MargemEsq = e.MarginBounds.Left;
            float MargemSuperior = e.MarginBounds.Top + 100;
            float MargemDireita = e.MarginBounds.Right;
            float MargemInferior = e.MarginBounds.Bottom;

            Pen CanetaDaImpressora = new Pen(Color.Black, 1);

            //Variaveis das fontes
            Font FonteNegrito = default(Font);
            Font FonteTitulo = default(Font);
            Font FonteSubTitulo = default(Font);
            Font FonteRodape = default(Font);
            Font FonteNormal = default(Font);

            //define efeitos em fontes
            FonteNegrito = new Font("Arial", 9, FontStyle.Bold);
            FonteTitulo = new Font("Arial", 15, FontStyle.Bold);
            FonteSubTitulo = new Font("Arial", 12, FontStyle.Bold);
            FonteRodape = new Font("Arial", 8);
            FonteNormal = new Font("Arial", 10);

            //define valores para linha atual e para linha da impressao
            LinhaAtual = 0;
            
            //Cabecalho
            e.Graphics.DrawLine(CanetaDaImpressora, MargemEsq, 60, MargemDireita, 60);
            e.Graphics.DrawLine(CanetaDaImpressora, MargemEsq, 160, MargemDireita, 160);
            //nome da empresa
            e.Graphics.DrawString(Properties.Settings.Default.Empresa, FonteTitulo, Brushes.Blue, MargemEsq + 250, 80, new StringFormat());
            //Imagem
            e.Graphics.DrawImage(Image.FromFile(GetCaminhoImagem() + "maco10.gif"), 100, 68);
            e.Graphics.DrawString(RelatorioTitulo + System.DateTime.Today, FonteSubTitulo, Brushes.Black, MargemEsq + 250, 110, new StringFormat());

            LinhasPorPagina = Convert.ToInt32(e.MarginBounds.Height / FonteNormal.GetHeight(e.Graphics) - 9);

            dtClientes = alunosTableAdapter.GetData();
            int registros = dtClientes.Rows.Count;

            List<DataRow> clientes = dtClientes.AsEnumerable().ToList();

            //List<DataRow> clientes = new List<DataRow>();
            //foreach (DataRow dr in dtClientes.Rows)
            //{
            //    clientes.Add(dr);
            //}

            //inicia a impressao
            PosicaoDaLinha = MargemSuperior + (LinhaAtual * FonteNormal.GetHeight(e.Graphics));

            //Aqui sao lidos os dados
            while ((LinhaAtual < LinhasPorPagina && registros > li))
            {
                //obtem os valores do datareader
                alunoid = clientes[li].ItemArray[0].ToString();
                nome = clientes[li].ItemArray[1].ToString();
                idade = clientes[li].ItemArray[2].ToString();
                email = clientes[li].ItemArray[3].ToString();
                cursoid =  clientes[li].ItemArray[4].ToString();
                sexo = clientes[li].ItemArray[5].ToString();

                ////'inicia a impressao
                PosicaoDaLinha = MargemSuperior + (LinhaAtual * FonteNormal.GetHeight(e.Graphics));

                ////'impressão dos dados
                e.Graphics.DrawString("Código : ", FonteNormal, Brushes.Black, MargemEsq, PosicaoDaLinha);
                e.Graphics.DrawString(alunoid, FonteNormal, Brushes.Black, MargemEsq + 150, PosicaoDaLinha);
                e.Graphics.DrawString("Nome : ", FonteNormal, Brushes.Black, MargemEsq + 200, PosicaoDaLinha);
                e.Graphics.DrawString(nome, FonteNormal, Brushes.Black, MargemEsq + 250, PosicaoDaLinha);
                e.Graphics.DrawString("Email : ", FonteNormal, Brushes.Black, MargemEsq, PosicaoDaLinha + 20);
                e.Graphics.DrawString(email, FonteNormal, Brushes.Black, MargemEsq + 150, PosicaoDaLinha + 20);
                e.Graphics.DrawString("Idade: ", FonteNormal, Brushes.Black, MargemEsq, PosicaoDaLinha + 40);
                e.Graphics.DrawString(idade, FonteNormal, Brushes.Black, MargemEsq + 150, PosicaoDaLinha + 40);
                e.Graphics.DrawString("Curso : ", FonteNormal, Brushes.Black, MargemEsq + 250, PosicaoDaLinha + 40);
                e.Graphics.DrawString(cursoid, FonteNormal, Brushes.Black, MargemEsq + 300, PosicaoDaLinha + 40);
                e.Graphics.DrawString("Sexo : ", FonteNormal, Brushes.Black, MargemEsq, PosicaoDaLinha + 60);
                e.Graphics.DrawString(sexo, FonteNormal, Brushes.Black, MargemEsq + 150, PosicaoDaLinha + 60);

                ////'verifica se imprime um ou todos 
                if (chkImprimirCliente.Checked == true)
                {
                    LinhaAtual += 1;
                }
                else
                {
                    LinhaAtual += 11;
                }
                li += 1;
            }

            //Rodape
            e.Graphics.DrawLine(CanetaDaImpressora, MargemEsq, MargemInferior, MargemDireita, MargemInferior);
            e.Graphics.DrawString(System.DateTime.Now.ToString(), FonteRodape, Brushes.Black, MargemEsq, MargemInferior, new StringFormat());
            LinhaAtual += Convert.ToInt32(FonteNormal.GetHeight(e.Graphics));
            LinhaAtual += 1;
            e.Graphics.DrawString("Pagina : " + paginaAtual, FonteRodape, Brushes.Black, MargemDireita - 50, MargemInferior, new StringFormat());

            //Incrementa o numero da pagina
            paginaAtual += 1;

            //verifica se continua imprimindo
            if ((LinhaAtual > LinhasPorPagina))
            {
                e.HasMorePages = true;
            }
            else
            {
                e.HasMorePages = false;
            }
        }       

O código já esta comentado eu quero apenas chamar a atenção para a forma como estamos obtendo as informações da tabela Alunos:

O código abaixo é usado para obter os dados do TableAdapter alunosTableAdapter onde GetData() retorna um DataTable dtClientes;

dtClientes = alunosTableAdapter.GetData();
int registros = dtClientes.Rows.Count;

List<DataRow> clientes = dtClientes.AsEnumerable().ToList();

Obs: Eu deixei comentado uma outra forma de obter o mesmo resultado usando um laço for/next;

A seguir estamos convertendo o DataTable retornado para uma coleção;

Para acessar os dados da coleção usamos a seguinte notação:

alunoid = clientes[li].ItemArray[0].ToString();
nome = clientes[li].ItemArray[1].ToString();
idade = clientes[li].ItemArray[2].ToString();
email = clientes[li].ItemArray[3].ToString();
cursoid = clientes[li].ItemArray[4].ToString();
sexo = clientes[li].ItemArray[5].ToString();

Além disso temos a rotina GetCaminhoImagem() que obtém a imagem que estamos exibindo no relatório:

    //obtem o caminho da imagem no relatorio
        public static string GetCaminhoImagem()
        {
            string root = Environment.GetFolderPath(0);
            string caminhoImagem = Application.StartupPath;

            if (caminhoImagem.IndexOf("\\bin\\Debug")>0)
            {
                caminhoImagem = caminhoImagem.Replace("\\bin\\Debug", "");
            }
            else if (caminhoImagem.IndexOf("\\bin\\Release")>0)
            {
                caminhoImagem = caminhoImagem.Replace("\\bin\\Release", "");
            }

            caminhoImagem = caminhoImagem + "\\Imagens\\";
            return caminhoImagem;
        }

O relatório obtido pode se visto abaixo:

Vamos agora definir o código para a funcionalidade Consultar Aluno da segunda tabPage - Consultar Alunos:

No evento Click do botão - Procurar - inclua o seguinte código:

  private void btnProcurar_Click(object sender, EventArgs e)
  {
            if (txtNome.Text == string.Empty)
            {
                alunosDataGridView.DataSource = alunosTableAdapter.GetData();
            }
            else
            {
                alunosDataGridView.DataSource = alunosTableAdapter.GetDataByNome("%"+txtNome.Text+"%");
            }
 }

O código verifica se o nome do aluno foi informado na caixa de texto - TxtNome.

1- Se o nome NÃO foi informado então usamos o método GetData() para preencher o DataGridView com todos os dados da tabela Alunos
2- Se algo foi informado na caixa de texto então usamos a consulta GetDataByNome para filtrar os dados e usamos o caractere % que é um coringa de forma que todos os caracteres antes e depois do valor informado serão considerados;

Precisamos então criar a consulta GetDataByNome no TableAdapter alunosTableAdapter. Para fazer isso vamos seguir os mesmos passos usados para criar a consulta GetDataByUsuarioLogin;

1- Clique duas vezes no em CadastroDataSet para exibir a janela contendo o DataSet:
2- Clique com o botão direito sobre UsuariosTableAdapter e a seguir clique em Add Query...
3- Marque a opção Use SQL Statements (ela já vem marcada) e clique em Next>;
4- Marque a opção SELECT which returns rows (também ja vem marcada) pois queremos retornar um resultado obtido e clique em Next>;

A seguir defina a seguinte consulta SQL : SELECT alunoid, nome, idade, email, cursoid, sexo FROM dbo.Alunos WHERE nome LIKE @nome

Clique em Next> e Informe o nome para a consulta criada como GetDataByNome();

Pronto a consulta já esta pronto para uso.

Dessa forma implementamos todas as funcionalidades desejadas na aplicação usando os recursos dos assistentes do Visual C# 2010 Express Edition.

Esse exemplo é uma amostra do que podemos fazer para criar aplicações simples para uso pessoal usando os recursos RAD do Visual C#.Naturalmente existem outras funcionalidades que na prática deverão ser implementadas e isso eu deixo como um exercício para você...

O projeto completo esta disponível no Super DVD C#  que contém mais de 50 projetos completos com código fonte aberto além de diversos recursos de aprendizagem como apostilas, livros, artigos, etc.

Veja os destaques do Super DVD C#

Clique aqui e faça o seu pedido

1Pedro 2:13 Sujeitai-vos a toda autoridade humana por amor do Senhor, quer ao rei, como soberano,
1Pedro 2:14
quer aos governadores, como por ele enviados para castigo dos malfeitores, e para louvor dos que fazem o bem.

Referências:


José Carlos Macoratti