Creación de controles de transporte personalizados

La clase MediaPlayerElement tiene controles de transporte de XAML personalizables para administrar el control del contenido de audio y vídeo dentro de una aplicación de Windows. Aquí se muestra cómo personalizar la plantilla MediaTransportControls. Le mostraremos cómo trabajar con el menú de desbordamiento, agregar un botón personalizado y modificar el control deslizante.

API importantes: MediaPlayerElement, MediaPlayerElement.AreTransportControlsEnabled, MediaTransportControls

Antes de empezar, debes estar familiarizado con las clases MediaPlayerElement y MediaTransportControls. Para obtener más información, consulta la guía de control MediaPlayerElement.

Sugerencia

Los ejemplos de este tema se basan en el ejemplo controles de transporte multimedia. Puede descargar el ejemplo para ver y ejecutar el código completado.

Nota:

MediaPlayerElement solo está disponible en Windows 10, versión 1607 y posteriores. Si vas a desarrollar una aplicación para una versión anterior de Windows 10, tendrás que usar MediaElement en su lugar. Todos los ejemplos de esta página también funcionan con MediaElement .

¿Cuándo debe personalizar la plantilla?

MediaPlayerElement tiene controles de transporte integrados diseñados para funcionar bien sin modificaciones en la mayoría de las aplicaciones de reproducción de vídeo y audio. Los proporciona la clase MediaTransportControls e incluyen botones para reproducir, detener y navegar por medios, ajustar el volumen, alternar pantalla completa, convertir a un segundo dispositivo, habilitar subtítulos , cambiar pistas de audio y ajustar la velocidad de reproducción. MediaTransportControls tiene propiedades que permiten controlar si se muestra y habilita cada botón. También puede establecer la propiedad IsCompact para especificar si los controles se muestran en una fila o dos.

Sin embargo, puede haber escenarios en los que necesite personalizar aún más el aspecto del control o cambiar su comportamiento. Estos son algunos ejemplos:

  • Cambie los iconos, el comportamiento del control deslizante y los colores.
  • Mueva botones de comando menos usados con menos frecuencia a un menú de desbordamiento.
  • Cambie el orden en el que los comandos se eliminan cuando se cambia el tamaño del control.
  • Proporcione un botón de comando que no esté en el conjunto predeterminado.

Nota:

Los botones visibles en la pantalla se quitarán de los controles de transporte integrados en un orden predefinido si no hay suficiente espacio en pantalla. Para cambiar este orden o colocar comandos que no caben en un menú de desbordamiento, deberá personalizar los controles.

Puede personalizar la apariencia del control modificando la plantilla predeterminada. Para modificar el comportamiento del control o agregar nuevos comandos, puede crear un control personalizado derivado de MediaTransportControls.

Sugerencia

Las plantillas de control personalizables son una característica eficaz de la plataforma XAML, pero también hay consecuencias que debes tener en cuenta. Al personalizar una plantilla, se convierte en una parte estática de la aplicación y, por tanto, no recibirá ninguna actualización de plataforma que Microsoft realice en la plantilla. Si Microsoft realiza actualizaciones de plantillas, debe tomar la nueva plantilla y volver a modificarla para obtener las ventajas de la plantilla actualizada.

Estructura de plantilla

ControlTemplate forma parte del estilo predeterminado. Puede copiar este estilo predeterminado en el proyecto para modificarlo. ControlTemplate se divide en secciones similares a otras plantillas de control XAML.

  • La primera sección de la plantilla contiene las definiciones de estilo para los distintos componentes de MediaTransportControls.
  • En la segunda sección se definen los distintos estados visuales que usa MediaTransportControls.
  • La tercera sección contiene la cuadrícula que contiene los distintos elementos MediaTransportControls juntos y define cómo se diseñan los componentes.

Nota:

Para obtener más información sobre cómo modificar plantillas, consulta Plantillas de control. Puedes usar un editor de texto o editores similares en el IDE para abrir los archivos XAML en (Archivos de programa)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\(versión del SDK)\Generic. El estilo y la plantilla predeterminados para cada control se definen en el archivo generic.xaml . Puedes encontrar la plantilla MediaTransportControls en generic.xaml buscando "MediaTransportControls".

En las secciones siguientes, aprenderá a personalizar varios de los elementos principales de los controles de transporte:

  • Slider: permite que un usuario arrastre a través de sus elementos multimedia y también muestra el progreso.
  • CommandBar: contiene todos los botones. Para obtener más información, consulta la sección Anatomía del tema de referencia MediaTransportControls.

Personalización de los controles de transporte

Si desea modificar solo la apariencia de MediaTransportControls, puede crear una copia del estilo y la plantilla de control predeterminados y modificarlo. Sin embargo, si también desea agregar o modificar la funcionalidad del control, debe crear una nueva clase que derive de MediaTransportControls.

Volver a plantillar el control

Para personalizar la plantilla y el estilo predeterminados de MediaTransportControls

  1. Copie el estilo predeterminado de los estilos y plantillas de MediaTransportControls en un ResourceDictionary en el proyecto.
  2. Asigne al estilo un valor x:Key para identificarlo, como este.
<Style TargetType="MediaTransportControls" x:Key="myTransportControlsStyle">
    <!-- Style content ... -->
</Style>
  1. Agregue un objeto MediaPlayerElement con MediaTransportControls a la interfaz de usuario.
  2. Establezca la propiedad Style del elemento MediaTransportControls en el recurso Style personalizado, como se muestra aquí.
<MediaPlayerElement AreTransportControlsEnabled="True">
    <MediaPlayerElement.TransportControls>
        <MediaTransportControls Style="{StaticResource myTransportControlsStyle}"/>
    </MediaPlayerElement.TransportControls>
</MediaPlayerElement>

Para obtener más información sobre cómo modificar estilos y plantillas, consulta Aplicar estilos a controles y plantillas de control.

Creación de un control derivado

Para agregar o modificar la funcionalidad de los controles de transporte, debe crear una nueva clase derivada de MediaTransportControls. Una clase derivada denominada CustomMediaTransportControls se muestra en el ejemplo Controles de transporte multimedia y los ejemplos restantes de esta página.

Para crear una nueva clase derivada de MediaTransportControls

  1. Agrega un nuevo archivo de clase al proyecto.
    • En Visual Studio, seleccione Project Add Class (Agregar clase).> Se abrirá el cuadro de diálogo Agregar nuevo elemento.
    • En el cuadro de diálogo Agregar nuevo elemento, escriba un nombre para el archivo de clase y haga clic en Agregar. (En el ejemplo Controles de transporte multimedia, la clase se denomina CustomMediaTransportControls.
  2. Modifique el código de clase para derivar de la clase MediaTransportControls.
public sealed class CustomMediaTransportControls : MediaTransportControls
{
}
  1. Copie el estilo predeterminado de MediaTransportControls en un ResourceDictionary en el proyecto. Este es el estilo y la plantilla que se modifican. (En el ejemplo Controles de transporte multimedia, se crea una nueva carpeta denominada "Temas" y se agrega un archivo ResourceDictionary denominado generic.xaml).
  2. Cambie targetType del estilo al nuevo tipo de control personalizado. (En el ejemplo, targetType se cambia a local:CustomMediaTransportControls).
xmlns:local="using:CustomMediaTransportControls">
...
<Style TargetType="local:CustomMediaTransportControls">
  1. Establezca DefaultStyleKey de la clase personalizada. Esto indica a la clase personalizada que use un style con un targetType de local:CustomMediaTransportControls.
public sealed class CustomMediaTransportControls : MediaTransportControls
{
    public CustomMediaTransportControls()
    {
        this.DefaultStyleKey = typeof(CustomMediaTransportControls);
    }
}
  1. Agregue un objeto MediaPlayerElement al marcado XAML y agréguele los controles de transporte personalizados. Una cosa que hay que tener en cuenta es que las API para ocultar, mostrar, deshabilitar y habilitar los botones predeterminados siguen funcionando con una plantilla personalizada.
<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>

Ahora puede modificar el estilo de control y la plantilla para actualizar el aspecto del control personalizado y el código de control para actualizar su comportamiento.

Trabajar con el menú de desbordamiento

Puede mover los botones de comando MediaTransportControls a un menú de desbordamiento, de modo que los comandos menos usados estén ocultos hasta que el usuario los necesite.

En la plantilla MediaTransportControls, los botones de comando se encuentran en un elemento CommandBar . La barra de comandos tiene el concepto de comandos principal y secundario. Los comandos principales son los botones que aparecen en el control de forma predeterminada y siempre están visibles (a menos que deshabilite el botón, oculte el botón o no haya suficiente espacio). Los comandos secundarios se muestran en un menú de desbordamiento que aparece cuando un usuario hace clic en el botón de puntos suspensivos (...) . Para obtener más información, consulta el artículo Barras de aplicaciones y barras de comandos.

Para mover un elemento de los comandos principales de la barra de comandos al menú de desbordamiento, debes editar la plantilla de control XAML.

Para mover un comando al menú de desbordamiento:

  1. En la plantilla de control, busque el elemento CommandBar denominado MediaControlsCommandBar.
  2. Agregue una sección SecondaryCommands al XAML para CommandBar. Colóquelo después de la etiqueta de cierre de 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 rellenar el menú con comandos, corte y pegue el XAML para los objetos AppBarButton deseados de PrimaryCommands a SecondaryCommands. En este ejemplo, movemos al PlaybackRateButton menú de desbordamiento.

  2. Agregue una etiqueta al botón y quite la información de estilo, como se muestra aquí. Dado que el menú de desbordamiento está formado por botones de texto, debe agregar una etiqueta de texto al botón y también quitar el estilo que establece el alto y el ancho del botón. De lo contrario, no aparecerá correctamente en el menú de desbordamiento.

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

Importante

Debe hacer visible el botón y habilitarlo para usarlo en el menú de desbordamiento. En este ejemplo, el elemento PlaybackRateButton no está visible en el menú de desbordamiento a menos que la propiedad IsPlaybackRateButtonVisible sea true. No está habilitado a menos que la propiedad IsPlaybackRateEnabled sea true. El establecimiento de estas propiedades se muestra en la sección anterior.

Adición de un botón personalizado

Una razón por la que es posible que quiera personalizar MediaTransportControls es agregar un comando personalizado al control. Tanto si se agrega como un comando principal como un comando secundario, el procedimiento para crear el botón de comando y modificar su comportamiento es el mismo. En el ejemplo Controles de transporte multimedia, se agrega un botón "clasificación" a los comandos principales.

Para agregar un botón de comando personalizado

  1. Cree un objeto AppBarButton y agréguelo a CommandBar en la plantilla de control.
<AppBarButton x:Name="LikeButton"
              Icon="Like"
              Style="{StaticResource AppBarButtonStyle}"
              MediaTransportControlsHelper.DropoutOrder="3"
              VerticalAlignment="Center" />

Debes agregarlo a CommandBar en la ubicación adecuada. (Para obtener más información, vea la sección Trabajar con el menú de desbordamiento). El modo en que se coloca en la interfaz de usuario viene determinado por dónde se encuentra el botón en el marcado. Por ejemplo, si quieres que este botón aparezca como el último elemento en los comandos principales, agrégalo al final de la lista de comandos principal.

También puedes personalizar el icono del botón. Para obtener más información, consulta la referencia AppBarButton.

  1. En la invalidación de OnApplyTemplate, obtenga el botón de la plantilla y registre un controlador para su evento Click. Este código va en la CustomMediaTransportControls clase .
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. Agregue código al controlador de eventos Click para realizar la acción que se produce cuando se hace clic en el botón. Este es el código completo de la clase .
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);
        }
    }
}

Modificación del control deslizante

El control "seek" de MediaTransportControls lo proporciona un elemento Slider. Una manera de personalizarla es cambiar la granularidad del comportamiento de búsqueda.

El control deslizante de búsqueda predeterminado se divide en 100 partes, por lo que el comportamiento de búsqueda se limita a esas muchas secciones. Puedes cambiar la granularidad del control deslizante de búsqueda obteniendo el Control deslizante del árbol visual XAML del controlador de eventos MediaOpened en MediaPlayerElement.MediaPlayer. En este ejemplo se muestra cómo usar VisualTreeHelper para obtener una referencia al control deslizante y, a continuación, cambiar la frecuencia de paso predeterminada del control deslizante del 1 % al 0,1 % (1000 pasos) si el medio es superior a 120 minutos. MediaPlayerElement se denomina 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;
  }
}