Curso Windows Phone – Como obter acesso a controles dentro do ItemTemplate do ListBox

Olá pessoal, tudo bom?

Aproveito uma questão que me fizeram para escrever esse post que demonstra como obter acesso a controles que estão posicionados dentro do ItemTemplate de um determinado ListBox ou outro container qualquer.

Tomando por base a seguinte definição para um ListBox cuja finalidade seria exibir tipos de pizzas e seus respectivos ingredientes:

...
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <ListBox Name="lbSabores" Height="540" ItemsSource="{StaticResource MeusDados}">
 <ListBox.ItemTemplate>
 <DataTemplate>
 <StackPanel>
 <CheckBox Height="Auto" Content="{Binding Nome}" IsChecked="{Binding Selecionado}" />
 <TextBlock Name="txtIngredientes" Height="Auto" Text="{Binding Ingredientes}" />
 </StackPanel>
 </DataTemplate>
 </ListBox.ItemTemplate>
 </ListBox>
</StackPanel>
...

Considerando ainda a existência de um botão que irá destacar todos os TextBlocks que exibem os ingredientes das pizzas (trocar a cor do texto Foreground)

...
<Button Name="btnDestacar" Content="Destacar Ingredientes" Tap="btnDestacar_Tap" />
...

Repare agora que utilizei um método genérico em C# que permite localizar controles dentro de um determinado container (no nosso caso o ListBox lbSabores), sendo que para o caso, faço uma pergunta buscando por um determinado TextBlock chamado txtIngredientes e, quando encontrado, troco a cor da fonte do mesmo.

...
private void Destacar(DependencyObject targetElement)
{
  var count = VisualTreeHelper.GetChildrenCount(targetElement);
  if (count == 0)
    return;
  for (int i = 0; i < count; i++)
  {
    var child = VisualTreeHelper.GetChild(targetElement, i);
    if (child is TextBlock)
    {
      TextBlock targetItem = (TextBlock)child;
      if (targetItem.Name == "txtIngredientes")
      {
        targetItem.Foreground = new SolidColorBrush(Colors.Green);
        return;
      }
    }
    else
    {
      Destacar(child);
    }
  }
}
...

Agora, imaginando que o usuário toque no botão “Destacar Ingredientes” podemos chamar o método Destacar e passar para ele o ListBox que contem os elementos que queremos localizar.

...
private void btnDestacar_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
  Destacar(lbSabores);
}
...

controles-localizar-wp

Espero ter ajudado!

Posts Relacionados: 

Grande abraço,
Eduardo Henrique Rizo

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

Referência: http://www.geekchamp.com/tips/how-to-access-a-control-placed-inside-listbox-itemtemplate-in-wp7

22 comentários em “Curso Windows Phone – Como obter acesso a controles dentro do ItemTemplate do ListBox”

  1. Olá Eduardo!
    Muito obrigado pelo post.

    Porém, não funcionou como esperado.
    Utilizei esse método para que ao entrar na página dependendo de uma condição, o foreground fique branco ou preto.

    Porém se eu sair da aplicação e entrar de novo, mesmo chamando o método ao carregar página (Loaded), o fundo fica da cor padrão.

    Mas, se eu vou pra outra página e volto pra ela, funciona normalmente.

    O que pode estar errado?
    Por que não carrega quando saio da app e volto?

    Abraços.

  2. Olá Eduardo Segue o cód:

    //1º Faço uma verificação para saber qual cor devo usar dentro do LayoutRoot_Update:

    ImageSource sourceBg = new BitmapImage(new Uri(imagem, UriKind.Relative));
    //imagem é o caminho da imagem de fundo
    if (imagem== “Imagens/05.jpg”)
    {
    cor_do_texto = new SolidColorBrush(Colors.White);
    Muda_Cor_Texto(cor_do_texto);
    }
    else
    {
    cor_do_texto = new SolidColorBrush(Colors.Black);
    Muda_Cor_Texto(cor_do_texto);
    }

    //Muda Cor Texto é pra mudar os foreground’s de todos os itens da página.
    private void Muda_Cor_Texto(SolidColorBrush cor)
    {
    SolidColorBrush foreground_cor = cor;
    //Mudar_Cor_ListBox é o método que você passou ali em cima como ‘Destacar’.
    Mudar_Cor_ListBox(Sit_ListBox, foreground_cor);
    ApplicationTitle.Foreground = foreground_cor;
    PageTitle.Foreground = foreground_cor;
    }

    Então o código que uso é esse.

    1. Gutenberg, tudo bom?
      Você pode experimentar fazer as chamadas ao seus métodos que trocam as cores não no MainPage, mas sim no OnNavigatedTo(…) da página.
      Experimente declarar esse método e realizar as ações desejadas.

      []s
      Eduardo

      1. Acho que agora só se tentar debugar a APP para ver as decisões que o código está tomando.
        Se quiser que eu ajude, pode me mandar os fontes por e-mail (eduardo@eduardorizo.com.br)

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

  4. Muito bom o post Eduardo, falando de ListBox, eu tenho um problema. Eu crio o Selection Changed do listbox, quando eu clico e vou pra a proxima pagina com o o objeto selecionado, blz isso tá certo, só quando eu volto para pagina onde está a listbox o item fica selecionando e não posso seleciona novamente. Para eu selecionar ele novamente tenho que clicar em outro item e depois volto e posso selecionar o antigo item selecionando, mas o que acabei de seleciona eu não consigo.

    1. E você precisa voltar com esse último item selecionado?
      Se não, basta utilizar o método OnNavigatedTo na página onde está o ListBox e fazer com que ele volte à sua posição inicial. O método OnNavigatedTo ocorre quando a pessoa entra na página ou volta para ela.

      Certo?

      1. E como se tira o evento SelectionChange ? Eu tenho um livro de WP, ele explica que se faz assim . Ex: MeuListBox.SelectionChanged -= OnSelectionChanged;

        Só que OnSelectionChanged não existe. No livro mostra pra usar no OnNavigatedFrom. Mas mesmo assim não reconhece o OnSelectionChanged.

        Tem outro jeito de fazer?

    2. Caro Arthur,
      Se entendi bem você quer que ao voltar para o listbox possa selecionar o mesmo item novamente é isso?

      Se for isso, tente resetar o selectIndex. assim óh:

      private void SeuListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
      {
      // If selected index is -1 (no selection) do nothing
      if (SeuListBox.SelectedIndex == -1)
      return;

      // açao que você quer.
      Acao();

      // Reset selected index to -1 (no selection)
      SeuListBox.SelectedIndex = -1;
      }

      Ou seja, quando ele executar a ação já não vai ter nenhum item selecionado.
      Se sua ação for de ir em outra página, quando você voltar não vai ter nenhum item selecionado.

      Abraços.

      1. Caro Gutenberg Carlos,

        Deu certo o seu exemplo, vlw mesmo.

        Caro Eduardo,
        vlw pelos link, vou da uma olhada sim.

        Abraço a todos.

  5. olá Eduardo, estou tentando fazer isto para acessar uma stackpanel e deixa-lá visível mas pelo que eu entendi as stackpanel não visíveis não são encontradas pelo VisualTreeHelper.GetChild, você teria alguma alternativa para isto?

  6. 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