WPF - Preenchendo uma Combobox
Neste tutorial vou mostrar como preencher um controle Combobox do WPF - Windows Presentation Foundation usando o Visual Studio 2010 Beta 2.
Vou iniciar falando um pouco sobre o controle Combobox da WPF e suas características.
Exibindo itens (texto) em um Combobox
Eu estou usando o Visual Studio 2010 beta 2 nos exemplos citados neste artigo.
Selecione o menu File ->New Project e crie uma nova aplicação do Tipo WPF Application com o nome wpf_Combobox;
O controle ComboBox é muito parecido com o controle ListBox e é muito fácil de usar. No código abaixo estamos usando um controle ComboBox em um controle StackPanel;
Defina o código abaixo no arquivo MainWindow.xaml e observe o resultado da execução do projeto na figura ao lado;
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Preenchendo uma Combobox" Height="286" Width="322"> <Grid> <StackPanel> <ComboBox> <ComboBoxItem>Item 1</ComboBoxItem> <ComboBoxItem>Item 2</ComboBoxItem> <ComboBoxItem>Item 3</ComboBoxItem> <ComboBoxItem>Item 4</ComboBoxItem> <ComboBoxItem>Item 5</ComboBoxItem> </ComboBox> </StackPanel> </Grid> </Window> |
Usando a linguagem XAML declaramos um controle ComboBox usando a tag <ComboBox> e definimos seus itens pela tag <ComboBoxItem>.
O controle ComboBox da WPF permite também tratarmos com elementos complexos como imagens e texto. Vejamos como exibir esses itens...
Exibindo itens com texto e imagem em um Combobox
No menu Project ->Add Window aceite o nome padrão window1.xaml e defina o código abaixo no arquivo window1.xaml;
Nota: Para abrir a janela desejada como janela inicial do projeto clique sobre My Project na janela Solution Explorer e defina o nome da janela no item Startup URI;
<Window x:Class="Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="395" Width="438"> <Grid> <ComboBox Margin="0,0,12,317"> <ComboBoxItem> <StackPanel Orientation="Horizontal"> <TextBlock Width="50">Alegre</TextBlock> <Image Source="C:\dados\alegre.jpg" Height="50" /> </StackPanel> </ComboBoxItem> <ComboBoxItem> <StackPanel Orientation="Horizontal"> <TextBlock Width="50">Elvis</TextBlock> <Image Source="C:\dados\elvis.jpg" Height="50" /> </StackPanel> </ComboBoxItem> <ComboBoxItem> <StackPanel Orientation="Horizontal"> <TextBlock Width="50">Mike</TextBlock> <Image Source="C:\dados\mike.jpg" Height="50" /> </StackPanel> </ComboBoxItem> </ComboBox> </Grid> </Window> |
Note que estamos usando a combobox para exibir itens com nome e imagem; Fizemos isso usando a tag ComboBoxItem e definindo o texto e a imagem em seu interior.
Vejamos agora como tratar as informações obtidas de um ComboBox como um item selecionado.
Obtendo o item selecionado de um ComboBox
Uma das formas de fazer isso é converter o item selecionado para um item da Combobox e então obter o seu conteúdo para exibi-lo;
No menu Project ->Add Window aceite o nome padrão window2.xaml e defina o código abaixo no arquivo window2.xaml;
Vamos usar uma combobox com os mesmos itens do exemplo anterior. Inclua o código a seguir entre as tags <Grid> no arquivo XAML;
<StackPanel> <ComboBox Name=mComboBox > <ComboBox Margin="0,0,12,317"> <ComboBoxItem> <StackPanel Orientation="Horizontal"> <TextBlock Width="50">Alegre</TextBlock> <Image Source="C:\dados\alegre.jpg" Height="50" /> </StackPanel> </ComboBoxItem> <ComboBoxItem> <StackPanel Orientation="Horizontal"> <TextBlock Width="50">Elvis</TextBlock> <Image Source="C:\dados\elvis.jpg" Height="50" /> </StackPanel> </ComboBoxItem> <ComboBoxItem> <StackPanel Orientation="Horizontal"> <TextBlock Width="50">Mike</TextBlock> <Image Source="C:\dados\mike.jpg" Height="50" /> </StackPanel> </ComboBoxItem> </ComboBox> </ComboBox> <Button Name=mButton Content=OK Click=mButton_Click /> </StackPanel> |
Primeiro incluímos um controle ComboBox chamado mComboBox, de forma que podemos identificá-lo e usá-lo no código.
Em seguida incluímos um controle Button (mButton) usado para exibir o que foi selecionado;
A seguir para o exemplo funcionar temos que incluir o código a seguir no evento Click do controle Button:
Private Sub mButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Dim cbi As ComboBoxItem = TryCast(mComboBox.SelectedItem, ComboBoxItem) If cbi IsNot Nothing Then Dim sp As StackPanel = TryCast(cbi.Content, StackPanel) Dim bloco As TextBlock = TryCast(sp.Children(0), TextBlock) MessageBox.Show("Você selecionou " & bloco.Text) Else MessageBox.Show("Na selecionado ainda") End If End Sub |
Executando o projeto e selecionando um item após clicar no botão de comando Ok iremos obter:
Vamos entender o código usado:
- Primeiro obtivemos o item atual da ComboBox
e armazenei-o na variável cbi;
- Então verifiquei se ele era válido (nothing) (seria
o caso do cliente não ter selecionado nada ainda);
- Se fosse inválido (nothing) exibiria a mensagem de
item não selecionado;
- Como o conteúdo dos itens da combobox estão na tag
ComboBoxItem e são controles StackPanel, foi preciso obter uma
referência deles na variável sp;
- A seguir podemos iterar com o filho de um StackPanel, mas como
eu conheço o TextBlock eu obtenho o primeiro filho e
referencio-o diretamente como elemento zero e retorno na
variável de bloco;
- Finalmente obtemos o texto atual da linha que o usuário
selecionou;
Vejamos agora como obter informações de uma fonte de dados e exibi-las em um ComboBox.
Exibindo informações de uma fonte de dados em um ComboBox
No menu Project ->Add Window aceite o nome padrão window3.xaml e defina o código abaixo no arquivo window3.xaml;
A partir da ToolBox inclua um elemento Combobox no descritor WPF e em seguida ajuste o seu código no arquivo XAML;
O código no arquivo window3.xaml deverá ser o seguinte:
<Window x:Class="Window3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window3" Height="300" Width="300"> <Grid> <ComboBox Margin="35,32,25,0" Name="comboBox1" ItemsSource="{Binding}" VerticalAlignment="Top" Height="31"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding ProductName}" Width="100" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </Grid> </Window> |
No código acima usamos um DataTemplate. Um DataTemplate é um recurso do WPF que permite uma grande flexibilidade para definir a apresentação de dados vinculados, dessa forma os Data templates permitem customizar a aparência de um controle.
No arquivo code-behind Window3.xaml.vb vamos incluir o código que faz o acesso ao banco de dados Northwind.mdb do Microsoft Access e obtém os dados da tabela Products para em seguida preencher o Combobox;
Inclua o código abaixo no evento Window3_Loaded:
Imports System.Data Imports System.Data.OleDb Public Class Window3 Private Sub Window3_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded Try 'cria um DataTabale Dim dt As New DataTable() 'define a string de conexão com o MSAccess Dim strConn As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\dados\Northwind.mdb;" 'Abre a conexão Dim conn As New OleDbConnection(strConn) 'cria um DataAdapter selecionando os dados de um tabela do MSAccess Dim da As New OleDbDataAdapter("Select ProductID, ProductName from Products", conn) 'preenche o DataTable da.Fill(dt) 'exibe os dados no DataGridView comboBox1.DataContext = dt.DefaultView Catch ex As Exception MessageBox.Show("Erro : " & ex.Message) End Try End Sub End Class |
Abaixo vemos o resultado da execução
Se você quiser exibir o código do produto e o nome na combobox como em duas colunas basta alterar a definição no arquivo XAML incluindo a informação que deseja exibir, no caso ProductID;
No exemplo eu inclui um outro controle ComboBox (ComboBox2) e inclui o código do produto(ProductID) como um item a ser exibido:
<Window x:Class="Window3" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window3" Height="300" Width="300"> <Grid> <ComboBox Margin="35,32,25,0" Name="comboBox1" ItemsSource="{Binding}" VerticalAlignment="Top" Height="31"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding ProductName}" Width="100" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <ComboBox Height="36" Margin="35,88,0,0" Name="ComboBox2" ItemsSource="{Binding}" VerticalAlignment="Top" Width="218"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding ProductID}" Width="70" /> <TextBlock Text="{Binding ProductName}" Width="100" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> </Grid> </Window> |
A seguir basta atribuir ao segundo combobox(ComboBox2) a tabela obtida do banco de dados no código do arquivo code-behind:
ComboBox2.DataContext = dt.DefaultView |
Executando o projeto após estas alterações teremos:
Se deseja usar o Northwind.mdf do SQL Server 2005/2008 usando um dataset pode usar o código abaixo:
Private Sub window3_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded Dim ds As New DataSet() Dim strConn As String = "Server = .\sqlexpress;Database = NorthWind; Integrated Security = SSPI;" Dim con As New SqlConnection(strConn) Dim cmd As New SqlCommand("select ProductID,ProductName from Products", con) Dim sqlDa As New SqlDataAdapter() sqlDa.SelectCommand = cmd sqlDa.Fill(ds) ComboBox1.DataContext = ds.Tables(0).DefaultView End Sub |
Pegue o projeto completo aqui: wpf_ComboBox.zip(Lembre-se que você precisa do VS2010 beta 2 para abrir o projeto)
Eu sei é apenas WPF , mas eu gosto...
Referências: