Find child controls of LongListSelector Windows phone

2.6k views Asked by At

I trying to find the child element of LongListSelector. Here is my UI

<phone:PhoneApplicationPage.Resources>
  <DataTemplate x:Key="ItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding Photo}" Height="100" Width="100"/>
            <StackPanel>                    
                <TextBlock FontFamily="Segoe UI Semilight" Padding="9" Foreground="#313131" Width="330" TextWrapping="Wrap" Name="lblMessage" Text="{Binding Message}" FontSize="26" />
                <Button HorizontalAlignment="Left" Width="130" FontFamily="Segoe UI Semilight" BorderThickness="0.5" BorderBrush="#D62429" Content="Button1" Foreground="#313131"></Button>
                <Button Margin="15,-65,0,0" Width="120" FontFamily="Segoe UI Semilight" BorderThickness="0.5" BorderBrush="#D62429" Content="Button2" Foreground="#313131"></Button>                    
            </StackPanel>     
            <StackPanel>
              <RadioButton Name="Rdb1"/>
              <RadioButton Name="Rdb2"/> 
            </StackPanel>           
        </StackPanel>
    </DataTemplate>

     <DataTemplate  x:Key="ListHeader">
        <Border Background="#D62429" Opacity="0.8" Height="50">
            <TextBlock Name="txtHeader" Text="Long List Header" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black" FontFamily="Segoe UI Semilight"/>
        </Border>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

<Grid x:Name="LayoutRoot" Background="White">       
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <!--<Grid x:Name="gvHeader" Width="480" Height="70" Grid.Row="0" Canvas.ZIndex="1"></Grid>-->
    <!--Pivot Control-->
    <phone:Pivot Grid.Row="1" Name="pivotItems" Title="Welcome">            
        <phone:PivotItem FontFamily="Segoe WP Light" Header="item1">
            <Grid x:Name="item2" Grid.Row="1">
                <phone:LongListSelector ItemsSource="{Binding ListModel}"  x:Name="longListSelector"
                IsGroupingEnabled="True" LayoutMode="List" HideEmptyGroups="False"                                           
                ListHeaderTemplate="{StaticResource ListHeader}"/>
            </Grid>
        </phone:PivotItem>

        <!--Pivot item two-->
        <phone:PivotItem Header="item2">

        </phone:PivotItem>
    </phone:Pivot>
</Grid>

Here I want to find the TextBlock control of ListHeader. I use this code to find the control. but not getting anything.

TextBlock txtBlockHeader = FindFirstElementInVisualTree<TextBlock>(this.longListSelector.ListHeaderTemplate);

private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
    var count = VisualTreeHelper.GetChildrenCount(parentElement);
    if (count == 0)
        return null;

    for (int i = 0; i < count; i++)
    {
        var child = VisualTreeHelper.GetChild(parentElement, i);

        if (child != null && child is T)
        {
            return (T)child;
        }
        else
        {
            var result = FindFirstElementInVisualTree<T>(child);
            if (result != null)
                return result;

        }
    }
    return null;
}

How can I find the TextBlock from ListHeader ? What's wrong in my code ?

1

There are 1 answers

8
Kevin Gosse On BEST ANSWER

That's because ListHeaderTemplate returns the datatemplate. A datatemplate is, as its name indicate, a template: a blueprint indicating what controls should be built and how. It's not the actual control.

I don't know if the instantiated template is accessible in the LongListSelector. However, you can get around the problem by using ListHeader instead:

    <phone:LongListSelector ItemsSource="{Binding ListModel}"  x:Name="longListSelector"
       IsGroupingEnabled="True" LayoutMode="List" HideEmptyGroups="False"                       
       ItemTemplate="{StaticResource ItemTemplate}">
        <phone:LongListSelector.ListHeader>
            <Border Background="#D62429" Opacity="0.8" Height="50">
                <TextBlock Name="txtHeader" Text="Long List Header" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Black" FontFamily="Segoe UI Semilight"/>
            </Border>
        </phone:LongListSelector.ListHeader>
    </phone:LongListSelector>

Then you can call your method by using the same ListHeader property:

FindFirstElementInVisualTree<TextBlock>((FrameworkElement)this.longListSelector.ListHeader);

Or even by using directly the textbox's name:

this.txtHeader.Text = "Hello world!";