Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access a Control inside the data template in C# Metro UI in the code behind

I have a MediaElement that resides inside the datatemplate of flipview, i want to access that MediaElement named "video" in the code behind so that i can assign properties like play, pause, etc to through buttons here is the code of what i'm trying to do :

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

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

    <FlipView.ItemTemplate>
        <DataTemplate>
            <UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates">
                <ScrollViewer x:Name="scrollViewer" Style="{StaticResource VerticalScrollViewerStyle}" Grid.Row="1">
                    <Grid Margin="120,0,20,20">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="400" />
                            <ColumnDefinition Width="40" />
                            <ColumnDefinition Width="360" />
                            <ColumnDefinition Width="40" />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <Border BorderBrush="Black" BorderThickness="1" Width="350" HorizontalAlignment="Left" Grid.Row="0">
                            <MediaElement x:Name="Video" AutomationProperties.Name="Video" Source="/Assets/Big_Buck_Bunny.mp4" HorizontalAlignment="Center" VerticalAlignment="Stretch" Height="250" Width="350" AutoPlay="True" IsLooping="True" />
                        </Border>
                        <Border BorderBrush="Black" BorderThickness="1" Height="65" Width="350" HorizontalAlignment="Left" Grid.Row="1">
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
                                <Button x:Name="playButton" Margin="0,0" Click="playButton_Click" Style="{StaticResource PlayAppBarButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                <Button x:Name="pauseButton" Margin="0,0" Click="pauseButton_Click" Style="{StaticResource PauseAppBarButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </StackPanel>
                        </Border>
                    </Grid>
                </ScrollViewer>
            </UserControl>
        </DataTemplate>
    </FlipView.ItemTemplate>
</FlipView>

How do i achieve the intended ?

like image 503
Justice Avatar asked Mar 03 '13 19:03

Justice


People also ask

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.

What is the difference between control template and data template?

A ControlTemplate will generally only contain TemplateBinding expressions, binding back to the properties on the control itself, while a DataTemplate will contain standard Binding expressions, binding to the properties of its DataContext (the business/domain object or view model).


2 Answers

Try the following:

    private DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName)
    {
        int childNumber = VisualTreeHelper.GetChildrenCount(control);
        for (int i = 0; i < childNumber; i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(control, i);
            FrameworkElement fe = child as FrameworkElement;
            // Not a framework element or is null
            if (fe == null) return null;

            if (child is T && fe.Name == ctrlName)
            {
                // Found the control so return
                return child;
            }
            else
            {
                // Not found it - search children
                DependencyObject nextLevel = FindChildControl<T>(child, ctrlName);
                if (nextLevel != null)
                    return nextLevel;
            }
        }
        return null;
    }

Then call it from the play / pause button button:

    MediaElement media = FindChildControl<MediaElement>(this, "media") as MediaElement;
    media.Play();

A related blog post on the subject

like image 75
Paul Michaels Avatar answered Sep 20 '22 16:09

Paul Michaels


I wrote a blog article on this very topic about a year ago. Perhaps it will help you: http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html

The gist is this. You must parse through the visual tree to get all elements, and then you can use something like LINQ to filter the results and get your objects.

like image 37
Jerry Nixon Avatar answered Sep 17 '22 16:09

Jerry Nixon