2

我有一个无法在代码隐藏中访问的控件,我相信这是因为它是在 DataTempalte 中定义的。

整体控制是幻灯片放映轮播。每张幻灯片都可以是 Image 或 MediaElement(视频),其内容在 ItemSource 绑定中定义。旋转木马上有一个计时器,可以从一张幻灯片切换到下一张幻灯片。每次幻灯片更改时,我都会触发一个事件来实现该效果。

当我用视频点击幻灯片时,我想停止幻灯片计时器(完成此操作)并开始播放视频,这是我遇到问题的地方。我无法从我的代码隐藏中访问该MediaPlayer元素。Name我在这一点上的假设是因为它是一个 DataTemplate。

这个假设正确吗?如果是这样,我如何从代码隐藏中访问此控件,或者(更重要的是)在幻灯片出现时开始播放?

<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>
4

2 回答 2

4

WPF 提供了一种简单直接的方法来访问从 DataTemplates 生成的命名元素。MSDN 文章How to: Find DataTemplate-Generated Elements对此进行了解释。

假设您的 AutoScrollCarousel 是从 ItemsControl 派生的,您将获得 ContentPresenter,它是这样一个项目的容器:

AutoScrollCarousel carousel = ...
object item = ...
var contentPresenter =
    carousel.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter;

从 ContentPresenter 中,您将通过FindName方法获得 DataTemplate 中的命名元素:

var dataTemplate = contentPresenter.ContentTemplate;
var mediaPlayer = dataTemplate.FindName("MediaPlayer", contentPresenter) as MediaElement;
于 2012-10-31T22:18:32.353 回答
2

我通常建议不要从代码中触摸 UIElements ......但 MediaElement 是一个特例......也许你应该将整个模板包装在一个用户控件中(也许使用一些自定义的 DepProps),这将使你更好地控制整个事物。

编辑:另一种方法是创建具有几个属性(例如 IsPlaying)的行为并从那里操作媒体元素。然后,您可以在 DataTemplate 的 XAML 中使用此行为,而无需隐藏代码或用户控件。

于 2012-10-31T20:40:40.403 回答