Search code examples
c#wpfwpf-controlsdatatemplate

Access XAML Control In DataTemplate From CodeBehind?


I have a control that I am unable to access in the codebehind, and I believe it is because it is defined in a DataTempalte.

The overall control is a slide show carousel. Each slide can be an Image or a MediaElement (video), the contents of which are defined in an ItemSource binding. The carousel is on a timer to switch from one slide to the next. Each time the slide changes I fire an event to that effect.

When I hit a slide with a video I'd like to stop the slide timer (done that) and start the video, which is where I've run into a problem. I can not access the MediaPlayer element Name from my codebehind. My assumption at this point is because it is a DataTemplate.

Is this assumption correct? If so, how can I get access to this control from the codebehind, or (more to the point) have it start playing when the slide comes up?

<ctrl:AutoScrollCarousel ...>
    <ctrl:AutoScrollCarousel.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ctrl:AutoScrollCarousel.ItemsPanel>
    <ctrl:AutoScrollCarousel.ItemTemplate>
        <DataTemplate>
            <Border x:Name="Border" VerticalAlignment="Center"
                    Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type UserControl},Mode=FindAncestor}}">
                <Grid Background="White">
                    ...
                    <Image Source="{Binding ContentImage}" Grid.Row="1" Grid.Column="1" Stretch="UniformToFill"
                            HorizontalAlignment="Center"
                            Visibility="{Binding ContentImage, Converter={StaticResource VisibilityConverter}}" />

                    <MediaElement Name="MediaPlayer" Source="{Binding ContentVideo}" Grid.Row="1" Grid.Column="1" Stretch="UniformToFill" LoadedBehavior="Play"
                                    Visibility="{Binding ContentVideo, Converter={StaticResource VisibilityConverter}}" MediaEnded="MediaPlayer_MediaEnded" />

                    <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Title}" Foreground="Black"
                                FontFamily="Segoe UI" FontWeight="Light" HorizontalAlignment="Left" FontSize="75" Margin="0" VerticalAlignment="Center" />

                    <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding ContentHeadline}" Foreground="Black"
                                FontFamily="Segoe UI" FontWeight="Light" HorizontalAlignment="Left" FontSize="50" VerticalAlignment="Center"
                                TextWrapping="Wrap">
                    </TextBlock>
                </Grid>
            </Border>
        </DataTemplate>
    </ctrl:AutoScrollCarousel.ItemTemplate>
</ctrl:AutoScrollCarousel>

Solution

  • I would normally recommend not to touch UIElements from code... but the MediaElement is a special case... maybe you should wrap the whole template inside a usercontrol (maybe with some custom DepProps) and that will give you better control over the whole thing.

    Edit: Another approach would be to create a Behavior with a couple of properties (such as IsPlaying) and manipulate the mediaelement from there. Then you could use this behavior in the XAML of the DataTemplate, with no need for code behind or usercontrols.