2013-03-03 2 views
8

Ho un MediaElement che risiede all'interno del datatemplate di flipview, voglio accedere a quel MediaElement chiamato "video" nel codice dietro in modo che io possa assegnare le proprietà come play, pausa, ecc per tramite pulsanti ecco il codice di quello che sto cercando di fare:Come accedere a un controllo all'interno del modello di dati nell'interfaccia utente di Metro C# nel codice

<FlipView 
    x:Name="flipView" 
    AutomationProperties.AutomationId="ItemsFlipView" 
    AutomationProperties.Name="Item Details" 
    TabIndex="1" 
    Grid.RowSpan="2" 
    ItemsSource="{Binding Source={StaticResource itemsViewSource}}"> 

    <FlipView.ItemContainerStyle> 
     <Style TargetType="FlipViewItem"> 
      <Setter Property="Margin" Value="0,137,0,0"/> 
     </Style> 
    </FlipView.ItemContainerStyle> 

    <FlipView.ItemTemplate> 
     <DataTemplate> 
      <UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates"> 
       <ScrollViewer x:Name="scrollViewer" Style="{StaticResource VerticalScrollViewerStyle}" Grid.Row="1"> 
        <Grid Margin="120,0,20,20"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="400" /> 
          <ColumnDefinition Width="40" /> 
          <ColumnDefinition Width="360" /> 
          <ColumnDefinition Width="40" /> 
          <ColumnDefinition /> 
         </Grid.ColumnDefinitions> 
         <Border BorderBrush="Black" BorderThickness="1" Width="350" HorizontalAlignment="Left" Grid.Row="0"> 
          <MediaElement x:Name="Video" AutomationProperties.Name="Video" Source="/Assets/Big_Buck_Bunny.mp4" HorizontalAlignment="Center" VerticalAlignment="Stretch" Height="250" Width="350" AutoPlay="True" IsLooping="True" /> 
         </Border> 
         <Border BorderBrush="Black" BorderThickness="1" Height="65" Width="350" HorizontalAlignment="Left" Grid.Row="1"> 
          <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 
           <Button x:Name="playButton" Margin="0,0" Click="playButton_Click" Style="{StaticResource PlayAppBarButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
           <Button x:Name="pauseButton" Margin="0,0" Click="pauseButton_Click" Style="{StaticResource PauseAppBarButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
          </StackPanel> 
         </Border> 
        </Grid> 
       </ScrollViewer> 
      </UserControl> 
     </DataTemplate> 
    </FlipView.ItemTemplate> 
</FlipView> 

Come faccio a raggiungere la destinazione?

risposta

20

Provare quanto segue:

private DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName) 
    { 
     int childNumber = VisualTreeHelper.GetChildrenCount(control); 
     for (int i = 0; i < childNumber; i++) 
     { 
      DependencyObject child = VisualTreeHelper.GetChild(control, i); 
      FrameworkElement fe = child as FrameworkElement; 
      // Not a framework element or is null 
      if (fe == null) return null; 

      if (child is T && fe.Name == ctrlName) 
      { 
       // Found the control so return 
       return child; 
      } 
      else 
      { 
       // Not found it - search children 
       DependencyObject nextLevel = FindChildControl<T>(child, ctrlName); 
       if (nextLevel != null) 
        return nextLevel; 
      } 
     } 
     return null; 
    } 

Poi chiamare dal bottone pulsante play/pausa:

MediaElement media = FindChildControl<MediaElement>(this, "media") as MediaElement; 
    media.Play(); 

A related blog post on the subject

1

ho scritto un articolo del blog su questo argomento circa un anno fa. Forse ti aiuterà: http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html

L'essenza è questa. È necessario analizzare l'albero visivo per ottenere tutti gli elementi, quindi è possibile utilizzare qualcosa come LINQ per filtrare i risultati e ottenere i propri oggetti.

+0

Nixon grazie per la risposta Ho già visto il tuo articolo è molto istruttivo ma ho avuto un dubbio per cui ho lasciato una domanda nel tuo blog, gentilmente dare un'occhiata a questo – Justice

0

Ho esteso la soluzione di Jerry a una soluzione più flessibile e migliore per ottenere solo i controlli desiderati e non creare elenchi intermedi durante le chiamate ricorsive.

Si può semplicemente usando come quella di ottenere il controllo:

var myControl = AllChildren(parent, c => c.Name == "xxx").FirstOrDefault(); 

Per questo è necessario includere le seguenti AllChildren funcion:

private List<Control> AllChildren(DependencyObject parent, Func<DependencyObject, bool> query, List<Control> _List = null) 
    { 
     if (_List == null) 
      _List = new List<Control>(); 

     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
     { 
      var _Child = VisualTreeHelper.GetChild(parent, i); 
      if (_Child is Control && query(_Child)) 
      { 

       _List.Add(_Child as Control); 
      } 
      AllChildren(_Child, query, _List); 
     } 
     return _List; 
    }