Creare MediaElement da codice con WinRT
Una delle piacevoli novità che ho visto introdotte con WinRT è la possibilità di definire e poter utilizzare oggetti di tipo MediaElement direttamente in codice WinRT, senza quindi passare dalla loro istanziazione in pagine Xaml. Questo comporta due vantaggi concreti:
– evita, come già detto, di dover definire tanti MediaElement nello Xaml, ciascuno con il suo nome. Dico “tanti” perchè se in un pagina dovevate far sentire più suoni (contemporanei o no) dovevate per forza mettere più MediaElement (a meno di non usarne uno solo switchando da un source all’altro)
– miglior utilizzo del MVVM, conseguenza del punto precedente. Nel ViewModel associato ad una pagina posso mandare in play un suono senza aver a che fare con la view corrente
Detto questo, mi sono potuto fare una serie di classi helper:
public static class MediaElementGenerator { public async static Task<MediaElement> Get(string source) { MediaElement result = new MediaElement(); var package = Windows.ApplicationModel.Package.Current; var installedLocation = package.InstalledLocation; var storageFile = await installedLocation.GetFileAsync(source); if (storageFile != null) { var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read); result.SetSource(stream, storageFile.ContentType); } return result; } }
Questa riportata qui sopra è una classe statica che lavora in modo asincrono (async/await) e che restituisce un MediaElement associato ad un source specifico. Il source ovviamente deve essere un qualsiasi Uri, che punta ad un file wav/mp3 incluso come “Content” all’interno della nostra solution.
All’interno dei miei ViewModel utilizzo ciò che mi viene esposto dalla classe ApplicationContext:
private async Task Play(string source) { if (ApplicationContext.Instance.Sound) { if (!this.MediaElements.ContainsKey(source)) { this.MediaElements.Add(source, await MediaElementGenerator.Get(source)); } this.MediaElements[source].Play(); } } public async Task PlayClickButton() { await this.Play("Media\ClickButton.mp3"); } public async Task PlayReady() { await this.Play("Media\Ready.mp3"); }
Gli ultimi due metodi pubblici (PlayClickButton e PlayReady) si appoggiano su Play che invece è privato. Notare che nel metodo Play controllo anche che il suono all’interno dell’applicazione sia attivo: ricordiamoci infatti che è buona norma permettere all’utente di attivare/disattivare i suoni nelle nostre app Windows 8, tramite il pannellino dei settings che va gestito correttamente. Ma questo è forse un tema da affrontare in un altro post.