user1106633
user1106633

Reputation: 155

How to access xaml Control inside DataTemplate inside FlipView

I want to access the "image" element in the C# code. I know that i cannot access it directly since it is in datatemplate. I have tried visual trees but still not able to get "image" control element in the code .

<FlipView
            x:Name="flipView"
            AutomationProperties.AutomationId="ItemsFlipView"
            AutomationProperties.Name="Item Details"
            TabIndex="1"
            Grid.RowSpan="2"
            ItemsSource="{Binding Source={StaticResource itemsViewSource}}" SelectionChanged="flipView_SelectionChanged">

            <FlipView.ItemContainerStyle>
                <Style TargetType="FlipViewItem">
                    <Setter Property="Margin" Value="0,137,0,0"/>
                </Style>
            </FlipView.ItemContainerStyle>

            <FlipView.ItemTemplate>
                <DataTemplate>

                    <!--
                        UserControl chosen as the templated item because it supports visual state management
                        Loaded/unloaded events explicitly subscribe to view state updates from the page
                    -->
                    <UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
                        <ScrollViewer x:Name="scrollViewer" Style="{StaticResource HorizontalScrollViewerStyle}" Grid.Row="1">

                            <!-- Content is allowed to flow across as many columns as needed -->
                            <common:RichTextColumns x:Name="richTextColumns" Margin="117,0,117,47">
                                <RichTextBlock x:Name="richTextBlock" Width="560" Style="{StaticResource ItemRichTextStyle}" IsTextSelectionEnabled="False">
                                    <Paragraph>
                                        <Run FontSize="26.667" FontWeight="Light" Text="{Binding Title}"/>
                                        <LineBreak/>
                                        <LineBreak/>
                                        <Run FontWeight="Normal" Text="{Binding Subtitle}"/>
                                    </Paragraph>
                                    <Paragraph LineStackingStrategy="MaxHeight">
                                        <InlineUIContainer>
                                            <Image x:Name="image" MaxHeight="480" Margin="0,20,0,10" Stretch="Uniform" Source="{Binding Image}" AutomationProperties.Name="{Binding Title}"/>
                                        </InlineUIContainer>
                                    </Paragraph>                                  
                                </RichTextBlock>
                            </common:RichTextColumns>
                        </ScrollViewer>
                    </UserControl>
                </DataTemplate>
            </FlipView.ItemTemplate>
</FlipView>

Upvotes: 2

Views: 4080

Answers (2)

Jerry Nixon
Jerry Nixon

Reputation: 31813

Answered here https://stackoverflow.com/a/16446670/265706

The short answer is: The problem you are experiencing is that the DataTemplate is repeating and the content is being generated by he FlipView. The Name is not exposed because it would conflict with the previous sibling that was generated (or the next one that will be).

So, to get a named element in the DataTemplate you have to first get the generated item, and then search inside that generated item for the element you want. Remember, the Logical Tree in XAML is how you access things by name. Generated items are not in the Logical Tree. Instead, they are in the Visual Tree (all controls are in the Visual Tree). That means it is in the Visual Tree you must search for the control you want to reference. The VisualTreeHelper lets you do this.

Upvotes: 2

sankar
sankar

Reputation: 1726

I have tried and I am able to access the control inside of FlipView DataTemplate as you described. Try to below approach and let me know if this helps.

public static IEnumerable<T> RecurseChildren<T>(DependencyObject root) where T : UIElement
{
    if (root is T)
    {
        yield return root as T;
    }

    if (root != null)
    {
        var count = VisualTreeHelper.GetChildrenCount(root);


        for (var idx = 0; idx < count; idx++)
        {
            foreach (var child in RecurseChildren<T>(VisualTreeHelper.GetChild(root, idx)))
            {
                yield return child;
            }
        }
    }
}

Accessing Image control:

var imageControl = RecurseChildren<Image>(rootVisual).FirstOrDefault();

here rootVisual is the Grid instance in my page.

Upvotes: 3

Related Questions