WPF
- Controle de usuários com ADO .NET
O objetivo deste artigo é mostrar como criar uma aplicação WPF básica para gerenciar um cadastro de usuários com login e senha usando os recursos da ADO .NET.
Nossa aplicação deverá acessar um banco de dados SQL Server 2008 Express chamado Usuarios, criado no SQL Server Management Studio, que possui a tabela Userdata com a seguinte estrutura:
![]() |
Estrutura da tabela
Userdata :
onde ID é uma chave primária do tipo Identity. |
O foco é gerenciar o cadastro de usuários realizando as operações CRUD - inclusão, atualização e exclusão de usuários.
Vamos abrir o Visual C# 2010 Express Edition e criar um novo projeto do tipo WPF Application: File -> New Project -> WPF Application;
Informe o nome ControlaUsuarios e clique em OK;
Vamos incluir no projeto um arquivo de configuração para que possamos armazenar a string de conexão com o banco de dados SQL Server.
No menu Project -> Add New Item , selecione o template Application Configuration File, aceite o nome App.Config e clique em Add;
![]() |
Isso irá criar o arquivo App.Config no projeto. Agora inclua no arquivo o código abaixo que define a string de conexão com o banco de dados usado no projeto:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="conexaoSQLServer"
providerName="System.Data.SqlClient"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Usuarios.mdf;Integrated Security=True;User Instance=True;" />
</connectionStrings>
</configuration>
|
Note que definimos o nome da seção : conexaoSQLServer , o provedor usado: System.Data.SqlClient e a string de conexão usada.
Selecione o arquivo MainWindow1.xaml e a partir da ToolBox vamos incluir nesta janela os seguintes controles:
Defina o leiaute do formulário conforme a figura abaixo:
![]() |
O código XAML gerado será o seguinte:
<Window x:Class="DatabaseApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Controle de Usuários" Height="373" Width="522" Loaded="Window_Loaded" Background="White">
<Grid Height="336" Width="503" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="141*" />
<ColumnDefinition Width="356*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="136*" />
<RowDefinition Height="198*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<ListView Margin="8,9,68,125" Name="lstvUsuarios" ItemsSource="{Binding}" MinWidth="350" MinHeight="100" Grid.ColumnSpan="2" Grid.RowSpan="2" Background="#BFF3D9D2">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Path=ID}"></GridViewColumn>
<GridViewColumn Header="Usuário" DisplayMemberBinding="{Binding Path=usuario}"></GridViewColumn>
<GridViewColumn Header="Senha" DisplayMemberBinding="{Binding Path=senha}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<TextBox Margin="92,81,145,96" Name="txtUsuario" DataContext="{Binding ElementName=lstvUsuarios,Path=SelectedItem}" _
Text="{Binding Path=usuario}" Grid.ColumnSpan="2" Grid.Row="1" Background="#FFEFFAC3" />
<TextBox Height="23" Margin="92,0,145,65" Name="txtSenha" VerticalAlignment="Bottom" DataContext="{Binding ElementName=lstvUsuarios,Path=SelectedItem}" _
Text="{Binding Path=senha}" Grid.ColumnSpan="2" Grid.Row="1" Background="#7DEBE88D" CharacterCasing="Normal" />
<Label Margin="16,81,53,92" Name="label1" Grid.Row="1" Content="Usuário :"></Label>
<Label Height="30" Margin="16,0,53,56" Name="label2" VerticalAlignment="Bottom" Grid.Row="1" Content="Senha :"></Label>
<Button Height="26" Margin="16,0,51,23.5" Name="btnIncluir" VerticalAlignment="Bottom" Click="btnIncluir_Click" Grid.Row="1" Content="Incluir"></Button>
<Button Height="26" Margin="102,0,0,23.5" Name="btnAtualizar" VerticalAlignment="Bottom" Click="btnAtualizar_Click" HorizontalAlignment="Left" Width="75" _
Grid.ColumnSpan="2" Grid.Row="1" Content="Atualizar"></Button>
<Button Height="26" Margin="51,0,0,23.5" Name="btnDeletar" VerticalAlignment="Bottom" Click="btnDeletar_Click" Grid.Column="1" HorizontalAlignment="Left" _
Width="75" Grid.Row="1" Content="Deletar"></Button>
<Button Height="27.5" Margin="136,0,145,22.75" Name="btnLimpar" VerticalAlignment="Bottom" Click="btnLimpar_Click" Grid.Column="1" Grid.Row="1" Content="Limpar"></Button>
</Grid>
</Window>
|
Observe que estou usando os recursos do DataBinding do WPF para vincular os dados da tabela nos controles do formulário.
Essa é a interface da nossa aplicação e através dela iremos realizar o gerenciamento dos usuários existentes na tabela Userdata;
- Ao carregar o projeto o controle ListView deverá exibir os usuários cadastrados;
- Ao selecionar uma linha do controle ListView as informações
de nome de usuário e senha deverão ser exibidos nas caixas de
texto do formulário;
- No evento Click de cada um dos botões teremos
o código que irá realizar as operações CRUD para manutenção
dos dados;
Para tornar nossa pequena aplicação mais aderente as boas práticas iremos criar uma classe chamada Acesso que será responsável por realizar as operações CRUD usando os recursos da ADO .NET;
Dessa forma teremos uma classe responsável pelo acesso e persistência dos dados na aplicação separando assim as responsabilidades de acesso a dados da intereface.
No menu Project, selecione Add Class , informe o nome Acesso.cs e clique em Add;
As declarações de uso de namespaces definidos na classe são:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
O namespace adotado para esta classe será: DatabaseApplication
Devemos também incluir uma referência ao namespace System.Configuration no projeto.
No menu Project -> Add Reference, selecione a Aba .NET na janela Add Reference e selecione : System.Configuration e clique em OK;
![]() |
Vamos agora definir os seguintes métodos nesta classe:
A seguir irei descrever cada um dos métodos :
1- getConexaoSQLServer() - obtém e retorna um a conexão com o SQL Server a partir do arquivo App.Config.
| /// <summary> /// Obtem uma conexão com o banco de dados /// </summary> /// <returns></returns> public static SqlConnection getConexaoSQLServer() { string strCon = GetConnectionStringByNome("conexaoSQLServer"); if (strCon == null) throw new Exception("String de conexão não localizada."); SqlConnection con = new SqlConnection(strCon); return con; } |
2- closeConexaoSQLServer() - Fecha uma conexão com o SQL server.
/// <summary>
/// Fecha a conexao
/// </summary>
/// <param name="conexao"></param>
public static void closeConexaoSQLServer(SqlConnection conexao)
{
if (conexao.State == ConnectionState.Open)
conexao.Close();
}
|
3- Insert(usuario,senha) - Inclui um novo usuário e senha.
/// <summary>
/// inclui um novo usuario
/// </summary>
/// <param name="usuario"></param>
/// <param name="senha"></param>
public static void Insert(string usuario, string senha)
{
if (!verificaUsuario(usuario))
{
throw new Exception("Usuário ja existe.");
}
SqlConnection con = Acesso.getConexaoSQLServer();
try
{
con.Open();
SqlCommand comm = new SqlCommand("insert into userdata(usuario,senha) values(@usuario,@senha)", con);
comm.Parameters.AddWithValue("@usuario", usuario);
comm.Parameters.AddWithValue("@senha", GerarHash(senha));
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
closeConexaoSQLServer(con);
}
}
|
4- verificaUsuario(user) - Verifica se o nome do usuário informado já esta cadastrado.
/// <summary>
/// Verifica se um usuário ja esta cadastrado
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
private static bool verificaUsuario(string user)
{
SqlDataReader dr = null;
SqlConnection con = getConexaoSQLServer();
string sql = "Select * from userdata where usuario='" + user +"'";
try
{
con.Open();
SqlCommand cmd = new SqlCommand( sql, con);
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
return false;
}
else
{
return true;
}
}
catch (Exception ex)
{
throw ex;
}
}
|
5- Update(id,usuario,senha) - Atualiza os dados de um usuário.
/// <summary>
/// atualiza um registro selecionado
/// </summary>
/// <param name="id"></param>
/// <param name="usuario"></param>
/// <param name="senha"></param>
public static void Update(int id,string usuario, string senha)
{
SqlConnection con = getConexaoSQLServer();
try
{
con.Open();
SqlCommand comm = new SqlCommand("update userdata set usuario=@usuario,senha=@senha where id=@id", con);
comm.Parameters.AddWithValue("@id", id);
comm.Parameters.AddWithValue("@usuario", usuario);
comm.Parameters.AddWithValue("@senha", GerarHash(senha));
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
closeConexaoSQLServer(con);
}
}
|
6- Delete(id) - Exclui um usuário existente com base no id do usuário.
/// <summary>
/// deleta um registro selecionado
/// </summary>
/// <param name="id"></param>
public static void Delete(int id)
{
SqlConnection con = getConexaoSQLServer();
try
{
con.Open();
SqlCommand comm = new SqlCommand("delete from userdata where id=@id", con);
comm.Parameters.AddWithValue("@id", id);
comm.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
closeConexaoSQLServer(con);
}
}
|
7- getTabela() - Retorna um DataTable contendo todos os usuários cadastrados.
/// <summary>
/// retorna um datatable com todos os usuarios
/// </summary>
/// <returns></returns>
public static DataTable getTabela()
{
SqlConnection con = getConexaoSQLServer();
try
{
con.Open();
SqlCommand comm = new SqlCommand("Select * from userdata", con);
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(comm);
da.Fill(dt);
return dt;
}
catch(Exception ex)
{
throw ex;
}
finally
{
closeConexaoSQLServer(con);
}
}
|
8- GeraHash() - Gera o hash para a senha do usuário.
/// <summary>
/// gera o hash
/// </summary>
/// <param name="Valor"></param>
/// <returns></returns>
public static string GerarHash(string Valor)
{
System.Security.Cryptography.SHA1Managed Sha = new System.Security.Cryptography.SHA1Managed();
Sha.ComputeHash(System.Text.Encoding.Default.GetBytes(Valor));
return Convert.ToBase64String(Sha.Hash);
}
|
Definindo o código da Interface
A seguir veremos o código dos eventos que ocorrem nos controles usados na interface MainWindow1.xaml.
Estaremos usando a classe Acesso e usar os métodos ali definidos para acessar e persistir as informações.
O evento Loaded() irá ser executado quando o formulário for carregado e nele iremos exibir os dados na interface;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
ExibeDados();
}
catch (Exception ex)
{
MessageBox.Show("Erro : " + ex.Message);
this.Close();
}
}
|
No botão incluir temos o código que chama o método Insert da classe Acesso. Primeiro validamos as informações e a seguir incluímos o usuário e exibimos os dados:
private void btnIncluir_Click(object sender, RoutedEventArgs e)
{
string usuario = txtUsuario.Text;
string senha = txtSenha.Text;
if (ValidaDados())
{
try
{
Acesso.Insert(usuario, senha);
ExibeDados();
}
catch (Exception ex)
{
MessageBox.Show(" Erro : " + ex.Message, "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
|
No evento Click do botão Deletar o solicitamos a confirmação e verificamos se existe um usuário selecionado no ListView para obtermos o seu id e usarmos o método Delete() para excluir o usuário;
Para obter o id do usuário selecionado no ListView obtemos um DataRowView que representa um modo de exibição personalizado de um DataRow e a seguir usamos a propriedade Row para obter o DataRow visualizado que no caso é a coluna zero (Row[0]) representando o id do usuário;
private void btnDeletar_Click(object sender, RoutedEventArgs e)
{
if (MessageBox.Show("Confirma exclusão deste registro ?", "Excluir", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
if (lstvUsuarios.SelectedItems.Count > 0)
{
DataRowView drv = (DataRowView)lstvUsuarios.SelectedItem;
int id = Convert.ToInt32(drv.Row[0].ToString());
try
{
Acesso.Delete(id);
ExibeDados();
}
catch (Exception ex)
{
MessageBox.Show(" Erro : " + ex.Message, "Erro", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
|
Para atualizar um usuário temos que selecioná-lo no ListView, validar as informações, obter o seu id no ListView e então usar o método Update();
private void btnAtualizar_Click(object sender, RoutedEventArgs e)
{
string usuario = txtUsuario.Text;
string senha = txtSenha.Text;
if (ValidaDados())
{
if (lstvUsuarios.SelectedItems.Count > 0)
{
DataRowView drv = (DataRowView)lstvUsuarios.SelectedItem;
int id = Convert.ToInt32(drv.Row[0].ToString());
try
{
Acesso.Update(id, usuario, senha);
ExibeDados();
}
catch (Exception ex)
{
MessageBox.Show(" Erro : " + ex.Message,"Erro",MessageBoxButton.OK,MessageBoxImage.Error);
}
}
}
}
|
A rotina ExibeDados() usa o método getTabela para obter um DataTable contendo os usuários cadastrados e exibí-los no ListView;
public void ExibeDados()
{
DataTable dtb = Acesso.getTabela();
lstvUsuarios.DataContext = dtb.DefaultView;
}
|
No botão Limpar , atribuimos um valor vazio as caixas de texto e colocamos o foco no nome do usuário;
private void btnLimpar_Click(object sender, RoutedEventArgs e)
{
txtUsuario.Text = "";
txtSenha.Text = "";
txtUsuario.Focus();
}
|
A rotina de validação é bem simples e apenas verifica se as informações não estão em branco ou possuem um tamanho menor que 6 caracteres;
private bool ValidaDados()
{
bool retorno;
if (txtSenha.Text == string.Empty || txtSenha.Text.Length < 6 )
{
MessageBox.Show("Informe a senha do Usuário com no mínimo seis caracteres.", "Senha", MessageBoxButton.YesNo, MessageBoxImage.Error);
txtSenha.Focus();
return false;
}
else
{
retorno = true;
}
if (txtUsuario.Text == string.Empty || txtUsuario.Text.Length < 6)
{
MessageBox.Show("Informe o nome do Usuário com no mínimo seis caracteres.", "Senha", MessageBoxButton.YesNo, MessageBoxImage.Error);
txtSenha.Focus();
return false;
}
else
{
retorno = true;
}
return retorno;
}
|
Executando o projeto teremos o seguinte resultado:
![]() |
Sugestões para melhorias no projeto:
Pegue o projeto completo aqui:
ControlaUsuarios.zip
Eu sei é apenas WPF, mas eu gosto...
Referências: