我有一个我无法在代码隐藏中访问的控件,我相信这是因为它是在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>
答案 0 :(得分: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;
答案 1 :(得分:2)
我通常建议不要从代码中触摸UIElements ...但MediaElement是一个特殊情况...也许你应该将整个模板包装在一个usercontrol(可能有一些自定义DepProps)中,这样可以让你更好地控制整个过程。
编辑:另一种方法是创建一个带有几个属性的行为(例如IsPlaying)并从那里操纵mediaelement。然后,您可以在DataTemplate的XAML中使用此行为,而无需代码隐藏或用户控件。