Curso Windows Phone – Como preencher e identificar os itens selecionados em um ListBox

Olá pessoal, tudo bom?

Nesse post demonstro como preencher e também identificar quais itens foram selecionados em um determinado ListBox. Adianto que há várias formas de se popular um ListBox e neste post estou utilizando apenas uma delas. 🙂

Tela de exemplo da APP desenvolvida para este post
Tela de exemplo da APP desenvolvida para este post

Para popular o ListBox criei uma classe hipotética para representar sabores de Pizza (dados fixos mas poderiam vir do BD, XML ou mesmo WebService) e coloquei alguns valores de tal forma que eu tenha uma lista de sabores representada por um objeto List<Sabor>. Vejamos:

Classe Sabor (arquivo Sabor.cs)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PhoneApp1
{
  public class Sabor
  {
    private int _codigo;
    public int Codigo
    {
      get { return _codigo; }
      set { _codigo = value; }
    }

    private string _nome;
    public string Nome
    {
      get { return _nome; }
      set { _nome = value; }
    }

    private string _ingredientes;
    public string Ingredientes
    {
      get { return _ingredientes; }
      set { _ingredientes = value; }
    }

    private bool _selecionado;
    public bool Selecionado
    {
      get { return _selecionado; }
      set { _selecionado = value; }
    }
  }
}

Abaixo temos o código desenvolvido em XAML para representação dos dados de nossa APP de exemplo:

Interface (arquivo MainPage.xaml)


&lt;phone:PhoneApplicationPage
 x:Class=&quot;PhoneApp1.MainPage&quot;
 xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
 xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
 xmlns:phone=&quot;clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone&quot;
 xmlns:shell=&quot;clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone&quot;
 xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
 xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
 mc:Ignorable=&quot;d&quot;
 FontFamily=&quot;{StaticResource PhoneFontFamilyNormal}&quot;
 FontSize=&quot;{StaticResource PhoneFontSizeNormal}&quot;
 Foreground=&quot;{StaticResource PhoneForegroundBrush}&quot;
 SupportedOrientations=&quot;Portrait&quot; Orientation=&quot;Portrait&quot;
 shell:SystemTray.IsVisible=&quot;True&quot;&gt;

 &lt;!--LayoutRoot is the root grid where all page content is placed--&gt;
 &lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;Transparent&quot;&gt;
   &lt;Grid.RowDefinitions&gt;
     &lt;RowDefinition Height=&quot;Auto&quot;/&gt;
     &lt;RowDefinition Height=&quot;*&quot;/&gt;
   &lt;/Grid.RowDefinitions&gt;

   &lt;!--TitlePanel contains the name of the application and page title--&gt;
   &lt;StackPanel x:Name=&quot;TitlePanel&quot; Grid.Row=&quot;0&quot; Margin=&quot;12,17,0,28&quot;&gt;
     &lt;TextBlock Text=&quot;BLOG DO EDUARDO H. RIZO&quot; Style=&quot;{StaticResource PhoneTextNormalStyle}&quot; Margin=&quot;12,0&quot;/&gt;
     &lt;TextBlock Text=&quot;listbox itens&quot; Margin=&quot;9,-7,0,0&quot; Style=&quot;{StaticResource PhoneTextTitle1Style}&quot;/&gt;
   &lt;/StackPanel&gt;

   &lt;!--ContentPanel - place additional content here--&gt;
     &lt;StackPanel x:Name=&quot;ContentPanel&quot; Grid.Row=&quot;1&quot; Margin=&quot;12,0,12,0&quot;&gt;
       &lt;ListBox Name=&quot;lbSabores&quot; Height=&quot;540&quot; &gt;
         &lt;ListBox.ItemTemplate&gt;
           &lt;DataTemplate&gt;
             &lt;StackPanel&gt;
               &lt;CheckBox Height=&quot;Auto&quot;
                         Checked=&quot;CheckBox_Checked&quot;
                         Unchecked=&quot;CheckBox_Unchecked&quot;
                         Content=&quot;{Binding Nome}&quot;
                         IsChecked=&quot;{Binding Selecionado}&quot; /&gt;
               &lt;TextBlock Height=&quot;Auto&quot;
                          Text=&quot;{Binding Ingredientes}&quot; /&gt;
             &lt;/StackPanel&gt;
           &lt;/DataTemplate&gt;
         &lt;/ListBox.ItemTemplate&gt;
       &lt;/ListBox&gt;
       &lt;Button Name=&quot;btnOK&quot; Content=&quot;Itens selecionados&quot; Click=&quot;btnOK_Click&quot; /&gt;
     &lt;/StackPanel&gt;
   &lt;/Grid&gt;
&lt;/phone:PhoneApplicationPage&gt;

Finalmente o código necessário para manipulação dos dados na interface. Veja a codificação abaixo:

Manipulação da interface (arquivo MainPage.xaml.cs)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PhoneApp1.Resources;

namespace PhoneApp1
{
  public partial class MainPage : PhoneApplicationPage
  {
     private List&lt;Sabor&gt; Sabores;

     public MainPage()
     {
       InitializeComponent();
       //Método para popular o ListBox
       Preencher();
     }

     protected void Preencher()
     {
       Sabores = new List&lt;Sabor&gt;();
       Sabores.Add(new Sabor { Codigo = 1, Nome = &quot;Napolitana&quot;, Ingredientes = &quot;Ingrediente 1, Ingrediente 2, Ingrediente 3&quot;, Selecionado = false });
       Sabores.Add(new Sabor { Codigo = 2, Nome = &quot;Portuguesa&quot;, Ingredientes = &quot;Ingrediente 1, Ingrediente 2, Ingrediente 3&quot;, Selecionado = false });
       Sabores.Add(new Sabor { Codigo = 3, Nome = &quot;Beringela&quot;, Ingredientes = &quot;Ingrediente 1, Ingrediente 2, Ingrediente 3&quot;, Selecionado = false });
       Sabores.Add(new Sabor { Codigo = 4, Nome = &quot;4 queijos&quot;, Ingredientes = &quot;Ingrediente 1, Ingrediente 2, Ingrediente 3&quot;, Selecionado = false });
       Sabores.Add(new Sabor { Codigo = 5, Nome = &quot;Calabresa&quot;, Ingredientes = &quot;Ingrediente 1, Ingrediente 2, Ingrediente 3&quot;, Selecionado = false });
       Sabores.Add(new Sabor { Codigo = 6, Nome = &quot;California&quot;, Ingredientes = &quot;Ingrediente 1, Ingrediente 2, Ingrediente 3&quot;, Selecionado = false });

       lbSabores.ItemsSource = Sabores;
     }

     private void CheckBox_Checked(object sender, RoutedEventArgs e)
     {
       var check = sender as CheckBox;
       if (check != null)
       {
         Sabor s = check.DataContext as Sabor;
         s.Selecionado = true;
       }
     }

     private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
     {
       var check = sender as CheckBox;
       if (check != null)
       {
         Sabor s = check.DataContext as Sabor;
         s.Selecionado = false;
       }
    }

    private void btnOK_Click(object sender, RoutedEventArgs e)
    {
      string selecao = &quot;&quot;;
      foreach (Sabor s in Sabores)
      {
        selecao += s.Selecionado ? s.Nome + &quot; - &quot; : &quot;&quot;;
      }
      MessageBox.Show(selecao);
    }
  }
}

Espero ter ajudado!

Post Relacionado: 

Grande abraço,
Eduardo Henrique Rizo

[twitter-follow screen_name=’eduardorizo’ show_count=’yes’]

45 comentários em “Curso Windows Phone – Como preencher e identificar os itens selecionados em um ListBox”

  1. Pingback: Free: Curso Windows Phone – Vários tópicos | Blog do Eduardo H. Rizo

  2. Pingback: [Desenvolvimento] Como preencher e identificar os itens selecionados em um ListBox - Windows Phone Brasil

  3. Pingback: Curso Windows Phone: Exemplo de binding usando Listbox | Blog do Eduardo H. Rizo

  4. Pingback: [Desenvolvimento] Exemplo de binding usando Listbox - Windows Phone Brasil

    1.             if (radioButtonResp1.IsChecked == false && radioButtonResp2.IsChecked == false
                   && radioButtonResp3.IsChecked == false && radioButtonResp4.IsChecked == false)
                  {
                      MessageBox.Show("Olá");
                  ------->>>>>  exit;
                  }
      
                  if (radioButtonResp1.IsChecked == true)
                  {
      
                  }
      
                  if (radioButtonResp2.IsChecked == true)
                  {
      
                  }
      
                  if (radioButtonResp3.IsChecked == true)
                  {
      
                  }
      
                  if (radioButtonResp4.IsChecked == true)
                  {
      
                  }
      

      Pelo código ai aonde tem a seta como seria no C# ? um exit tipo no delphi isto serviria para eu sair já procedimento ou seja neste exemplo não seria verificado os radiobutton

      Até mais.

  5. Eu estou precisando que fique Selecionado Somente um sabor
    Como seria ?

    Eu tentei aqui mas não funcionou

    lbSabores.SelectedIndex = -1;
    

    Obrigado desde já

    1. Olá Ewerton, tudo bom?
      Basta que você troque o elemento CheckBox por um RadioButton definindo a propriedade GroupName para que os mesmos se tornem exclusivos, ou seja, a seleção de um item desmarca os outros e assim por diante.
      Veja o exemplo abaixo:

      <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
             <ListBox Name="lbSabores" Height="540" >
               <ListBox.ItemTemplate>
                 <DataTemplate>
                   <StackPanel>
                     <RadioButton GroupName="items" Height="Auto" .... />
                     <TextBlock Height="Auto"
                                Text="{Binding Ingredientes}" />
                   </StackPanel>
                 </DataTemplate>
               </ListBox.ItemTemplate>
             </ListBox>
             <Button Name="btnOK" Content="Itens selecionados" Click="btnOK_Click" />
      </StackPanel>
      

      Abraços,
      Eduardo

      1. Muito obrigado,
        Mas que bobeira minha a resposta foi simples, eu queria por que queria que o listbox fosse usado que não pensei em outro componente (controle)
        É que comecei estes dias mas valeu.

        To lendo muito as suas postagens, continue postando assunto relacionados com WP para nós.

      2.             string selecao = "";
                    foreach (Sabor s in Sabores)
                    {
                        if (s.Selecionado == true)
                        {
                        selecao = s.Ingredientes;
                        }
                    }
                    MessageBox.Show(selecao);
        

        Eu tentei fazer como visto acima.
        Mas não deu o resultado esperado!
        Como eu faria para percorrer os radiobutton e ver qual foi marcado ?
        Neste pegar o s.selecionado ou s.nome ou s.codigo

        Eu sei que o radio button tem como fazer assim;

        if (rdbMasculino.IsChecked.Value)
            {
                sexo = "Masculino";
            }
            else
            {
                sexo = "Feminino";
            }
        

        E se não for pedir muito teria um código genérico que serviria para qualquer controle ?

        Mas acho que eu estou fazendo muito errado eu teria de trocar

        private List Sabores;

        Por outro código ?

        Grato desde já.

      3. Ewerton, acho que você está errando apenas a forma de enviar os valores para a variável selecao. Do jeito como está no seu código a variável selecao sempre terá apenas o último valor selecionado e isso está acontecendo porque você não está concatenando os valores…

        Procure fazer assim:

        ...
        ...
            if (s.Selecionado == true)
               selecao += s.Ingredientes;
        ...
        ...
        

        Repare que coloquei o operador += para que a variável selecao possa ir acumulando os valores dos selecionados.

  6. iii acho que comentei no lugar errado!

    if (radioButtonResp1.IsChecked == false && radioButtonResp2.IsChecked == false
     && radioButtonResp3.IsChecked == false && radioButtonResp4.IsChecked == false)
    {
        MessageBox.Show("Olá");
    ------->>>>>  exit;
    }
    
    if (radioButtonResp1.IsChecked == true)
    {
    
    }
    
    if (radioButtonResp2.IsChecked == true)
    {
    
    }
    
    if (radioButtonResp3.IsChecked == true)
    {
    
    }
    
    if (radioButtonResp4.IsChecked == true)
    {
    
    }
    

    Pelo código ai aonde tem a seta como seria no C# ? um exit tipo no delphi isto serviria para eu sair já procedimento ou seja neste exemplo não seria verificado os radiobutton

    desculpe pela comentário lá em cima

      1. uhn valeu no C# então é break;

        Pois pelo menos no Delphi o Exit; é uma mão na roda ajuda bastante
        E com certeza o break irá me ajudar no C#

        Valeu

      1. Valeu
        Eu testei aqui
        Vou usar ele aqui também, acho que este funciona igual ao exit do delphi pois o break só funciona no while e for correto ?

  7. Com a XAML. Quando eu adiciono um CheckBox o código dele fica abaixo do código da list box. Tentei recortar e colar para ficar igual seu código XAML mas não deu certo. Como devo fazer?

    1. Priscila, você deve observar se o seu container de objetos é um StackPanel ou Grid. No meu exemplo usei um StackPanel.
      Outra coisa a verificar é a orientação do StackPanel que está agrupando os objetos que você está usando está na vertical ou horizontal.
      Também repare que o próprio componente CheckBox possui Content que determina o texto a ficar na frente do mesmo. OK?

      []s
      Eduardo

  8. Bom dia Eduardo.

    Primeiramente gostaria de agradecer, e muito, pela ajuda. Como deu pra perceber estou começando a desenvolver pra WP agora, por isso estou com muitas dúvidas ainda.

    Voltando ao programa… realmente o container estava como grid. Todas as outras interfaces que criei eram como grid e na verdade eu nunca usei StackPanel. Tentei aqui adicionar um StackPanel do toolbox, coloquei um Listbox nele, mas novamente não consegui colocar o CheckBox dentro do ListBox.

    1. Olá Priscila, com certeza você ainda deve estar tendo algum problema com os containers e seus alinhamentos.
      Como você disse que é iniciante, sugiro fazer dois cursos sobre Windows Phone que estão disponíveis gratuitamente no MVA – Microsoft Virtual Academy. Experimente acessar http://aka.ms/mva e faça os cursos sobre Windows Phone.

      PS: Os cursos estão em português.

      Grande abraço,
      Eduardo

  9. Segui teu tutorial (muito bom por sinal), mas ocorre erro no debugar a aplicação!

    O debug é interrompido em Debugger.Break(); da App.xaml.cs e nao apresenta uma Exception util.

    Notei que, removendo {Binding xxx}, a aplicação executa sem problemas.

    Como poderia resolver isso?

    Att

    1. Boa tarde Fabrício, tudo bom?
      Bem se quando você tira o Binding a coisa funciona, então de repente você pode ter algum problema com a fonte de dados, mas é difícil afirmar sem ver o erro que está ocorrendo.
      Tente pegar alguma informações da mensagem de erro e post aqui para que nós possamos tentar ajudar.

      []s
      Eduardo

      1. Bom, esta é minha Lista:

        ListaEditais = new List();
        ListaEditais.Add(new Editais { Codigo = 1, Nome = “Edital 1”, Url = “http://www.google.com.br”, Data = “1/1/2014” });
        ListaEditais.Add(new Editais { Codigo = 2, Nome = “Edital 2”, Url = “http://www.terra.com.br”, Data = “2/2/2014” });

        e este o meu XAML:

        No debug, ele passa corretamente pelo metodo MainPage, mas ao abrir a aplicação no emulador, ela se fecha e para no Debugger.Break(); da App.xaml.cs como tinha dito, e a exception é esta:

        Object reference not set to an instance of an object.

        Ou seja, nada especifico =/

        e se eu qualquer textp no lugar dos {Binding, funciona corretamente!

      2. Pelo que me parece o programa está tentando fazer binding em algum objeto que ainda não existe.
        Você está criando essa lista de editais em qual evento?

        Se puder mande a parte XAML do teu código tbm.

        []s
        Eduardo

  10. Como você fez, tenho uma lista global:

    private List ListaEditais;

    e no metodo public MainPage()
    {

    eu populo a lista:

    ListaEditais = new List();
    ListaEditais.Add(new Editais { Codigo = 1, Nome = “Edital 1″, Url = “http://www.google.com.br”, Data = “1/1/2014″ });
    ListaEditais.Add(new Editais { Codigo = 2, Nome = “Edital 2″, Url = “http://www.terra.com.br”, Data = “2/2/2014″ });

    onde editais é uma classe publica:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace appProjec
    {
    public class Editais
    {
    private int _codigo;
    public int Codigo
    {
    get { return _codigo; }
    set { _codigo = value; }
    }

    private string _nome;
    public string Nome
    {
    get { return _nome; }
    set { _nome = value; }
    }

    private string _url;
    public string Url
    {
    get { return _url; }
    set { _url = value; }
    }

    private string _data;
    public string Data
    {
    get { return _data; }
    set { _data = value; }
    }
    }
    }

    e o XAML:

    Acho q esta tudo certo! Não?

    Obrigado por enquanto!

      1. Fabrício já virei teu código e não achei o erro.
        Caso queira, me passe o projeto do Visual Studio que dou uma olhada (eduardo@eduardorizo.com.br)

        []s
        Eduardo

      2. Obrigado por tudo Eduardo! Nunca iria descobrir o erro se não fosse você. O VS não apresenta erro no colocar um Binding na propriedade Name.

        Obrigado!

  11. phone:PhoneApplicationPage
    x:Class=”PanoramaApp1.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:phone=”clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone”
    xmlns:shell=”clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone”
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008″
    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″
    xmlns:wpControls=”clr-namespace:WPControls;assembly=WPControls”
    mc:Ignorable=”d”
    d:DataContext=”{d:DesignData SampleData/MainViewModelSampleData.xaml}”
    FontFamily=”{StaticResource PhoneFontFamilyNormal}”
    FontSize=”{StaticResource PhoneFontSizeNormal}”
    Foreground=”{StaticResource PhoneForegroundBrush}”
    SupportedOrientations=”Portrait” Orientation=”Portrait”
    shell:SystemTray.IsVisible=”False”>

    </phone:PhoneApplicationPage

    (nao sei se esta aparecendo, qqr cosia deleta que eu posto novamente)

  12. Eu tenho uma ListBox com 2 TextBlock e quer passar dados de uma página para outra, assim como você faria? Espero que você possa me ajudar, obrigado

    1. Boa noite, tudo bom?
      Você já conseguiu pegar os dados do ListBox e não sabe passar os dados para outra página, ou ainda não conseguiu pegar os dados do ListBox também?

      []s
      Eduardo

  13. Pingback: Curso Windows Phone – Como ler dados de documentos XML usando LINQ como forma de consulta | Blog do Eduardo H. Rizo

Deixe um comentário para Ewerton Cancelar resposta