Question

I have a Panorama which gets a dynamic amount of items based on data binding. In the created PanoramaItem, I have an Image which I want to modify over time (fade in/out different images over time).

I saw similar questions like this: How to retrieve the name of a Panorama-Item at runtime? but that does not work for me as I never get a PanoramaItem when I use Panorama.Items[index]. I only get an instance of the data binding I use.

I come from the Android world where I could simple use something like findViewById() to get a specific view. Is there anything similar in WP8? I do know FindName() but that used on my Panorama simply returns null...

So my question is: How can I get a reference of Image named GalleryPreview in the code behind file?

My page xaml

<phone:PhoneApplicationPage
    x:Class="App.View.AppDetailsPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"  Orientation="Portrait"
    shell:SystemTray.IsVisible="False" >

    <phone:PhoneApplicationPage.Resources>
        <DataTemplate x:Key="PanoramaHeaderTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="72"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Image Source="{Binding AppStoreIcon}"
                       Width="64" Height="64"
                       Grid.Column="0"
                       HorizontalAlignment="Left"/>
                <TextBlock x:Name="ItemTitle"
                           Text="{Binding os}"
                           Grid.Column="1"/>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="PanormaItemTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <TextBlock Text="{Binding storeName}" FontSize="24"
                           Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"/>

                <TextBlock Text="Rating" FontSize="24"
                           Grid.Row="1" Grid.Column="0"/>
                <TextBlock Text="{Binding rating}" FontSize="24"
                           Grid.Row="1" Grid.Column="1"/>

                <TextBlock Text="5 Stars: " FontSize="24"
                           Grid.Row="2" Grid.Column="0"/>
                <TextBlock Text="{Binding starsFive}" FontSize="24"
                           Grid.Row="2" Grid.Column="1"/>
                <TextBlock Text="4 Stars: " FontSize="24"
                           Grid.Row="3" Grid.Column="0"/>
                <TextBlock Text="{Binding starsFour}" FontSize="24"
                           Grid.Row="3" Grid.Column="1"/>
                <TextBlock Text="3 Stars: " FontSize="24"
                           Grid.Row="4" Grid.Column="0"/>
                <TextBlock Text="{Binding starsThree}" FontSize="24"
                           Grid.Row="4" Grid.Column="1"/>
                <TextBlock Text="2 Stars: " FontSize="24"
                           Grid.Row="5" Grid.Column="0"/>
                <TextBlock Text="{Binding starsTwo}" FontSize="24"
                           Grid.Row="5" Grid.Column="1"/>
                <TextBlock Text="1 Stars: " FontSize="24"
                           Grid.Row="6" Grid.Column="0"/>
                <TextBlock Text="{Binding starsOne}" FontSize="24"
                           Grid.Row="6" Grid.Column="1"/>

                <StackPanel Grid.ColumnSpan="2" Grid.Row="7"
                            ManipulationStarted="AppItemManipulationStarted"
                            ManipulationCompleted="AppItemManipulationCompleted">
                    <Image x:Name="GalleryPreview" Source="/Assets/images/blub.png"/>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </phone:PhoneApplicationPage.Resources>

    <!--LayoutRoot contains the root grid where all other page content is placed-->
    <Grid x:Name="LayoutRoot">
        <phone:Panorama x:Name="AppPanorama" Title="Title"
                        ItemsSource="{Binding}"
                        SelectionChanged="PanoramaSelectionChanged"
                        HeaderTemplate="{StaticResource PanoramaHeaderTemplate}"
                        ItemTemplate="{StaticResource PanormaItemTemplate}">
        </phone:Panorama>
    </Grid>

</phone:PhoneApplicationPage>

When I try to use FindName("GalleryPreview")

LogUtil.Log(AppPanorama.FindName("GalleryPreview") == null ? "null" : AppPanorama.FindName("GalleryPreview"));
LogUtil.Log(LayoutRoot.FindName("GalleryPreview") == null ? "null" : LayoutRoot.FindName("GalleryPreview"));
LogUtil.Log(AppPanorama.SelectedItem);

// output:
// null
// null
// App.Model.Store
Was it helpful?

Solution 3

@wankr guided me in the right direction though his link didn't fully helped me.

I wanted to access an Image to change the displayed source on a timer base.

This is what my OnTick contains to get the Image reference:

ImageSourceConverter converter = new ImageSourceConverter();
PanoramaItem myPanoramaItem = (PanoramaItem)(AppPanorama.ItemContainerGenerator.ContainerFromItem(AppPanorama.Items[_selectedIndex]));
Image galleryItem = (Image)FindVisualChild<Image>("GalleryPreview", myPanoramaItem);
galleryItem.Source = (ImageSource)converter.ConvertFromString(gallery[_galleryIndex]);

"GalleryPreview" is the name of the Image I want to access. As I have multiple Images in my layout, I needed to extend the method FindVisualChild I found on the link from @wankr.

public static ChildItem FindVisualChild<ChildItem>(String name, DependencyObject obj) where ChildItem : DependencyObject
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        DependencyObject child = VisualTreeHelper.GetChild(obj, i);
        FrameworkElement uiChild = (FrameworkElement)child;
        if (child != null && child is ChildItem && uiChild.Name.Equals(name))
        {
            return (ChildItem)child;
        }
        else
        {
            ChildItem childOfChild = FindVisualChild<ChildItem>(name, child);
            if (childOfChild != null)
            {
                return childOfChild;
            }
        }
    }
    return null;
}

OTHER TIPS

Control.GetTemplateChild might be what you are looking for.

Templates have a self-contained namescope. This is because templates are re-used, and any name defined in a template cannot remain unique once multiple instances of a control each instantiate their template. Call GetTemplateChild in order to return references to objects that come from the template after it is instantiated. You cannot use FindName to find items from templates because FindName acts in a more general scope, and there is no connection between the ControlTemplate class itself and the instantiated template once it is applied.

last try How to: Find DataTemplate-Generated Elements

try this and see if it helps:

Image newImg = new Image();
newImg = LayoutRoot.FindName("GalleryPreview") as Image;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top