2012-10-31 3 views
1

Codebehind에서 액세스 할 수없는 컨트롤이 있는데이 코드는 DataTempalte에 정의되어 있기 때문입니다.CodeBehind에서 DataTemplate의 XAML 컨트롤에 액세스 하시겠습니까?

전체 컨트롤은 슬라이드 쇼 회전 목마입니다. 각 슬라이드는 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> 

답변

2

나는 일반적으로 코드에서 UiElements의를 건드리지 않도록 추천 할 것입니다 ...하지만 MediaElement에 어쩌면 당신은 (아마도 일부 사용자 지정 DepProps 포함) UserControl을 내부의 전체 템플릿과 그 의지를 포장한다 ... 특별한 경우이다 모든 것을보다 잘 제어 할 수 있습니다.

편집 : 다른 접근법은 몇 가지 속성 (예 : IsPlaying)으로 동작을 만들고 여기에서 미디어 요소를 조작하는 것입니다. 그런 다음 코드 숨김 또는 usercontrols 필요없이 DataTemplate의 XAML에서이 동작을 사용할 수 있습니다.

+0

그래도 여전히 DataTemplate 안에 있지 않습니까? 나는 내가 UserControl으로 템플릿을 분리 할 곳을보고 있지 않다. 그 템플릿은 DataTemplate 내부에있는 것을 제어 할 필요가 없다. 내 ItemsPanel/ItemsTemplate은 모델에 바인딩되어 있으므로, 트리거 할 수있는 DependancyProperties (플래그가 아닌 플래그)를 볼 수 없습니다. –

+1

그래, 당신은 여전히 ​​DataTemplate 안에 UserControl을 가지지 만, UserControls는 그 자체로 코드를 가지고 있고, bool IsPlaying과 같은 종속성 프로퍼티를 선언 할 수도 있고, 변경된 콜백에서 mediaelement.play() 또는 stop() 등등. –

+0

그 부분을 이해하지만, 어떻게 'IsPlaying' 플래그를 뒤집을 수 있을까요? 나는이 경우 질문이 구속력있는 것에 합병된다고 생각한다. DataTemplate은 데이터 모델에 대해서만 알고 있습니다. 슬라이드가 표시되는지 여부를 확인하기 위해 DataTemplate 외부의 값을 어떻게 든 잡을 필요가 없습니까? –

2

WPF는 DataTemplates에서 생성 된 명명 된 요소에 간단하고 간단하게 액세스 할 수있는 방법을 제공합니다. 이 내용은 MSDN 기사 How to: Find DataTemplate-Generated Elements에서 설명합니다. 당신은에 의해 DataTemplate을에서 명명 된 요소를 얻을 것 ContentPresenter에에서

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

:

는이 같은 항목의 용기있는 ContentPresenter에 얻을 것이다, 당신의 AutoScrollCarousel가 ItemsControl에서 파생 된 것으로 가정 FindName 메서드 :

var dataTemplate = contentPresenter.ContentTemplate; 
var mediaPlayer = dataTemplate.FindName("MediaPlayer", contentPresenter) as MediaElement; 
관련 문제