2010-11-23 2 views
1

Я работаю над проектом, который включает в себя воспроизведение телевизора с карты тюнера в приложении WPF. В последнее время я переписывал возможности воспроизведения ТВ для работы с WPF MediaKit, чтобы обеспечить более бесшовное взаимодействие (ранее я использовал WindowsFormsHost и элемент управления WinForms в качестве цели рендеринга DirectShow, что привело к возникновению всех обычных проблем с воздушным пространством).Настройка элемента управления в DataTemplate как CommandTarget кнопки за пределами шаблона

Программное обеспечение играет аналоговое и цифровое телевидение, и как они обрабатываются по-другому, я создал Player и MediaElement для обоих (DigitalTvPlayer, DigitalTvElement, AnalogTvPlayer, AnalogTvElement), проходящие от соответствующих MediaKit классов MediaPlayerBase и MediaElementBase.

Все эти элементы управления работают, но теперь я ищу способ иметь одно «окно ТВ-плеера», которое может содержать список каналов (сочетание аналогового и цифрового) и автоматически обрабатывать переключение между ними, выбирая соответствующий игрок.

Моя первая попытка сделать это участие, используя ContentPresenter привязанный к выбранному каналу, и конкретный DataTemplate для каждого типа канала:

<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> 

Со следующим телом окна:

<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> 

Хотя этот подход «работает» (воспроизведение телевизора, оно автоматически переключается между аналоговым и цифровым и т. д.), я теряю возможность прямого управления TvElements, например, нацеливать их на команды, такие как MediaCommands.Play, так как у меня есть только ссылка на ContentPresenter или его связанный объект Channel.

В идеале я хотел бы иметь возможность установить один из этих TvPlayer с как CommandTarget в виде Button (что, вероятно, будет за пределами DataTemplate). Тем не менее, я не уверен, как это сделать (или это даже хорошая идея - он чувствует себя взломанным и подверженным ошибкам поиска DataTemplate, который ищет конкретный элемент управления).

Мне кажется, что я что-то упустил или поступил неправильно. Есть ли у кого-нибудь какие-либо советы или предложения о том, как я могу получить общее (желательно декларативное) средство обработки каналов, не теряя возможности выполнять команды на плеере?

ответ

1

Вы можете попытаться использовать событие Loaded, чтобы установить поле в своем коде позади.

<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> 

и загруженные методы будут установить поле в коде:

private AnalogTvGraphFileElement analogFileElement; 

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

Так, при необходимости, вы будете иметь правильные элементы управления, а также не придется искать их в первую очередь.

+0

Спасибо, я не знал, что EventHandlers можно установить в DataTemplates и не учитывать событие Loaded. Я думаю, что это сработает по мере необходимости! – jeffora 2010-11-23 22:51:09

Смежные вопросы