Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何确定MediaElement是否正在播放?_Wpf_Mediaelement - Fatal编程技术网

Wpf 如何确定MediaElement是否正在播放?

Wpf 如何确定MediaElement是否正在播放?,wpf,mediaelement,Wpf,Mediaelement,看起来很简单,但我想不出任何方法来确定MediaElement的状态。有些状态有各种属性(如IsBuffering),但我找不到任何状态的属性,如Play、Pause等。Silverlight似乎有一个CurrentState属性来显示所有这些 目前,我判断视频是否应该播放的方式是观看各种事件和一个计时器,检查是否有任何进展 我不熟悉MediaElement和WPF(实际上我只在WinForms应用程序中使用MediaElement)。我遗漏了什么吗?你没有遗漏任何东西。您几乎必须手动跟踪媒体是

看起来很简单,但我想不出任何方法来确定MediaElement的状态。有些状态有各种属性(如IsBuffering),但我找不到任何状态的属性,如Play、Pause等。Silverlight似乎有一个CurrentState属性来显示所有这些

目前,我判断视频是否应该播放的方式是观看各种事件和一个计时器,检查是否有任何进展


我不熟悉MediaElement和WPF(实际上我只在WinForms应用程序中使用MediaElement)。我遗漏了什么吗?

你没有遗漏任何东西。您几乎必须手动跟踪媒体是否正在播放。很遗憾,正如你提到的,在Silverlight中很容易。对我来说,这似乎是一个重大疏忽。

我所做的是“解决”MediaPlayer子类(这也适用于MediaElement),并添加我自己的播放/暂停/停止方法。在这些方法中,我维护一个表示回放状态的字段。此外,您还需要挂接MediaEnded,以便将状态从“播放”更改为“停止”。

对于WPFMediaElement,以下是我使用的解决方案/解决方法:

bool IsPlaying()
{
    var pos1 = wpfMediaElement.Position;
    System.Threading.Thread.Sleep(1);
    var pos2 = wpfMediaElement.Position;

    return pos2 != pos1;
}

您可以使用反射获取
\u currentState
成员

    private MediaState GetMediaState(MediaElement myMedia)
    {
        FieldInfo hlp = typeof(MediaElement).GetField("_helper", BindingFlags.NonPublic | BindingFlags.Instance);
        object helperObject = hlp.GetValue(myMedia);
        FieldInfo stateField = helperObject.GetType().GetField("_currentState", BindingFlags.NonPublic | BindingFlags.Instance);
        MediaState state = (MediaState)stateField.GetValue(helperObject);
        return state;
    }
这包括播放/暂停,但不会在结束时从“播放”更改为“停止”


您可以通过向
MediaEnded
事件添加事件处理程序,并运行
.Stop()
方法来解决此问题,这样可以正确更改状态(可以通过上述方法拾取)

对于
Silverlight
使用CurrentState检查状态是正在播放还是暂停

 if (YourMediaElementName.CurrentState == MediaElementState.Playing)
 {
     // TODO: when media is playing.
 }

对于
通用Windows 10平台(UWP)

如果您想改用
枚举
,请参见以下内容:

if (yourMediaElement.CurrentState == MediaElementState.Playing)
{
    //nou yourMediaElement is playng
}
对于WPF,请使用以下命令:
var playing=player.Position

并且可以基于Rich S实现扩展

//don't forget
using System.Windows.Controls;
using System.Reflection;


 public static class Util
    {
     public static MediaState GetMediaState(this MediaElement myMedia)
        {
            FieldInfo hlp = typeof(MediaElement).GetField("_helper", BindingFlags.NonPublic | BindingFlags.Instance);
            object helperObject = hlp.GetValue(myMedia);
            FieldInfo stateField = helperObject.GetType().GetField("_currentState", BindingFlags.NonPublic | BindingFlags.Instance);
            MediaState state = (MediaState)stateField.GetValue(helperObject);
            return state;
        }
    }

把它放到CodePlex上。如果你没有时间,我打算,只是不想踩到任何脚趾。那是可怕的解决办法。如果你在UI线程中调用这个方法,整个UI将是forzen。我同意,这不是最好的方法。但我敢打赌,这个世界上没有人会在小程序上意识到这一毫秒。这是亚历克斯·威奇的一个变通办法,我称之为“快脏”,为此我将放弃投票。通过访问隐藏字段来使用隐藏的HeperProperty并不是一个“好的解决方案”。。媒体元素没有状态属性是非常可怕的解决方案。。。也没有人让你在UI线程中调用它。很好的解决方案!除非微软在将来某个时候重新命名这个领域,否则这对我来说是非常有效的。谢谢我看到了重命名的潜在危险,但我们还有什么其他解决方案?下面引用的
CurrentState
在现代完整WPF中不存在。应该注意的是
CurrentState
仅是Silverlight。我已经在WPF GitHub存储库中添加了一个关于此的功能请求。请去竖起大拇指。
//don't forget
using System.Windows.Controls;
using System.Reflection;


 public static class Util
    {
     public static MediaState GetMediaState(this MediaElement myMedia)
        {
            FieldInfo hlp = typeof(MediaElement).GetField("_helper", BindingFlags.NonPublic | BindingFlags.Instance);
            object helperObject = hlp.GetValue(myMedia);
            FieldInfo stateField = helperObject.GetType().GetField("_currentState", BindingFlags.NonPublic | BindingFlags.Instance);
            MediaState state = (MediaState)stateField.GetValue(helperObject);
            return state;
        }
    }