VB.NET - Uma introdução básica as controles de lista
Neste artigo vou falar um pouco sobre os controles de lista : ListBox , CheckedListBox e Combobox. Todos estes controles derivam da classe base ListControl . Esta classe é uma classe abstrata (MustInherit no VB.NET) e não pode ser instanciada , mas as classes concretas citadas e delas derivadas podem ser instanciadas e usadas normalmente conforme veremos a seguir.
A classe ListControl fornece muito das funcionalidades comuns entre estes três controles. A tabela abaixo lista as cinco propriedades nativas da classe ListControl que são herdadas pelas classes derivadas.
Propriedades da classe ListControl
Propriedade | Tipo | Descrição |
---|---|---|
DataSource | Object | Read/write. Define a fonte de dados para o controle de lista |
DisplayMember | String | Read/write. Define a propriedade da fonte de dados a ser exibida no controle. |
SelectedValue | Object | Read/write. Contém o valor do item selecionado atual definido pela propriedade ValueMember. Se ValueMember nao estiver definido retorna : object.ToString( ). |
ValueMember | String | Read/write. Define a propriedade da fonte de dados retornada pela propriedade SelectedValue. Pode ser anulada atribuindo uma string vazia ou uma referencia Null. |
SelectedIndex | Integer | Read/write. O indice baseado no valor inicial zero do item atualmente selecionado. O valor -1 indica que nenhum item esta selecionado. |
Estas propriedades incluem a propriedade DataSource e muitas propriedades úteis . Nas tabelas a seguir temos as propriedades/métodos que não são membros da classe ListControl mas são membros para todos os três controles derivados desta classe. Elas incluem propriedades para definir a aparência do controle e propriedades relacionadas com a coleção de itens dos controles.
Propriedades comum a todos os controles de lista
Propriedade | tipo | Descrição |
---|---|---|
IntegralHeight | Boolean | Read/write. Se True (o padrão) o controle se redimensiona para evitar mostrar itens parciais. |
DrawMode | DrawMode | Read/write.
Define o modo de desenho para o controle. Os valores válidos são: - DrawMode.Normal (padrão), DrawMode.OwnerDrawFixed, and DrawMode.OwnerDrawVariable. |
ItemHeight | Integer | Read/write. Altura de um item no controle em pixels. |
Items | ObjectCollection | Read-only. Coleção de itens no controle. |
PreferredHeight | Integer | Read-only. A altura de todos os itens no controle em pixels. Esta é a altura que o controle precisa para exibir todos os itens se efetuar uma rolagem vertical. |
SelectedItem | Object | Read/write. O item atualmente selecionado no controle. |
Sorted | Boolean | Read/write. Se false (o padrão), os itens no controle não estão ordenados e novos itens são incluídos no final da lista. De outra forma eles são ordenados em ordem crescente , em ordem alfabética , e case-insensitive. Se True , o indice de um item especifico pode ser alterado conforme novos itens forem sendo incluídos. |
Text | String | Read/write. O texto associado ao item atualmente selecionado. |
Métodos comum a todos os controles de lista
Método | Descrição |
---|---|
BeginUpdate | Evita o redesenho do controle enquanto itens são incluídos na coleção de itens. |
EndUpdate | Recupera o desenho do controle depois que BeginUpdate foi invocado. |
FindString | Overloaded. Retorna um índice baseado em zero do primeiro item na coleção de itens que inicia com uma string definida. |
FindStringExact | Overloaded. Retorna um índice baseado em zero do primeiro item da coleção deitens que coincide exatamente com a string definida |
Preenchendo um Controle de Lista
Vamos então ao que interessa.
Há duas maneiras de preencher os controles de lista:
A propriedade Items representa uma coleção de objetos contidos em uma lista ; como toda a coleção de objetos , ela implementa as interfaces IList, ICollection e IEnumerable e fornece métodos para inclui , excluir e manipular a coleção. Abaixo temos os métodos mais usados para isto:
Métodos mais comuns usados em ObjectCollection
Método | Descrição |
---|---|
Add | Inclui um novo objeto a coleção de itens atual. Retorna um índice baseado em zero de um item na coleção. |
AddRange | Inclui um array de objetos na coleção |
Clear | Remove todos os itens de uma coleção. |
Contains | Retorna true se o objeto especificado é encontrado na coleção. |
CopyTo | Copie a coleção completa para um objeto array definido iniciando no índice especificado. |
IndexOf | Retorna um índice baseado em zero de um objeto definido dentro da coleção. Se o objeto não for encontrado retorna -1. |
Insert | Insere um objeto em uma coleção de um índice definido. Se o If the Sorted property is true, the index is ignored. |
Remove | Remove o objeto especificado da coleção.Todos os objetos se movem uma posição. |
RemoveAt | Remove o objeto da coleção na posição definida pelo índice.Todos os objetos se movem uma posição. |
Se olharmos as tabelas veremos que a coleção Items é do tipo ObjectCollection , acima temos os métodos mais usados de ObjectCollection.
Note porem que não existe uma classe ObjectCollection. Cada um dos controles derivados da classe ListControl possui a sua própria classe ObjectCollection: ObjectCollection, CheckedListBox.ObjectCollection, e ComboBox.ObjectCollection. Porém todas as 3 classes contém essencialmente os mesmos métodos com algumas exceções que veremos a seguir.
Além disto a classe ObjectCollection possui a propriedade de somente-leitura Count que retorna o número de itens na coleção e a propriedade Item de leitura/escrita que é um indexador dentro da coleção. Vamos falar delas logo , logo...
Quando você usa o IDE do VS.NET , strings podem ser incluídas em uma coleção de itens em tempo de desenho usando o Editor de Strings para Coleções. O acesso é feito quando você clica no botão com três pontos(...) perto da propriedade Items na janela Property. A seguir basta digitar a relação de strings e clicar no botão OK.
O editor utiliza o método AddRange para incluir strings para a coleção items. O código que faz isto reside no método InitializeComponente gerado pelo VS.NET.
A segunda maneira de preencher um controle de lista é vincular o controle a uma fonte de dados usando a propriedade DataSource. A fonte de dados pode ser qualquer objeto que implementa a interface IList. Esta interface representa uma coleção de objetos que são individualmente acessados via index:
A propriedade DataSource vincula os dados na fonte de dados do controle. Geralmente um DataSource possui um ou mais membros , tais como DataColumns em um DataTable.
Vamos supor que você tem um banco de dados que contém todos os estados do país. Suponha que esta tabela possua duas colunas : UF e Nome do estado. Você gostaria de exibir o nome do estado no controle de lista , mas gostaria de passar a abreviação para o programa que esta acessando o controle. O código que faz este serviço é o seguinte :
' Cria uma conexão e um comando Dim conStr As String = "Provider=Microsoft.JET.OLEDB.4.0;data source=d:\teste\northwind.mdb" Dim sqlStr As String = "SELECT * from estados" ' Cria um objeto connection Dim conn As OleDbConnection = New OleDbConnection(conStr) ' Cria o objeto dataadapter Dim da As OleDbDataAdapter = New OleDbDataAdapter(sqlStr, conn) ' Cria o dataset e preenche com os dados do datadapter Dim ds As DataSet = New DataSet da.Fill(ds, "estados") ' vincula o DefaultView do dataset ao controle Dim dv As DataView = ds.Tables("estados").DefaultView lb.DataSource = dv lb.DisplayMember = "NomeEstado" lb.ValueMember = "UF" lb.SelectedIndex = 0 conn.Close() |
O código acima apenas faz a conexão com a fonte de dados e exibe os dados em um controle ListBox. Para extrair o valor do membro do controle para processamento podemos usar o evento SelectedValueChanged :
Dim strEstado As String If lb.SelectedIndex <> -1 Then strEstado = CType(lb.SelectedItem, DataRowView)("NomeEstado").ToString() lblselecao.Text = " Selecionou : " & strEstado End If |
Você dever realizar um cast (conversao forçada) a propriedade SelectedValue para um tipo correto (neste caso um string) pois a propriedade é herdada de um tipo objeto, como cada item da coleção Items.
Abaixo temos o código onde um controle ListBox é preenchido a partir de um tabela sem usar a propriedade DataSource . Ao invés disto fazemos uma iteração na tabela e o método add da classe Items é chamado para cada registro.
Dim connectionString As String connectionString = "Provider=Microsoft.JET.OLEDB.4.0;data source=d:\teste\northwind.mdb" Dim commandString As String commandString = "Select * from estados" Dim da As New OleDbDataAdapter(commandString, connectionString) Dim ds As New DataSet da.Fill(ds, "estados") Dim dt As DataTable dt = ds.Tables(0) Dim linha As DataRow For Each linha In dt.Rows lb.Items.Add(linha("UF") & ": " & linha("NomeEstado")) Next |
Esta técnica oferece dois benefícios sobre o databinding. O Primeiro é que muito conveniente exibir a concatenação de um ou mais campos como um string texto. O segundo deriva do fato de que se a propriedade DataSource é usada, então a coleção Items da lista não pode ser modificada.
Esta técnica evita que seja possível modificar os itens da coleção. Porém você perde a habilidade de exibir um valor na lista representado pela propriedade DisplayMember e retornar um valor diferente para processamento posterior representado pela propriedade ValueMember.
Você pode usar a propriedade DataSource e a vinculação de dados e alem disto preservar o uso das propriedades DisplayMember e ValueMember enquanto ainda estiver concatenando os campos e o texto. Vejamos um exemplo onde iremos retornar o nome do Estado e a UF da tabela estados de um banco de dados northwind.mdb.(Criei esta tabela no banco de dados para o artigo)
Dim connectionString As String connectionString = "Provider=Microsoft.JET.OLEDB.4.0;data source=d:\teste\northwind.mdb" Dim commandString As String commandString = "Select * from estados" Dim da As New OleDbDataAdapter(commandString, connectionString) Dim ds As New DataSet da.Fill(ds, "estados") Dim dt As DataTable dt = ds.Tables(0) ' vincula o controle a tabela lb.DataSource= dt; lb.DisplayMember = "NomeEstado"; lb.ValueMember = "UF"; |
A consulta SQL contida na string de comando retorna a coluna código mais a concatenação do primeiro nome com o sobrenome separados por uma virgula que formam o campo nome.
Logo depois de definir a propriedade DataSource , a propriedade DisplayMember é definida para membro NomeEstado e a propriedade ValueMember é definida para o membro UF. O resultado obtido pode ser exibido em um ListBox.
O código do evento Click do botão de comando é exibido abaixo. Se houver uma seleção no ListBox, sua propriedade SelectionMode é definida para o valor One:
If lb.SelectedIndex <> -1 Then Dim s As String = CType(lb.SelectedItem, DataRowView)("NomeEstado").ToString() MessageBox.Show("Valor : " + lb.SelectedValue.ToString() + vbCrLf + "Exibir : " + s) Else MessageBox.Show("Nada selecionado") End If |
O resultado da caixa de mensagem é mostrado abaixo:
No exemplo a propriedade SelectedValue e o método ToString mostra o membro especificado pela propriedade ValueMember porém exibe o membro definido pela propriedade DisplayMember . Você poderia substituir o argumento do MessageBox com o seguinte codigo:
MessageBox.Show("Valor : " + lb.SelectedValue.ToString( ) + vbCrLf + "Exibir :" + lb.SelectedItem.ToString( ))
Ao fazer isto o resultado será o exibido abaixo. Este resultado evidencia que os itens na coleção Items são objetos e neste caso objetos do tipo DataRowView.
Você poderia esperar que os itens na coleção Items deste exemplo fossem objetos DataRow , desde que a propriedade DataSource é um DataTable porém sempre que um dado é exibido em um formulário Windows Forms ele é exibido como um objeto DataRowView.
Por causa disto o código realiza um cast no SelectedItem para um objeto DataRowView e chama o método ToString para convertê-lo para uma string para exibir no MessageBox.
Isto funciona bem , exceto por dois efeitos colaterais : isto requer que você informe o nome do membro e , se o ListBox fosse definido como sendo multiselected ele irá exibir somente o primeiro elemento selecionado.
Para tratar um multi-seleção no controle devemos usar o seguinte código:
Dim strMsg As String = "" If lb.SelectedIndex <> -1 Then Dim item As Object For Each item In lb.SelectedItems Dim s1 As String = CType(item, DataRowView)(lb.ValueMember).ToString() Dim s2 As String = CType(item, DataRowView)(lb.DisplayMember).ToString() trMsg += "Valor : " + s1 + vbCrLf + "Exibir : " + s2 + vbCrLf + vbCrLf Next MessageBox.Show(strMsg) Else MessageBox.Show("Nada selecionado") End If |
A solução do código acima realiza uma iteração através da coleção SelectedItems, construindo uma string para exibir no controle MessageBox. O nome dos membros não estão incluídos fixos no código , mas as propriedades ValueMember e DisplayMember são usadas diretamente para inspecionar o interior dos objetos DataRowVIew. O resultado será os itens selecionados exibidos.
Os exemplos acima mostram diferentes formas de retornar o texto associado com um item na coleção Items usando as propriedades SeletecdItem, SelectedItems e SelectedValue. A classe ListControl fornece também o método GetItemText que simplifica esta tarefa pois toma um item objeto como um argumento e retorna uma string.
Usando o método GetItem , você pode reescrever e consolidar os exemplos acima :
Dim strMsg As String = "" If lb.SelectedIndex <> -1 Then ' para seleção simples no listbox MessageBox.Show("Item Texto : " + lb.GetItemText(lb.SelectedItem)) ' para seleção múltiplas no listbox Dim item As Object For Each item In lb.SelectedItems Dim s1 As String = CType(item, DataRowView)(lb.ValueMember).ToString() Dim s2 As String = CType(item, DataRowView)(lb.DisplayMember).ToString() Dim s3 As String = lb.GetItemText(item) strMsg += "Valor: " + s1 + vbCrLf + "Exibe : " + s2 + vbCrLf + "Item texto : " + s3 + vbCrLf + vbCrLf Next MessageBox.Show(strMsg) Else MessageBox.Show("Nada Selecinado") End If
|
Finalmente existe um outra forma ainda simples de retornar e exibir um item. A propriedade Text da classe derivada de LisControl sobre-escreve a propriedade Text do controle Base.
A propriedade Text dos controles ListBox, CheckedListBox, and ComboBox reflete não a string associada com o próprio controle , mas o item atualmente selecionado. . No caso de controles que suportam multi selecao (ListBox and CheckedListBox) ele corresponde ao texto do primeiro item selecionado.
Para exibir o valor de um simples item selecionado usamos o seguinte código:
MessageBox.Show("Text: " + lb.Text)
Creio que deu para você ter uma visão panorâmica dos controles de lista e obter os conceitos básicos para saber usá-los em suas aplicações .NET.
Arriverdeci !!!
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET