13
José Carlos Macoratti Quinta-feira, 30 de abril de 2009 C# - DataGridView, BindingSource e BindingNavigator Neste artigo veremos a utilização dos componentes BindingSource, BindingNavigator e DataGridView em aplicações C#. Sabe porque é importante você conhecer estes componentes? O componente BindingSource oferece a maneira mais simples e fácil de navegar através de registros em uma fonte de dados; ele foi criado justamente para simplificar o processo de vinculação com os controles relacionados a uma fonte de dados. Podemos fazer a vinculação do BindingSource com qualquer um dos seguintes objetos/Interfaces: ICollection , IList , IListSource, IBindingList e IBindingListViewObject , System.Type , IEnumerable , O componente BindingSource veio substituir o componente CurrencyManager e, embora você ainda possa continuar usando o CurrencyManager, o BindingSource deve ter preferência quando houve a necessidade de vincular os controles de um formulário Windows a uma fonte de dados; dessa forma o componente BindingSource permite criar um vínculo entre os controles e a fonte de dados. Ele fornece as seguintes vantagens sobre as técnicas de vinculação anteriores: Encapsular a funcionalidade do CurrencyManager e expor os eventos do CurrencyManager em tempo de projeto; Interagir com outros controles windows forms relacionados como por exemplo o BindingNavigator e o DataGridView; A propriedade DataSource é a propriedade padrão para a classe BindingSource, e o evento padrão é o evento CurrentChanged. Além disso, o BindingSource fornece métodos, propriedades e eventos como os eventos CurrentItemChanged e DataSourceChanged, que permite uma certa customização. A propriedade Positon obtém ou define o índice para o item atual na fonte de dados atual, enquanto que o método MoveLast() altera o valor atual da propriedade Position para o índice do último item na fonte de dados, que é a mesma coisa que obter o valor pela propriedade Count. Ex: Count -1. O item atual pode ser retornado através da propriedade Current, e a lista inteira pode ser retornada através da propriedade List. As operações de edição são suportadas no item atual através dos métodos: Current, RemoveCurrent, EndEdit, CancelEdit, Add e AddNew. iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindin gnavigator/im... 1 de 13 5/8/2010 17:11

C# - Data Grid View, Binding Source e Binding Navigator

Embed Size (px)

Citation preview

Page 1: C# - Data Grid View, Binding Source e Binding Navigator

José Carlos Macoratti Quinta-feira, 30 de abril de 2009

C# - DataGridView, BindingSource e BindingNavigator

Neste artigo veremos a utilização dos componentes BindingSource, BindingNavigator e DataGridView em aplicações C#.

Sabe porque é importante você conhecer estes componentes?

O componente BindingSource oferece a maneira mais simples e fácil de navegar através de registros em uma fonte de dados; ele foi criado justamente para

simplificar o processo de vinculação com os controles relacionados a uma fonte de dados.

Podemos fazer a vinculação do BindingSource com qualquer um dos seguintes objetos/Interfaces:

ICollection , IList , IListSource, IBindingList e IBindingListViewObject , System.Type , IEnumerable ,

O componente BindingSource veio substituir o componente CurrencyManager e, embora você ainda possa continuar usando o CurrencyManager, o

BindingSource deve ter preferência quando houve a necessidade de vincular os controles de um formulário Windows a uma fonte de dados; dessa forma o

componente BindingSource permite criar um vínculo entre os controles e a fonte de dados. Ele fornece as seguintes vantagens sobre as técnicas de

vinculação anteriores:

Encapsular a funcionalidade do CurrencyManager e expor os eventos do CurrencyManager em tempo de projeto;

Interagir com outros controles windows forms relacionados como por exemplo o BindingNavigator e o DataGridView;

A propriedade DataSource é a propriedade padrão para a classe BindingSource, e o evento padrão é o evento CurrentChanged. Além disso, o BindingSource

fornece métodos, propriedades e eventos como os eventos CurrentItemChanged e DataSourceChanged, que permite uma certa customização.

A propriedade Positon obtém ou define o índice para o item atual na fonte de dados atual, enquanto que o método MoveLast() altera o valor atual da

propriedade Position para o índice do último item na fonte de dados, que é a mesma coisa que obter o valor pela propriedade Count. Ex: Count -1.

O item atual pode ser retornado através da propriedade Current, e a lista inteira pode ser retornada através da propriedade List.

As operações de edição são suportadas no item atual através dos métodos: Current, RemoveCurrent, EndEdit, CancelEdit, Add e AddNew.

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

1 de 13 5/8/2010 17:11

Page 2: C# - Data Grid View, Binding Source e Binding Navigator

Embora o tratamento de valores atualizados seja feito automaticamente para todos os tipos de fonte de dados, a classe fornece os eventos

CurrentItemChanged and DataSourceChanged, que permitem uma customização.

As fontes de dados que são vinculadas ao BindingSource podem ser percorridas e gerenciadas com a classe BindingNavigator, que fornece uma interface para

navegação pelos itens da lista. Embora o BindingNavigator possa ser vinculado a qualquer fonte de dados, ele foi criado para ser integrado com o

BindingSource através da propriedade BindingNavigator.BindingSource

Muitos membros da classe BindingSource operam na lista relacionada representada pela propriedade List, e simplesmente referencia suas operações para lista

relacionada. Desta forma, quando o BindingSource está vinculado a uma implementação customizada de IList, o comportamento dos membros pode diferir

do comportamento descrito na documentação da classe. Assim, o método RemoveAt chama IList.RemoveAt. Na documentação, o método RemoveAt é

descrito considerando que a implementação de IList foi corretamente implementada.

A propriedade padrão para a classe BindingSource é DataSource e o evento padrão é CurrentChanged.

Nota: Como o BindingSource suporta a vinculação a fonte de dados simples e a complexas, a terminologia pode ser confusa. O temo list refere-se à

coleção de dados da fonte de dados, item denota um simples elemento. Para fonte de dados complexas os termos equivalentes table e row são usados.

Exemplos de utilização

//vincular o BindingSource a um componente DataGridViewthis.DataGridView1.DataSource = this.clientesBindingSource1;

ou

//obter o número total de items em uma fonte de dadosint count = this.clientesBindingSource.Count;

ou

//obtem ou define um indice para o item atualint pos = this.clientesBindingSource1.Position;

ou

//move para o último item na listathis.bindingSource1.Position = this.bindingSource1.Count - 1;

ou

//move para o último item na listathis.bindingSource1.Position = this.bindingSource1.MoveLast();

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

2 de 13 5/8/2010 17:11

Page 3: C# - Data Grid View, Binding Source e Binding Navigator

Usando BindingSource, BindingNavigator e DataGridView

Veremos agora um exemplo prático usando estes componentes e algumas de suas propriedades e métodos.

Se você deseja navegar através dos registros de uma fontes de dados basta vincular o componente BindingSource a fonte de dados e em seguida vincular os

controles do formulário (TextBox) ao controle BindingSource. Assim, poderemos usar os métodos: MoveNext(), MovePrevious(), MoveFirst(), and

MoveLast() para realizar tal tarefa.

Para o exemplo deste artigo, eu vou usar um banco de dados Microsoft Access que foi criado com o nome Cadastro.mdb e que estará em uma pasta c:\dados

e uma tabela Clientes com a seguinte estrutura:

Abra o Visual C# 2008 Express Edition ou o SharpDevelop 2.2 e crie uma nova aplicação do tipo Windows com o nome DataGridViewBinding.

Neste ponto, se você selecionar no menu Data a opção Add New Data Source e estabelecer uma conexão com o banco de dados Cadastro.mdb, selecionar

um DataSet e escolher a tabela Clientes, você criará um DataSet e, a partir da janela DataSource, poderá selecionar os campos e arrastar para o formulário

criando, assim, de forma automática, toda a interface para navegação pelos registros da tabela e o acesso ao banco de dados conforme pode ser visto na

figura abaixo:

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

3 de 13 5/8/2010 17:11

Page 4: C# - Data Grid View, Binding Source e Binding Navigator

Observe que são criados de forma automática os objetos

TableAdapter, BindingSource e BindingNavigator

além do DataSet.

Mas não é isso que queremos mostrar. Queremos mostrar outra forma de obter o mesmo resultado e aproveitar para mostrar como os componentes

BindingSource e BindingNavigator trabalham em conjunto.

Nosso objetivo será:

Obter os dados da tabela Clientes do banco de dados Cadastro.mdb;

Exibir os dados em um controle DataGridView;

Vamos limpar o projeto e ficar somente com o formulário form1.cs. Agora a partir da ToolBox inclua os seguintes controles no formulário:

Inclua o controle DataGridView no formulário form1.cs a partir da ToolBox e não use assistente que será aberto para selecionar um Data Source;

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

4 de 13 5/8/2010 17:11

Page 5: C# - Data Grid View, Binding Source e Binding Navigator

Vamos agora ao código do formulário clicando na opção View Code.

A primeira coisa que temos que definir é a conexão com o banco de dados, no exemplo estou usando um banco de dados Access, mas poderia usar o SQL

Server.

Vamos incluir então no início do código do formulário a linha de código abaixo para podermos usar as classes para efetuar a conexão com o banco de dados

Cadastro.mdb;

using System.Data.OleDb;

A seguir no interior da seção:

publicpartial classForm 1 :

Form

{

Vamos incluir o código a seguir onde estaremos definindo um objeto do tipo BindingSource:

BindingSource bs = new BindingSource();

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

5 de 13 5/8/2010 17:11

Page 6: C# - Data Grid View, Binding Source e Binding Navigator

Iremos atribuir os dados obtidos do banco de dados para o objeto bs e assim o DataGridView e o BindingNavigator podem usá-lo como fonte de dados.

Vamos agora extrair os dados da nossa base de dados.

Vamos usar o evento Load do formulário para efetuar a conexão com o banco de dados usando a seguinte linha de código:

OleDbConnection myConn = new OleDbConnection ("Provider=Microsoft.Jet.OleDb.4.0; Data Source=c:/dados/Cadastro.mdb");

Nota: O provedor para um banco de dados Access pode ser definido assim:

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=seu.mdb;Jet OLEDB:Database Password=suasenha;";

Como tratar com banco de dados sempre é uma tarefa sujeita a erros, vamos usar o bloco Try/Catch/Finally para tratar eventuais erros usando o seguinte

código:

private void Form1_Load(object sender, EventArgs e){

string conexaoBD = "Provider=Microsoft.Jet.OleDb.4.0; Data Source=c:/dados/Cadastro.mdb"

OleDbConnection conexao = new OleDbConnection (conexaoBD);

try

{

//abre a conexão

conexao.Open();

//define o comando sql para selecionar os dados das tabela Clientes

OleDbCommand sql = new OleDbCommand("SELECT * from Clientes", conexao);

//cria um adapter para preencher um dataset

OleDbDataAdapter da = new OleDbDataAdapter(sql);

//define um objeto DataSet

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

6 de 13 5/8/2010 17:11

Page 7: C# - Data Grid View, Binding Source e Binding Navigator

DataSet ds = new DataSet();

da.Fill(ds);

//atribui o dataset ao DataSource do BindingSource

bs.DataSource = ds;

//atribui o BindingSource ao BindingNavigator

bs.DataMember = ds.Tables[0].TableName;

//Atribui o BindingSource ao DataGridView

dataGridView1.DataSource = bs;

}

catch (Exception)

{

MessageBox.Show("erro ao obter os dados.");

}

finally

{

conexao.Close();

}

}

Executando o projeto iremos obter o seguinte:

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

7 de 13 5/8/2010 17:11

Page 8: C# - Data Grid View, Binding Source e Binding Navigator

Agora vamos usar um recurso do BindingSource para filtrar os dados na exibição do DataGridView. Inclua um controle Combobox no formulário e ativando

o ComboBox Tasks clique no link Edit Items e informe os valores 10, 20, 30 e 40. Inclua uma Label com o texto: Exibir Clientes com idade menor ou igual

a:

Agora no evento SelectedIndexChanged do Combobox inclua o código abaixo onde estamos usando a propriedade Filter do BindingSource.

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)

{

if (comboBox1.Text == "10")

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

8 de 13 5/8/2010 17:11

Page 9: C# - Data Grid View, Binding Source e Binding Navigator

bs.Filter = "idade <= 10";

if (comboBox1.Text == "20")

bs.Filter = "idade <= 20";

if (comboBox1.Text == "30")

bs.Filter = "idade <= 30";

if (comboBox1.Text == "40")

bs.Filter = "idade <= 40";

}

A propriedade Filter obtém ou define a expressão usada para filtrar quais linhas serão exibidas.

Geralmente usada em cenários de ligação de dados complexos, a propriedade Filter permite que você exiba um subconjunto da sua fonte de dados. Somente

listas subjacentes que implementam a interface IBindingListView oferece suporte a filtragem.

Quando o filtro não for referência nula, o BindingSource passa essa propriedade para a lista subjacente. Se você definir essa propriedade durante a

inicialização de objeto, a chamada será ser adiada até depois de inicialização for concluída.

Para formar um valor de filtro, especifique o nome de uma coluna seguido por um operador e um valor para filtrar.

O valor da propriedade Filter será mantido quando a fonte de dados for alterada. Para interromper a filtragem da fonte de dados, chame o método

RemoveFilter.

Executando o projeto iremos obter:

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

9 de 13 5/8/2010 17:11

Page 10: C# - Data Grid View, Binding Source e Binding Navigator

Inclua também um botão de comando no formulário e no seu evento Click inclua o código para remover o filtro aplicado usando a propriedade RemoveFilter:

private void button1_Click(object sender, EventArgs e)

{

bs.RemoveFilter();

}

Ao clicar no botão o filtro será removido e todos os dados serão exibidos novamente.

Podermos implementar outros filtros, como por exemplo filtrar por nome de forma que ao digitar os caracteres de um nome em uma caixa de texto os dados

serão filtrados e exibidos dinamicamente no DataGridView.

Para implementar este recurso inclua uma Label com o texto: Filtrar por nome e um TextBox - txtNome - no formulário form1.cs e no evento TextChanged

do TextBox inclua o código abaixo que usar a propriedade Filter:

private void textBox1_TextChanged(object sender, EventArgs e)

{

bs.Filter = "Nome like '%" + txtNome.Text + "%'";

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

10 de 13 5/8/2010 17:11

Page 11: C# - Data Grid View, Binding Source e Binding Navigator

}

Executando projeto e digitando as letras Ma teremos:

Você pode aplicar um filtro e sobre os dados filtrados aplicar outro filtro obtendo assim como resultado os dados que foram filtrados por critérios distintos em

duas etapas. No exemplo você pode filtrar a idade primeiro e depois filtrar por nome.

Podemos ainda efetuar combinações de condições para criar um filtro com múltiplos critérios sendo aplicados de uma vez. No exemplo acima podemos

definir um critério para filtrar por idade e por cidade.

Vamos então incluir um controle GroupBox e no seu interior dois controles Label: Cidade e Idade e dois TextBox : txtCidade e txtIdade e um Button -

btnFiltrar. Defina o leiaute conforme a figura abaixo:

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

11 de 13 5/8/2010 17:11

Page 12: C# - Data Grid View, Binding Source e Binding Navigator

No evento Click do botão de comando Aplicar Filtro inclua o código abaixo que aplica o filtro usando dois critérios:

Cidade que contenha o caractere digitado;1.

E idade maior que a informada;2.

private voidbtnFiltrar_Click(object sender,EventArgs e)

{ int id = Convert.ToInt32(txtIdade.Text); bs.Filter = "cidade like '%" + txtCidade.Text + "%' AND idade > " + id;

}

Executando o projeto e aplicando o filtro para os dois critérios definidos teremos exibidos os clientes cuja idade for maior que 25 e que a cidade inicie com

San;

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

12 de 13 5/8/2010 17:11

Page 13: C# - Data Grid View, Binding Source e Binding Navigator

Como o foco é mostrar como usar a propriedade Filter do BindingSource eu não estou efetuando validações, o que deve ser feito em uma aplicação de

produção.

Pegue o projeto completo aqui: DataGridViewBinding.zip

Eu sei é apenas C# , mas eu gosto...

iMasters - Por uma Internet mais criativa e dinâmica http://imasters.uol.com.br/artigo/12622/csharp/c_datagridview_bindingsource_e_bindingnavigator/im...

13 de 13 5/8/2010 17:11