Personalizando nuestro reproductor SMF (y 2) – Play Silverlight

Como decíamos en entradas anteriores, las opciones de extensión de SMF permiten llevar más lejos la interacción del usuario con el reproductor multimedia. Para demostrarlo crearé una prueba de concepto que consistirá en la reproducción de un video en el que, al final del mismo, se muestre una pregunta relacionada con cuatro posibles respuestas.

Creando la plantilla

El primer paso es definir tanto las partes que la conformarán, como los diferentes estados visuales por lo que pasará.

En este sencillo ejemplo solo habrá un única parte, que será un control de tipo Grid y que contendrá un bloque de texto para la pregunta y un botón por cada posible respuesta. En cuanto  a estados visuales, serían dos, uno en el que se mostrará el panel con la pregunta y las posibles respuestas y otro en el que permanecerán ocultos.

Comenzaremos definiendo las partes y estados antes especificados en una nueva clase, que extenderá la clase CoreSmoothStreamingMediaElement, y que llamaremos MyMediaElement. Esta nueva clase tendrá tantos atributos de tipo TemplatePart como partes hayamos identificado, en nuestro caso, sería sólo una que corresponde con un control de tipo Grid. En el caso de los estados visuales, se añadirán dos atributos de tipo TemplateVisualState uno por cada uno de los estados que comentábamos antes. La nueva clase quedaría de este modo:


[TemplatePart(Name = "QuestionPanel", Type = typeof(Grid))]
[TemplateVisualState(Name = "ShowingQuestion", GroupName = "Question")]
[TemplateVisualState(Name = "HidingQuestion", GroupName = "Question")]
public class MyMediaElement : CoreSmoothStreamingMediaElement
 {

 ...
 }

Luego sustituiremos en el xaml el elemento de tipo CoreSmoothStreamingMediaElement, que estaba embebido en el reproductor, y lo sustituiremos por uno de la clase MyMediaElement que acabamos de crear.

        <p:MyPlayer x:Name="player" MarkerData="{Binding MyMarkerData}" Style="{StaticResource VideoPlayerStyle}">
            <s:MyMediaElement SmoothStreamingSource="{Binding VideoUri}"
                                       Style="{StaticResource MediaElementStyle}"
                                       Position="{Binding PlayerPosition, Mode=TwoWay}"
                                       AutoPlay="True" CanSeek="True"
                                       />
        </p:MyPlayer>

El siguiente paso, consiste en crear la plantilla con Expression Blend, para ello, primero localizamos en el árbol de controles del xaml el elemento multimedia que colgará del reproductor para, a continuación, crear una nueva plantilla a partir de una copia del actual. Si nos fijamos en las pestañas Partes y Estados, veremos los atributos que hemos definido en nuestra nueva clase.

Partes y estados visuales

Partes y estados visuales

Con la plantilla ya creada, añadiremos un Grid, cuyo nombre deberá coincidir con el que hemos especificado en el atributo de la clase MyMediaElement, y dentro de éste el bloque de texto con la pregunta y los botones con las respuestas.

Plantilla resultante

Plantilla resultante

Controlando la visualización de los elementos con VisualStateManager

El siguiente paso será controlar la visualización de los elementos que hemos añadido según el estado en que nos encontremos. En la pestaña Estados, veremos el grupo que hemos definido y los dos estados que lo conforman. Al hacer click sobre un estado, se mostrará un indicador con el que se avisa al usuario de que las propiedades que cambie se aplicarán sólo cuando se esté en dicho estado.

Indicador de edición de estado visual

Indicador de edición de estado visual

La idea es ocultar el grid que contiene la pregunta cuando el estado sea “HidingQuestion” y mostrarlo cuando sea “ShowingQuestion”, para lo cual, tan solo cambiaremos la propiedad Visibility a Collapsed, en el primer caso, y a Visible en el segundo.

Ahora toca definir cuándo cambiar el estado visual. El objetivo de esta prueba de concepto era mostrar una pregunta al finalizar el video, por lo que deberemos pasar al estado “HidingQuestion” cuando se produzca el evento MediaEnded. Esa transición entre estados se realiza gracias al método GoToState de la clase estática VisualStateManager, pasando como parámetros la referencia al propio control, el nombre del estado al que se quiere pasar y si se quiere que se realice con una transición o simplemente se cambie el estado.

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    this.MediaEnded += new RoutedEventHandler(CoreMediaElement_MediaEnded);

    VisualStateManager.GoToState(this, "HidingQuestion", true);
}

void CoreMediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
    VisualStateManager.GoToState(this, "ShowingQuestion", true);
}

Llegados a este punto, ya tenemos lista la reproducción del video y la muestra de la pregunta al final del mismo. Ahora queda asociar el evento Click de los botones de respuesta

Aplicando el patrón MVVM

Hasta la aparición de la versión 4, Silverlight no disponía de un sistema de comandos, lo que obligaba a realizar ciertas tareas en el código de la vista. Las propiedades Command y CommandParameter, disponibles en todos los controles que hereden de ButtonBase y Hiperlink, posibilita asociar la vista y modelo-vista, permitiendo aplicar el patrón MVVM.

Para ello, primero añadiremos una propiedad de tipo ICommand en la clase modelo-vista.

public ICommand SelectAnswerCommand { get; set; }

En el constructor de la clase modelo-vista, inicializaremos la propiedad con una instancia de la clase DelegateCommand, incluida en la librería Prism, pasando como parámetro el método que se ejecutará al lanzare el comando.

this.SelectAnswerCommand = new DelegateCommand<string>(OnAnswerSelected);

Por último, ya en el xaml, asociaremos el comando a la propiedad Command del botón y como parámetro simplemente pasaremos un número que identifique la respuesta.

<Button x:Name="btnAnswer1"
Content="{Binding CurrentQuestion.Answers[0]}"
Command="{Binding SelectAnswerCommand}"
CommandParameter="0" />

A continuación, definiremos dos estados que añadiremos como atributos a la clase MyMediaElement que hemos creado anteriormente. Uno en el que estarán visibles la pregunta y las cuatro respuestas (ShowingQuestion) y otro en el que permanecerán ocultos. Ambos pertenecerán al mismo grupo (Question).A continuación, definiremos dos estados que añadiremos como atributos a la clase MyMediaElement que hemos creado anteriormente. Uno en el que estarán visibles la pregunta y las cuatro respuestas (ShowingQuestion) y otro en el que permanecerán ocultos. Ambos pertenecerán al mismo grupo (Question).

Anuncios
Esta entrada fue publicada en Patrones, Silverlight, Silverlight Media Framework y etiquetada , , , , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s