Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get element in code behind from DataTemplate

I have a FlipView control with the DataTemplate defined as below:

<FlipView x:Name="FlipView5Horizontal" Width="480" Height="270" BorderBrush="Black" BorderThickness="1" Style="{StaticResource FlipViewStyle1}">
        <FlipView.ItemTemplate>
          <DataTemplate>
            <Grid>
              <Image Width="480" Name="xxxImage" Height="270" Source="{Binding Image}" Stretch="UniformToFill"/>
              <Border Name="xxxBorder" Background="#A5000000" Height="80" VerticalAlignment="Bottom">
                <TextBlock Name="xxxTB" Text="{Binding Title}" FontFamily="Segoe UI" FontSize="26.667" Foreground="#CCFFFFFF" Padding="15,20"/>
              </Border>
            </Grid>
          </DataTemplate>
        </FlipView.ItemTemplate>
      </FlipView>

In my code behind, I need to have access to the TextBlock named "xxxTB". Here is my code to do that:

public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

public void TestMethod()
{
        foreach (var item in FindVisualChildren<TextBlock>(this))
        {
            if (timeLine.Name == "xxxTB")
            { }                    
        }
}

But, when it finds the FlipView in the VisualTree, it returns from: for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) because VisualTreeHelper.GetChildrenCount(depObj) does not return anything.

Any idea?

like image 889
tavier Avatar asked Dec 21 '15 12:12

tavier


People also ask

How do you find DataTemplate generated elements?

If you want to retrieve the TextBlock element generated by the DataTemplate of a certain ListBoxItem, you need to get the ListBoxItem, find the ContentPresenter within that ListBoxItem, and then call FindName on the DataTemplate that is set on that ContentPresenter.

How do you access elements that are embedded inside the ControlTemplate?

When you declare elements inside the ControlTemplate, use the 'Name' of each control for identifying it from the outside. We can then use the 'FindName' function for finding the resource. An example shown below is for accessing the TextBlock of a button.


1 Answers

So here is a working solution:

public void TestMethod()
{
    DataTemplate dt = FlipView5Horizontal.ItemTemplate;
    DependencyObject dio = dt.LoadContent();
    foreach (var timeLine in FindVisualChildren<TextBlock>(dio)) //FindVisualTree is defined in the question :)
    {
        if (timeLine.Name == "xxxTB")
        { }
    }
}

Now, I am able to load the control at least. (However, I read that this trick should not be used in the overridden method OnApplyTemplate for some reason).

like image 129
tavier Avatar answered Oct 24 '22 10:10

tavier