patrick
patrick

Reputation: 16979

Why is VisualTreeHelper.GetChildrenCount(lbi) == 0?

I am trying to get my ToggleButton from a DataTemplate

ListBoxItem lbi = this.UnitsListBox.ItemContainerGenerator.ContainerFromItem(obj) as ListBoxItem;

lbi is ok (not null).

I would like to do this:

ContentPresenter cp = VisualTreeHelper.GetChild(lbi, 0) as ContentPresenter;
ToggleButton btn = (ToggleButton) VisualTreeHelper.GetChild(cp, 0);

But

VisualTreeHelper.GetChildrenCount(lbi) is 0. 

This is my XAML

<ListBox  MaxWidth="215" FlowDirection="RightToLeft" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"   DockPanel.Dock="Left" Name="UnitsListBox" VirtualizingStackPanel.IsVirtualizing="False" SelectionChanged="UnitsListBox_SelectionChanged" IsSynchronizedWithCurrentItem="True">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.Resources>
                    <Style TargetType="Button"/>
                </ListBox.Resources>
                <ListBox.ItemTemplate  >
                    <DataTemplate >
                        <ToggleButton x:Name="UnitSidebarButton"  FlowDirection="LeftToRight" Height="60" Width="60"  HorizontalContentAlignment="Center" Background="Transparent"  Margin="0" Padding="0" Checked="UnitSidebarButton_Checked" Unchecked="UnitSidebarButton_Unchecked" Focusable="False" VirtualizingStackPanel.IsVirtualizing="False">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Converter={StaticResource cIMSidebarConverter2}}" TextWrapping="Wrap"  TextAlignment="Center" Background="Transparent"/>
                          </Grid>
                        </ToggleButton>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Upvotes: 1

Views: 2334

Answers (1)

Rachel
Rachel

Reputation: 132618

When I copied/pasted your code into a test project, the next item in the visual tree hierarchy below the ListBoxItem was a Border element, not a ContentPresenter (I use Snoop to view the Visual Tree). I suspect that is why your ContentPresenter object is null.

If you're interested, I have some VisualTreeHelpers on my blog that would probably make this easier. You can use them like this:

var toggleBtn = VisualTreeHelpers.FindChild<ToggleButton>(lbi);

(Old Answer)

Your containers are probably not generated

Here's an example of how to use the StatusChanged event to identify if the containers have been generated or not before running your code

public Window()
{
    InitializeComponent();

    // Attach StatusChanged event
    UnitsListBox.ItemContainerGenerator.StatusChanged += 
        ItemContainerGenerator_StatusChanged;
}

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    // If containers have been generated
    if (UnitsListBox.ItemContainerGenerator.Status == 
        System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
    {
        // Remove event
        UnitsListBox.ItemContainerGenerator.StatusChanged -= 
            ItemContainerGenerator_StatusChanged;

        // Do whatever here
        var lbi = UnitsListBox.ItemContainerGenerator.ContainerFromItem(obj) as ListBoxItem;

    }
}

Upvotes: 1

Related Questions