Access ListBoxItem-Controls in WPF ListBox

idelix picture idelix · Jun 12, 2012 · Viewed 9.2k times · Source

In WPF application I create Listbox with it's ItemTemplate defined in following DataTemplate in XAML:

<DataTemplate x:Key="ListItemTemplate">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto"></RowDefinition>
      <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <StackPanel>
      <Button/>
      <Button/>
      <Button Name="btnRefresh" IsEnabled="false"/>
      <TextBlock/>
      <TextBlock/>
      <TextBlock/>
      <TextBlock/>
    </StackPanel>
    <TextBox/>
  </Grid>
</DataTemplate>

Once ListBox is generated I need to change following button IsEnabled propety to true on all ListBoxItem(s): <Button Name="btnRefresh" IsEnabled="false"/>

PROBLEM:

I Cannot access ListBoxItem(s) and therefore cant access their children with that button among them.

Is there in WPF anything like ListBox.Descendents() which is in Silverlight or any other way to get to that button,

Answer

evanb picture evanb · Jun 13, 2012

The preferred way to do this is by changing a property in the ViewModel that is bound to that Button's IsEnabled property. Add a handler to the ListBox.Loaded event and set that property in the ViewModel to false when the ListBox is loaded.

The other option, if you need to traverse through each data templated item in the ListBox then do the following:

    if (listBox.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
        {
           foreach (var item in listBox.Items)
           {
              ListBoxItem container = listBox.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem;
              // Get button
              ContentPresenter contentPresenter = contentPresenter.ContentTemplate.FindName("btnRefresh", contentPresenter);
              Button btn = contentPresenter as Button;
              if (btn != null)
                  btn.IsEnabled = true;
           }
        }