Criar controles de transporte personalizados

MediaPlayerElement tem controles de transporte XAML personalizáveis para gerenciar o controle de conteúdo de áudio e vídeo em um aplicativo do Windows. Aqui, demonstramos como personalizar o modelo MediaTransportControls. Mostraremos como trabalhar com o menu flutuante, adicionar um botão personalizado e modificar o controle deslizante.

APIs importantes: MediaPlayerElement, MediaPlayerElement.AreTransportControlsEnabled, MediaTransportControls

Antes de começar, você deve estar familiarizado com as classes MediaPlayerElement e MediaTransportControls. Para obter mais informações, consulte o guia de controle MediaPlayerElement.

Dica

Os exemplos neste tópico são baseados no exemplo de Controles de Transporte de Mídia. Você pode baixar o exemplo para exibir e executar o código concluído.

Observação

MediaPlayerElement só está disponível no Windows 10, versão 1607 e posterior. Se estiver desenvolvendo um aplicativo para uma versão anterior do Windows 10, você precisará usar MediaElement. Todos os exemplos nesta página também funcionam com MediaElement .

Quando você deve personalizar o modelo?

MediaPlayerElement tem controles de transporte internos projetados para funcionar bem sem modificação na maioria dos aplicativos de reprodução de vídeo e áudio. Eles são fornecidos pela classe MediaTransportControls e incluem botões para reproduzir, parar e navegar na mídia, ajustar o volume, alternar a tela inteira, transmitir para um segundo dispositivo, habilitar legendas, alternar faixas de áudio e ajustar a taxa de reprodução. MediaTransportControls tem propriedades que permitem controlar se cada botão é mostrado e habilitado. Você também pode definir a propriedade IsCompact para especificar se os controles são mostrados em uma linha ou duas.

No entanto, pode haver cenários em que você precise personalizar ainda mais a aparência do controle ou alterar seu comportamento. Estes são alguns exemplos:

  • Altere os ícones, o comportamento do controle deslizante e as cores.
  • Mova os botões de comando menos usados para um menu flutuante.
  • Altere a ordem em que os comandos são descartados quando o controle é redimensionado.
  • Forneça um botão de comando que não esteja no conjunto padrão.

Observação

Os botões visíveis na tela sairão dos controles de transporte integrados em uma ordem predefinida se não houver espaço suficiente na tela. Para alterar essa ordem ou colocar comandos que não se encaixam em um menu flutuante, você precisará personalizar os controles.

Você pode personalizar a aparência do controle modificando o modelo padrão. Para modificar o comportamento do controle ou adicionar novos comandos, você pode criar um controle personalizado derivado de MediaTransportControls.

Dica

Os modelos de controle personalizáveis são um recurso poderoso da plataforma XAML, mas também há consequências que você deve levar em consideração. Quando você personaliza um modelo, ele se torna uma parte estática do seu aplicativo e, portanto, não receberá nenhuma atualização de plataforma feita no modelo pela Microsoft. Se as atualizações de modelo forem feitas pela Microsoft, você deverá pegar o novo modelo e modificá-lo novamente para obter os benefícios do modelo atualizado.

Estrutura do modelo

O ControlTemplate faz parte do estilo padrão. Você pode copiar esse estilo padrão em seu projeto para modificá-lo. O ControlTemplate é dividido em seções semelhantes a outros modelos de controle XAML.

  • A primeira seção do modelo contém as definições de estilo para os vários componentes do MediaTransportControls.
  • A segunda seção define os vários estados visuais usados pelo MediaTransportControls.
  • A terceira seção contém o Grid que contém vários elementos MediaTransportControls juntos e define como os componentes são dispostos.

Observação

Para obter mais informações sobre como modificar modelos, consulte Modelos de controle. Você pode usar um editor de texto ou editores semelhantes em seu IDE para abrir os arquivos XAML em (Arquivos de Programas)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\(versão do SDK)\Generic. O estilo e o modelo padrão para cada controle são definidos no arquivo generic.xaml . Você pode encontrar o modelo MediaTransportControls em generic.xaml pesquisando "MediaTransportControls".

Nas seções a seguir, você aprenderá a personalizar vários dos principais elementos dos controles de transporte:

  • Slider: permite que um usuário navegue em sua mídia e também exibe o progresso
  • CommandBar: contém todos os botões. Para obter mais informações, consulte a seção Anatomia do tópico de referência MediaTransportControls.

Personalizar os controles de transporte

Se você quiser modificar apenas a aparência do MediaTransportControls, poderá criar uma cópia do estilo e do modelo de controle padrão e modificá-la. No entanto, se você também quiser adicionar ou modificar a funcionalidade do controle, precisará criar uma nova classe derivada de MediaTransportControls.

Remodelar o controle

Para personalizar o modelo e o estilo padrão MediaTransportControls

  1. Copie o estilo padrão dos estilos e modelos MediaTransportControls para um ResourceDictionary em seu projeto.
  2. Dê ao Style um valor x:Key para identificá-lo, assim.
<Style TargetType="MediaTransportControls" x:Key="myTransportControlsStyle">
    <!-- Style content ... -->
</Style>
  1. Adicione um MediaPlayerElement com MediaTransportControls à sua interface do usuário.
  2. Defina a propriedade Style do elemento MediaTransportControls como seu recurso Style personalizado, conforme mostrado aqui.
<MediaPlayerElement AreTransportControlsEnabled="True">
    <MediaPlayerElement.TransportControls>
        <MediaTransportControls Style="{StaticResource myTransportControlsStyle}"/>
    </MediaPlayerElement.TransportControls>
</MediaPlayerElement>

Para obter mais informações sobre como modificar estilos e modelos, consulte Controles de estilo e Modelos de controle.

Criar um controle derivado

Para adicionar ou modificar a funcionalidade dos controles de transporte, você deve criar uma nova classe derivada de MediaTransportControls. Uma classe derivada chamada CustomMediaTransportControls é mostrada no exemplo de Controles de Transporte de Mídia e nos exemplos restantes nesta página.

Para criar uma nova classe derivada de MediaTransportControls

  1. Adicione um novo arquivo de classe ao projeto.
    • No Visual Studio, selecione Adicionar Classe do Projeto > . A caixa de diálogo Adicionar Novo Item é aberta.
    • Na caixa de diálogo Adicionar Novo Item, insira um nome para o arquivo de classe e clique em Adicionar. (No exemplo de Controles de Transporte de Mídia, a classe é chamada CustomMediaTransportControls.)
  2. Modifique o código da classe para derivar da classe MediaTransportControls.
public sealed class CustomMediaTransportControls : MediaTransportControls
{
}
  1. Copie o estilo padrão de MediaTransportControls em um ResourceDictionary em seu projeto. Este é o estilo e o modelo que você modifica. (No exemplo de Controles de Transporte de Mídia, uma nova pasta chamada "Themes" é criada e um arquivo ResourceDictionary chamado generic.xaml é adicionado a ela.)
  2. Altere o TargetType do estilo para o novo tipo de controle personalizado. (No exemplo, o TargetType é alterado para local:CustomMediaTransportControls.)
xmlns:local="using:CustomMediaTransportControls">
...
<Style TargetType="local:CustomMediaTransportControls">
  1. Defina o DefaultStyleKey da sua classe personalizada. Isso informa à classe personalizada para usar um Style com um TargetType de local:CustomMediaTransportControls.
public sealed class CustomMediaTransportControls : MediaTransportControls
{
    public CustomMediaTransportControls()
    {
        this.DefaultStyleKey = typeof(CustomMediaTransportControls);
    }
}
  1. Adicione um MediaPlayerElement à sua marcação XAML e adicione os controles de transporte personalizados a ele. Uma coisa a observar é que as APIs para ocultar, mostrar, desabilitar e habilitar os botões padrão ainda funcionam com um modelo personalizado.
<MediaPlayerElement Name="MediaPlayerElement1" AreTransportControlsEnabled="True" Source="video.mp4">
    <MediaPlayerElement.TransportControls>
        <local:CustomMediaTransportControls x:Name="customMTC"
                                            IsFastForwardButtonVisible="True"
                                            IsFastForwardEnabled="True"
                                            IsFastRewindButtonVisible="True"
                                            IsFastRewindEnabled="True"
                                            IsPlaybackRateButtonVisible="True"
                                            IsPlaybackRateEnabled="True"
                                            IsCompact="False">
        </local:CustomMediaTransportControls>
    </MediaPlayerElement.TransportControls>
</MediaPlayerElement>

Agora você pode modificar o estilo e o modelo de controle para atualizar a aparência do controle personalizado e o código de controle para atualizar seu comportamento.

Trabalhando com o menu flutuante

Você pode mover os botões de comando MediaTransportControls para um menu flutuante, para que os comandos menos usados fiquem ocultos até que o usuário precise deles.

No modelo MediaTransportControls, os botões de comando estão contidos em um elemento CommandBar . A barra de comandos tem o conceito de comandos primários e secundários. Os comandos primários são os botões que aparecem no controle por padrão e estão sempre visíveis (a menos que você desabilite o botão, oculte o botão ou não haja espaço suficiente). Os comandos secundários são mostrados em um menu flutuante que aparece quando um usuário clica no botão de reticências (...). Para obter mais informações, consulte o artigo Barras de aplicativos e barras de comandos .

Para mover um elemento dos comandos primários da barra de comandos para o menu de estouro, você precisa editar o modelo de controle XAML.

Para mover um comando para o menu de estouro:

  1. No modelo de controle, localize o elemento CommandBar chamado MediaControlsCommandBar.
  2. Adicione uma seção SecondaryCommands ao XAML para o CommandBar. Coloque-o após a tag de fechamento para os PrimaryCommands.
<CommandBar x:Name="MediaControlsCommandBar" ... >  
  <CommandBar.PrimaryCommands>
...
    <AppBarButton x:Name='PlaybackRateButton'
                    Style='{StaticResource AppBarButtonStyle}'
                    MediaTransportControlsHelper.DropoutOrder='4'
                    Visibility='Collapsed'>
      <AppBarButton.Icon>
        <FontIcon Glyph="&#xEC57;"/>
      </AppBarButton.Icon>
    </AppBarButton>
...
  </CommandBar.PrimaryCommands>
<!-- Add secondary commands (overflow menu) here -->
  <CommandBar.SecondaryCommands>
    ...
  </CommandBar.SecondaryCommands>
</CommandBar>
  1. Para preencher o menu com comandos, recorte e cole o XAML para os objetos AppBarButton desejados de PrimaryCommands para SecondaryCommands. Neste exemplo, movemos o PlaybackRateButton para o menu de estouro.

  2. Adicione um rótulo ao botão e remova as informações de estilo, conforme mostrado aqui. Como o menu flutuante é composto por botões de texto, você deve adicionar um rótulo de texto ao botão e também remover o estilo que define a altura e a largura do botão. Caso contrário, ele não aparecerá corretamente no menu flutuante.

<CommandBar.SecondaryCommands>
    <AppBarButton x:Name='PlaybackRateButton'
                  Label='Playback Rate'>
    </AppBarButton>
</CommandBar.SecondaryCommands>

Importante

Você ainda deve tornar o botão visível e habilitá-lo para usá-lo no menu flutuante. Neste exemplo, o elemento PlaybackRateButton não está visível no menu de estouro, a menos que a propriedade IsPlaybackRateButtonVisible seja true. Ele não está habilitado a menos que a propriedade IsPlaybackRateEnabled seja true. A configuração dessas propriedades é mostrada na seção anterior.

Adicionando um botão personalizado

Um motivo pelo qual você pode querer personalizar MediaTransportControls é adicionar um comando personalizado ao controle. Se você adicioná-lo como um comando principal ou secundário, o procedimento para criar o botão de comando e modificar seu comportamento é o mesmo. No exemplo de Controles de Transporte de Mídia, um botão "classificação" é adicionado aos comandos principais.

Para adicionar um botão de comando personalizado

  1. Crie um objeto AppBarButton e adicione-o ao CommandBar no modelo de controle.
<AppBarButton x:Name="LikeButton"
              Icon="Like"
              Style="{StaticResource AppBarButtonStyle}"
              MediaTransportControlsHelper.DropoutOrder="3"
              VerticalAlignment="Center" />

É necessário adicioná-lo à CommandBar na localização correta. (Para obter mais informações, consulte a seção Trabalhando com o menu flutuante.) A forma como ele é posicionado na interface do usuário é determinada por onde o botão está na marcação. Por exemplo, se você quiser que o botão apareça como o último elemento nos comandos principais, adicione-o no fim da lista de comandos principais.

Também é possível personalizar o ícone do botão. Para saber mais, confira a referência AppBarButton.

  1. Na substituição OnApplyTemplate, obtenha o botão do modelo e registre um manipulador para seu evento Click. Este código vai na CustomMediaTransportControls classe.
public sealed class CustomMediaTransportControls :  MediaTransportControls
{
    // ...

    protected override void OnApplyTemplate()
    {
        // Find the custom button and create an event handler for its Click event.
        var likeButton = GetTemplateChild("LikeButton") as Button;
        likeButton.Click += LikeButton_Click;
        base.OnApplyTemplate();
    }

    //...
}
  1. Adicione código ao manipulador de eventos Click para executar a ação que ocorre quando o botão é clicado. Aqui está o código completo para a aula.
public sealed class CustomMediaTransportControls : MediaTransportControls
{
    public event EventHandler< EventArgs> Liked;

    public CustomMediaTransportControls()
    {
        this.DefaultStyleKey = typeof(CustomMediaTransportControls);
    }

    protected override void OnApplyTemplate()
    {
        // Find the custom button and create an event handler for its Click event.
        var likeButton = GetTemplateChild("LikeButton") as Button;
        likeButton.Click += LikeButton_Click;
        base.OnApplyTemplate();
    }

    private void LikeButton_Click(object sender, RoutedEventArgs e)
    {
        // Raise an event on the custom control when 'like' is clicked.
        var handler = Liked;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

Modificando o controle deslizante

O controle "seek" do MediaTransportControls é fornecido por um elemento Slider . Uma maneira de personalizá-lo é alterar a granularidade do comportamento de busca.

O controle deslizante de busca padrão é dividido em 100 partes, portanto, o comportamento de busca é limitado a esse número de seções. Você pode alterar a granularidade do controle deslizante de busca obtendo o Slider da árvore visual XAML no manipulador de eventos MediaOpened em MediaPlayerElement.MediaPlayer. Este exemplo mostra como usar o VisualTreeHelper para obter uma referência ao controle deslizante e, em seguida, alterar a frequência de etapa padrão do controle deslizante de 1% para 0,1% (1000 etapas) se a mídia tiver mais de 120 minutos. O MediaPlayerElement é denominado MediaPlayerElement1.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  MediaPlayerElement1.MediaPlayer.MediaOpened += MediaPlayerElement_MediaPlayer_MediaOpened;
  base.OnNavigatedTo(e);
}

private void MediaPlayerElement_MediaPlayer_MediaOpened(object sender, RoutedEventArgs e)
{
  FrameworkElement transportControlsTemplateRoot = (FrameworkElement)VisualTreeHelper.GetChild(MediaPlayerElement1.TransportControls, 0);
  Slider sliderControl = (Slider)transportControlsTemplateRoot.FindName("ProgressSlider");
  if (sliderControl != null && MediaPlayerElement1.NaturalDuration.TimeSpan.TotalMinutes > 120)
  {
    // Default is 1%. Change to 0.1% for more granular seeking.
    sliderControl.StepFrequency = 0.1;
  }
}