2012-10-31 58 views
1

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

总体控制是幻灯片放映转盘。每张幻灯片可以是图像或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> 

回答

2

我通常会建议不要去碰从代码UI元素......但MediaElement的是一种特殊情况......也许你应该换一个用户控件(可能与一些自定义DepProps)内整个模板,这将让你更好地控制整个事情。

编辑:另一种方法是创建一个带有几个属性(如IsPlaying模块)行为,并从那里操纵的MediaElement。然后,您可以在DataTemplate的XAML中使用此行为,而不需要代码隐藏或usercontrols。

+0

但是,这仍然不会在DataTemplate内?我没有看到将模板分隔到UserControl的位置,但这并不会导致我需要控制DataTemplate中的某些内容。由于我的ItemsPanel/ItemsTemplate绑定到一个模型,我没有看到我可以标记(我还没有)的DependancyProperties来触发它。 –

+1

是的,你仍然有你的UserControl在DataTemplate中,但UserControls有自己的代码,你也可以声明一些依赖属性,如bool IsPlaying,并在为mediaelement.play()或stop()等等 –

+0

我明白那个部分,但是我怎么翻转'IsPlaying'标志?我认为在这种情况下,这个问题合并成一个具有约束力的问题。 DataTemplate只知道数据模型。我不需要以某种方式在DataTemplate外部获取一个值来查看幻灯片是否可见? –

2

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你会通过以下方式获得的DataTemplate中指定元素FindName方法:

var dataTemplate = contentPresenter.ContentTemplate; 
var mediaPlayer = dataTemplate.FindName("MediaPlayer", contentPresenter) as MediaElement; 
相关问题