媒体传输控件显示和隐藏时如何检测事件

How to detect the event when media transport controls show and hide

我正在使用 MediaPlayerElement。目前,媒体传输控件可以显示和隐藏自身。但是没有事件指示何时显示和隐藏。

有什么解决办法吗?谢谢

<MediaPlayerElement x:Name="viuMediaPlayer" AreTransportControlsEnabled="True">
        <MediaPlayerElement.TransportControls>
            <MediaTransportControls
                x:Name="MediaTransportControls_Custom"/>
        </MediaPlayerElement.TransportControls>
    </MediaPlayerElement>

目前,UWP 不提供 api 来检测传输控件的显示和隐藏。但是你可以检查 MediaTransportControls 样式。隐藏和显示动画匹配的 VisualState 是 ControlPanelFadeInControlPanelFadeOut.

<VisualState x:Name="ControlPanelFadeIn">

    <Storyboard>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ControlPanel_ControlPanelVisibilityStates_Border">
            <EasingDoubleKeyFrame KeyTime="0" Value="0" />
            <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1" />
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimation Storyboard.TargetProperty="Y" Storyboard.TargetName="TranslateVertical" From="50" To="0.5" Duration="0:0:0.3" />
    </Storyboard>
</VisualState>
<VisualState x:Name="ControlPanelFadeOut">

    <Storyboard>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ControlPanel_ControlPanelVisibilityStates_Border">
            <EasingDoubleKeyFrame KeyTime="0" Value="1" />
            <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0" />
        </DoubleAnimationUsingKeyFrames>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="ControlPanel_ControlPanelVisibilityStates_Border">
            <DiscreteObjectKeyFrame KeyTime="0" Value="False" />
        </ObjectAnimationUsingKeyFrames>
        <DoubleAnimation Storyboard.TargetProperty="Y" Storyboard.TargetName="TranslateVertical" From="0.5" To="50" Duration="0:0:0.7" />
    </Storyboard>
</VisualState>

因此您可以检测到 TranslateVertical Y 属性 更改为识别 MediaTransportControls 隐藏或显示状态。

 var PanelGrid = MyFindListViewChildByName(MyControl, "ControlPanelGrid") as Grid;
 var render = PanelGrid.RenderTransform;
 var watcher = new DependencyPropertyWatcher<string>(render, "Y");
 watcher.PropertyChanged += Watcher_PropertyChanged;

private void Watcher_PropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{

    if ((double)e.NewValue == 50)
    {
        System.Diagnostics.Trace.WriteLine("hide");
    }
    else if ((double)e.NewValue == 0.5)
    {
        System.Diagnostics.Trace.WriteLine("show");
    }

}

但是上面是个问题,如果承载上面事件的线程存在,Watcher_PropertyChanged将不可用。

参考工具class

public static DependencyObject MyFindListViewChildByName(DependencyObject parant, string ControlName)
{
    int count = VisualTreeHelper.GetChildrenCount(parant);

    for (int i = 0; i < count; i++)
    {
        var MyChild = VisualTreeHelper.GetChild(parant, i);
        if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName)
            return MyChild;

        var FindResult = MyFindListViewChildByName(MyChild, ControlName);
        if (FindResult != null)
            return FindResult;
    }

    return null;
}


public class DependencyPropertyWatcher<T> : DependencyObject, IDisposable
{
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register(
            "Value",
            typeof(object),
            typeof(DependencyPropertyWatcher<T>),
            new PropertyMetadata(null, OnPropertyChanged));

    public event DependencyPropertyChangedEventHandler PropertyChanged;

    public DependencyPropertyWatcher(DependencyObject target, string propertyPath)
    {
        this.Target = target;
        BindingOperations.SetBinding(
            this,
            ValueProperty,
            new Binding() { Source = target, Path = new PropertyPath(propertyPath), Mode = BindingMode.OneWay });
    }

    public DependencyObject Target { get; private set; }

    public T Value
    {
        get { return (T)this.GetValue(ValueProperty); }
    }

    public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        DependencyPropertyWatcher<T> source = (DependencyPropertyWatcher<T>)sender;

        if (source.PropertyChanged != null)
        {
            source.PropertyChanged(source.Target, args);
        }
    }

    public void Dispose()
    {
        this.ClearValue(ValueProperty);
    }
}

当然,更好的是 post 您在 UserVoice 中的要求向我们的团队询问此新功能。