Установка элемента управления в шаблоне данных как CommandTarget для кнопки вне шаблона - PullRequest
1 голос
/ 23 ноября 2010

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

Программное обеспечение воспроизводит как аналоговое, так и цифровое телевидение, и, поскольку они обрабатываются по-разному, я создал 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 s как CommandTarget из Button (который, вероятно, будет вне DataTemplate). Тем не менее, я не уверен, как это сделать (или даже если это хорошая идея - это кажется хакерским и склонным к ошибкам при поиске DataTemplate в поисках определенного элемента управления).

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

1 Ответ

1 голос
/ 23 ноября 2010

Вы можете попытаться использовать событие 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;
}

Поэтому при необходимости у вас будут правильные элементы управления, и вам не придется их искатьпервый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...