Dismiss volume slider

Topics: Windows 8 Xaml
Dec 6, 2012 at 2:08 PM
Edited Dec 6, 2012 at 2:09 PM

Hi,

I'd like to be able to dismiss the volume slider when the tapping anywhere in my app other than on the volume slider control itself.  To get this working I added the following to the VolumeButton:

void VolumeButton_Tapped(object sender, TappedRoutedEventArgs e)
{
    e.Handled = true;
}

public void DismissSlider()
{
    // coppied from volumeCollapseTimer_Tick
    if (VolumeSliderElement == null || VolumeSliderElement.InnerFocusState != FocusState.Keyboard)
    {
        IsVolumeVisible = false;
        this.GoToVisualState(VolumeVisibilityStates.Dismissed);
    }
}

and the following code to my sub-class of MediaPlayer:

void Player_Tapped(object sender, TappedRoutedEventArgs e)
{
    GetChildObjectByName<VolumeButton>(this, "VolumeButton").DismissSlider();
}

This works, but is there a better way?  I'd like a solution where I don't have to modify the PlayerFramework code at all.

Thanks,

J

Coordinator
Dec 6, 2012 at 8:45 PM

J, although it's a little "hack-ish", you can should be able to run all of this code without modifying the source. IsVolumeVisible is a public property and you can tell the control to go to another visual state using the VisualStateManager.

For example:

void ProgressivePage_Tapped(object sender, TappedRoutedEventArgs e)
{
    var obj = e.OriginalSource as DependencyObject;
    if (obj != null)
    {
        if (!obj.GetAncestors().OfType<VolumeButton>().Any())
        {
            var volumeButton = player.ControlPanel.GetDescendants().OfType<VolumeButton>().First();
            volumeButton.IsVolumeVisible = false;
            VisualStateManager.GoToState(volumeButton, "VolumeDismissed", true);
        }
    }
}

GetAncestors and GetDescendents are extension methods I threw together:

public static IEnumerable<DependencyObject> GetDescendants(this DependencyObject source)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(source); i++)
    {
        var child = VisualTreeHelper.GetChild(source, i);
        yield return child;
        foreach (var grandChild in GetDescendants(child))
        {
            yield return grandChild;
        }
    }
}

public static IEnumerable<DependencyObject> GetAncestors(this DependencyObject source)
{
    var parent = VisualTreeHelper.GetParent(source);
    if (parent != null)
    {
        yield return parent;
        foreach (var ancestor in GetAncestors(parent))
        {
            yield return ancestor;
        }
    }
}

But... to make this easier in the future, we can add new methods to hide and show the slider so you don't have to know anything about what happens behind the scenes to hide the slider. Look for this change in the next release.

Regards, Tim

Dec 7, 2012 at 8:58 AM

Thanks Tim - that works great.  Will look forward to having a hide method but this fulfills my needs perfectly.  :)