Fix: Silverlight Media Framework Player VolumeElement out of sync
I was just adding a storable (persistent) Volume property to the MediaPlayerView class used at ClipFlair’s MediaPlayerWindow (connected to the underlying SMF player’s VolumeLevel property), when I realized that after reloading saved state, the SMF player’s Volume control would show a different value than the value set to it (which I could confirm by flipping the MediaPlayer control and looking at its properties on the backpanel that the ClipFlair app features for each component and for the activity container itself).
It seems to be some bug in the SMF logic or in its default template, since the following fix makes the issue disappear. The trick is that at a descendent class from SMFPlayer (like the MediaPlayer class that ClipFlair’s MediaPlayerWindow uses), one can override the OnApplyTemplate method (a standard method in templated XAML-based controls at Silverlight and WPF) and call the UpdateVolumeElement method shown below.
That method temporarily sets the volume to another value than its current one (this is important, just setting again to the same value would be ignored), then set again the current value to force the VolumeElement control’s UI to update.
//Project: ClipFlair (http://ClipFlair.codeplex.com) //Filename: MediaPlayer.cs //Version: 20130211 using System; using System.Linq; using System.Windows; using System.Windows.Media; using Microsoft.SilverlightMediaFramework.Core; using Microsoft.SilverlightMediaFramework.Core.Media; using Microsoft.SilverlightMediaFramework.Core.Accessibility.Captions; using Microsoft.SilverlightMediaFramework.Plugins.Primitives; namespace ClipFlair.MediaPlayer { public class MediaPlayer : SMFPlayer { public override void OnApplyTemplate() { base.OnApplyTemplate(); //... UpdateVolumeElement(); //patch for SMF bug } protected void UpdateVolumeElement() { //patch for SMF to update VolumeElement UI with any already set VolumeLevel double volume = VolumeLevel; VolumeLevel = (volume == 1) ? 0.9 : 1; VolumeLevel = volume; } //...
Update: While submitting this as a bug to SMF source site on Codeplex it came to me that I could try setting the VolumeElement’s VolumeLevel value directly at ApplyTemplate and indeed it works:
protected void UpdateVolumeElement()
{
//patch for SMF to update VolumeElement UI with any already set VolumeLevel
VolumeElement.VolumeLevel = VolumeLevel;
}