2010-11-23 10 views
1

Ich arbeite an einem Projekt, bei dem TV von einer Tunerkarte in einer WPF-Anwendung wiedergegeben wird. Kürzlich habe ich die TV-Wiedergabefunktionen neu geschrieben, um mit WPF MediaKit zu arbeiten, um eine nahtlose Interaktionserfahrung zu ermöglichen (zuvor verwendete ich WindowsFormsHost und ein WinForms-Steuerelement als DirectShow-Renderziel, was zu allen üblichen Luftraumproblemen führte).Festlegen eines Steuerelements in einem DataTemplate als CommandTarget eines Buttons außerhalb der Vorlage

Die Software spielt sowohl analoge als auch digitale TV, und wie sie anders behandelt werden, ich habe eine Player und MediaElement für beide erstellt (DigitalTvPlayer, DigitalTvElement, AnalogTvPlayer, AnalogTvElement), die von den jeweiligen MediaKit Klassen erstrecken MediaPlayerBase und MediaElementBase.

Diese Kontrollen funktionieren alle, aber ich bin jetzt auf der Suche nach einer Möglichkeit, ein einzelnes 'TV Player Window' zu haben, das eine Liste von Kanälen (eine Mischung aus analog und digital) enthalten kann und automatisch zwischen ihnen wechseln und auswählen kann der geeignete Spieler.

Mein erster Versuch, dies zu tun beteiligt einen ContentPresenter auf den ausgewählten Kanal gebunden verwenden und einen bestimmten DataTemplate für jeden Kanaltyp:

<Window.Resources> 
    <DataTemplate DataType="{x:Type Channels:AnalogChannel}"> 
     <Controls:AnalogTvGraphFileElement 
      AnalogSpecificData="..." 
      Channel="{Binding}" /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type Channels:DigitalChannel}"> 
     <Controls:DigitalTvElement 
      DigitalSpecificData="..." 
      Channel="{Binding}" /> 
    </DataTemplate> 
</Window.Resources> 

Mit dem folgenden Fenster Körper:

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 
    <ContentPresenter 
     x:Name="TvPresenter" 
     VerticalAlignment="Stretch" 
     HorizontalAlignment="Center" 
     Content="{Binding ElementName=TvChannels, Path=SelectedItem}" /> 

    <ListBox Grid.Column="1" x:Name="TvChannels" ItemsSource="{Binding Channels}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding}" /> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 

Obwohl dieser Ansatz "funktioniert" (TV spielt, es schaltet automatisch zwischen analogen und digitalen usw. um), ich verliere die Fähigkeit, direkte Kontrolle über die TvElements zu haben, wie z. B. Targeting für Befehle wie MediaCommands.Play, da ich nur einen Bezug auf das ContentPresenter oder sein gebundenes Channel Objekt habe.

Im Idealfall würde Ich mag die Lage sein, eine dieser TvPlayer s einzustellen als CommandTarget ein Button (das wird wahrscheinlich außerhalb der DataTemplate sein). Allerdings bin ich mir nicht sicher, wie ich das machen soll (oder ob das überhaupt eine gute Idee ist - es fühlt sich hackig und fehleranfällig an, nach einem bestimmten Steuerelement zu suchen).

Ich fühle mich wie ich etwas vermisse oder dies in die falsche Richtung geht. Hat jemand irgendwelche Ratschläge oder Vorschläge, wie ich ein generisches (vorzugsweise deklaratives) Mittel zur Handhabung von Kanälen erreichen kann, ohne die Fähigkeit zu verlieren, Befehle auf dem Spieler auszuführen?

Antwort

1

Sie könnten versuchen, das Loaded-Ereignis zu verwenden, um ein Feld in Ihrem Code festzulegen.

<Window.Resources> 
    <DataTemplate DataType="{x:Type Channels:AnalogChannel}"> 
     <Controls:AnalogTvGraphFileElement 
      AnalogSpecificData="..." Loaded="OnAnalogTvGraphFileElementLoaded"    Channel="{Binding}" /> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type Channels:DigitalChannel}"> 
     <Controls:DigitalTvElement 
      DigitalSpecificData="..." Loaded="OnDigitalTvElementLoaded" 
      Channel="{Binding}" /> 
    </DataTemplate> 
</Window.Resources> 

und die geladenen Methoden werden Ihr Feld in Code hinter gesetzt:

private AnalogTvGraphFileElement analogFileElement; 

private void OnAnalogTvGraphFileElementLoaded(object sender, RoutedEventArgs e) 
{ 
    analogFileElement = (AnalogTvGraphFileElement) sender; 
} 

Also, wenn nötig, werden Sie die richtigen Kontrollen haben, und werden für sich nicht erst suchen.

+0

Danke, ich wusste nicht, dass EventHandlers in DataTemplates gesetzt werden konnte und berücksichtigte das Loaded Event nicht. Ich denke, das wird wie gewünscht funktionieren! – jeffora

+0

Kein Problem, froh, dass ich helfen konnte! – Arcturus

Verwandte Themen