C# - Cadastro de Alunos com foto (XML)
Nem sempre você vai precisar de um banco de dados para guardar informações.
Os bancos de dados relacionais são a melhor opção quando o objetivo é armazenar e recuperar informações mas apresentam diversos problemas.
Se o seu caso não requer a utilização de um banco de dados considere armazenar informações em arquivos XML.
As perspectivas do armazenamento de dados no formato XML são surpreendentes e até mesmo os Data WareHouses já estão armazenando informações no formato XML.
Um data warehouse (ou armazém de dados, ou depósito de dados no Brasil) é um sistema de computação utilizado para armazenar informações relativas às atividades de uma organização em bancos de dados, de forma consolidada. O desenho da base de dados favorece os relatórios, a análise de grandes volumes de dados e a obtenção de informações estratégicas que podem facilitar a tomada de decisão. (http://pt.wikipedia.org/wiki/Data_Warehouse) |
Se pensarmos que a plataforma .NET oferece diversos recursos para que possamos tratar informações no formato XML de forma rápida e descomplicada temos ai um motivo a mais para pensarmos na utilização do formato XML quando realmente indicado.
Neste artigo eu vou mostrar como criar uma aplicação usando a linguagem C# que realiza o gerenciamento de informações sobre alunos , incluindo a foto, persistindo e recuperando as informações de um arquivo XML.
É uma aplicação simples mas meu objetivo é mostrar o potencial que tem este recurso na plataforma .NET.
No exemplo deste artigo eu vou armazenar as seguintes informações sobre alunos:
Irei utilizar o arquivo Alunos.xml para armazenar as informações dos alunos. Este arquivo possui a seguinte estrutura:
<?xml version="1.0" standalone="yes"?> <alunos> <aluno> <codigo>10</codigo> <nome>Jimmi Hendrix</nome> <curso>Musica</curso> <mensalidade>3500</mensalidade> <foto>10)hendrix.jpg</foto> </aluno> </alunos> |
As fotos dos alunos serão armazenadas em uma pasta do projeto chamada Dados juntamente com o arquivo xml. Para evitar que existam nomes de fotos duplicadas (este é um dos problemas de usar esta solução) eu vou sempre concatenar o código do aluno mais o caractere cerquilha (#) com o nome da foto, dessa forma sempre teremos um nome único para a foto.
Para criar o projeto deste artigo eu vou usar o Visual C# 2008 Express Edition e antes de iniciar o projeto vou mostrar a aparência que terá a nossa aplicação na figura abaixo:
Agora vamos ao que interessa...
Criando a aplicação Windows Forms no Vsual C# 2008 Express Edition
Abra o Visual C# 2008 Express e crie um novo projeto do tipo Windows Forms Application no menu File->New Project -> Windows Forms Application com o nome CadastroAlunos;
No formulário form1.cs vamos incluir os controles a partir da ToolBox conforme o leiaute da figura abaixo:
|
Além disso vamos usar dois controles OpenFileDialog: ofd1 e ofd2.
Após incluir os controles acima e definir o nome de cada um conforme indicado, defina os controles conforme o leiaute acima;
A seguir vamos definir os namespaces usados no projeto no início do formulário form1.cs;
using
System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.VisualBasic;
using System.IO;
Feito isso vamos definir as variáveis que serão usadas no projeto:
//define
variáveis usadas no projeto
DataSet
ds;
string fcaminho;
string fdiretorio;
string pcaminho;
string pnome;
string pdestino;
int reg = 0;
DataRow linharegistro;
Vou começar definindo o código do botão de comando Carregar Arquivo XML.
Ao clicar no botão será aberta uma janela de diálogo OpenFileDialog para que seja possível selecionar o arquivo XML que desejamos carregar e exibir no controle DataGridView - gdvAlunos; O código é visto abaixo:
private void btnCarregaXML_Click(object sender, EventArgs e) { try { ofd1.Filter = "xml|*.xml|all files|*.*"; DialogResult res = ofd1.ShowDialog(); if (res == DialogResult.OK) { gdvAlunos.DataSource = null; btnLimpar.PerformClick(); fcaminho = ofd1.FileName; ds = new DataSet(); ds.ReadXml(fcaminho); //definindo a chave primaria a fim de procurar o registro usando o método find ds.Tables[0].Constraints.Add("pk_codigo", ds.Tables[0].Columns[0], true); gdvAlunos.DataSource = ds.Tables[0]; fdiretorio = fcaminho.Substring(0, fcaminho.LastIndexOf("\\") + 1); mostrarDados(); } } catch(Exception ex) { MessageBox.Show("Informação inválida : " + ex.Message, "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } } |
Se um arquivo for selecionado então faremos o seguinte:
- limpamos os controles do formulário: btnLimpar.PerformClick();
- Obtemos o caminho e nome do arquivo selecionado: fcaminho = ofd1.FileName;
- Criamos um dataset e usando o método ReadXml(fcaminho) lemos o conteúdo do arquivo XML para o dataset;
- Definimos uma chave primaria na tabela a fim de procurar o registro usando o método Find;
O
método Find da coleção Rows retorna um objeto DataRow,
e, neste caso, uma única linha e não um array de
linhas. Este método precisa que você defina a propriedade chave primária (Primary Key) antes de usá-lo. Se você não fizer isso vai obter uma exceção. |
- Chamamos a rotina mostrarDados() para exibir os dados no DataGridView;
Vejamos a seguir o código da rotina mostrarDados():
void mostrarDados() { if (ds.Tables[0].Rows.Count > 0) { picFoto.Image = null; txtCodigo.Text = ds.Tables[0].Rows[reg][0].ToString(); txtNome.Text = ds.Tables[0].Rows[reg][1].ToString(); txtCurso.Text = ds.Tables[0].Rows[reg][2].ToString(); txtMensalidade.Text = ds.Tables[0].Rows[reg][3].ToString(); picFoto.ImageLocation = fdiretorio + ds.Tables[0].Rows[reg][4].ToString(); } else MessageBox.Show("Não existem registros.","Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } |
Este código verifica se existem linhas na tabela : if (ds.Tables[0].Rows.Count > 0)
Em caso positivo exibe os dados nos controles do formulário. Estamos usando um dataset não tipado onde temos que definir a posição do registro na tabela do dataset da seguinte forma:
ds.Tables[0].Rows[reg][0].ToString();
A rotina mostrarDados() não retorna nada por isso o modificador void. Ela será usada sempre que desejamos exibir informações nos controles do formulário.
Vejamos agora o código do botão Incluir que deverá incluir um novo aluno no arquivo XML:
private void btnIncluir_Click(object sender, EventArgs e) { linharegistro = null; linharegistro = ds.Tables[0].Rows.Find(txtCodigo.Text); if (linharegistro == null) { //atribui os valores dos controles ao datarow linharegistro = ds.Tables[0].NewRow(); linharegistro[0] = txtCodigo.Text; linharegistro[1] = txtNome.Text; linharegistro[2] = txtCurso.Text; linharegistro[3] = txtMensalidade.Text; salvaFoto(); linharegistro[4] = pnome; //inclui uma linha na tabela ds.Tables[0].Rows.Add(linharegistro); reg = ds.Tables[0].Rows.IndexOf(linharegistro); //salva dados no arquivo xml ds.WriteXml(fcaminho); MessageBox.Show("Registro incluído com sucesso.", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } else MessageBox.Show("Registro já existe.O código deve ser único.","Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } |
Verificamos se o registro já existe usando o método Find: linharegistro = ds.Tables[0].Rows.Find(txtCodigo.Text);
Em caso positivo criamos uma nova linha(NewRow) e atribuímos os valores informados no TextBox à nova linha;
Chamamos a rotina SalvaFoto() e incluímos a nova linha na tabela e em seguida gravamos os dados no arquivo XML usando o método ds.WriteXml();
A rotina SalvaFoto() tem seu código exibido a seguir:
void salvaFoto() { //Procurando o nome da foto //salvando na pasta do arquivo xml com nome unico (codigo+nome_foto) pcaminho = picFoto.ImageLocation; pnome = txtCodigo.Text + "#" + (pcaminho.Substring(pcaminho.LastIndexOf('\\') + 1));//(codigo + nome da foto) pdestino = fdiretorio + pnome; picFoto.Image.Save(pdestino);//salva imagem no disco } |
Neste código atribuímos o caminho da foto a variável pcaminho e montamos o nome da foto com o código do aluno mais o caractere # e o nome da foto;
Montamos o diretório de destino e salvamos a foto no disco.
No botão Procurar temos o código que localiza um registro e exibe as informações no formulário:
private void btnProcurar_Click(object sender, EventArgs e) { int n = Convert.ToInt32(Interaction.InputBox("Informe o código do aluno :", "Procurar", "10", 200, 200)); //procurando registros usando o método find linharegistro = null; linharegistro = ds.Tables[0].Rows.Find(n); if (linharegistro != null) { //preenche os controles do formulário reg = ds.Tables[0].Rows.IndexOf(linharegistro); txtCodigo.Text = linharegistro[0].ToString(); txtNome.Text = linharegistro[1].ToString(); txtCurso.Text = linharegistro[2].ToString(); txtMensalidade.Text = linharegistro[3].ToString(); picFoto.ImageLocation = fdiretorio + linharegistro[4]; } else MessageBox.Show("registro não localizado.", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } |
Solicitamos o código do aluno usando o InputBox e novamente usamos o método Find para localizar o registro
O código do botão Atualizar que altera os dados do arquivo XML:
private void btnAtualizar_Click(object sender, EventArgs e) { //procurando registros usando o método find DataRow linharegistro = ds.Tables[0].Rows.Find(txtCodigo.Text); if (linharegistro!= null) { reg = ds.Tables[0].Rows.IndexOf(linharegistro); //atribui os valores dos controles aos campos da tabela ds.Tables[0].Rows[reg][0] = txtCodigo.Text; ds.Tables[0].Rows[reg][1] = txtNome.Text; ds.Tables[0].Rows[reg][2] = txtCurso.Text; ds.Tables[0].Rows[reg][3] = txtMensalidade.Text; File.Delete(fdiretorio + linharegistro[4]); salvaFoto(); ds.Tables[0].Rows[reg][4] = pnome; //grava no arquivo xml ds.WriteXml(fcaminho); MessageBox.Show("registro atualizado", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } else MessageBox.Show("Não existe registro de aluno com este código.", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } |
Localizamos o item usando o método Find e atribuímos os valores informados nas caixas de texto as linhas da tabela , salvamos a foto e gravamos as alterações no arquivo XML.
A rotina para excluir uma linha do arquivo é vista no código a seguir:
private void btnDeletar_Click(object sender, EventArgs e) { //procurando registros usando o método find DataRow linharegistro = ds.Tables[0].Rows.Find(txtCodigo.Text); if (linharegistro!= null) { File.Delete(fdiretorio + linharegistro[4]); ds.Tables[0].Rows.Remove(linharegistro); ds.WriteXml(ofd1.FileName); MessageBox.Show("Registro deletado.", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); reg = 0; mostrarDados(); } else MessageBox.Show("Não existe registro de aluno com este código.", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } |
Localizamos o item usando o método Find e usando método Remove excluímos a linha da tabela.
O código de cada um dos botões de navegação é mostrado a seguir:
private void btnPrimeiro_Click(object sender, EventArgs e) { reg = 0; mostrarDados(); } private void btnAnterior_Click(object sender, EventArgs e) { if (reg > 0) { reg--; mostrarDados(); } else { MessageBox.Show("Primeiro Registro."); } } private void btnProximo_Click(object sender, EventArgs e) { if (reg < ds.Tables[0].Rows.Count - 1) { reg++; mostrarDados(); } else { MessageBox.Show("Último Registro."); } } private void btnUltimo_Click(object sender, EventArgs e) { reg = ds.Tables[0].Rows.Count - 1; mostrarDados(); } |
Verificamos a posição do registro e usamos a rotina mostraDados para exibir os dados atuais.
O código do botão Limpar é dado a seguir:
private void btnLimpar_Click(object sender, EventArgs e) { //limpa controles TextBox do formulário e o picturebox txtCodigo.Text = txtNome.Text = txtCurso.Text = txtMensalidade.Text = ""; picFoto.Image = null; } |
Também incluímos o código abaixo no evento CellClick do DataGridView;
private void gdvAlunos_CellClick(object sender, DataGridViewCellEventArgs e) { try { //obtem o valor da primeira célula do grid que é o código do aluno int codigo = Convert.ToInt32(gdvAlunos.CurrentRow.Cells[0].Value); linharegistro = ds.Tables[0].Rows.Find(codigo); if (linharegistro != null) { //preenche os controles do formulário reg = ds.Tables[0].Rows.IndexOf(linharegistro); txtCodigo.Text = linharegistro[0].ToString(); txtNome.Text = linharegistro[1].ToString(); txtCurso.Text = linharegistro[2].ToString(); txtMensalidade.Text = linharegistro[3].ToString(); picFoto.ImageLocation = fdiretorio + linharegistro[4]; } else MessageBox.Show("registro não localizado.", "Aviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); } catch { } } |
dessa forma quando uma linha do grid for clicada obtemos os valores da linha e exibimos no formulário.
Para encerrar temos o código do botão que encerra a aplicação
private void btnSair_Click(object sender, EventArgs e) { DialogResult resultado = MessageBox.Show("Deseja Encerrar a aplicação?", "Sair", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (resultado == DialogResult.Yes) Application.Exit(); } |
Com isso mostramos que podemos ter informações armazenadas em arquivos XML e que podemos tratá-la de forma dinâmica e funcional com os recursos da linguagem C#.
Simples, simples assim
O projeto completo com os fontes abertos está no Super DVD .NET.
Eu sei é apenas XML, mas eu gosto...
Referências: