如何从ViewModel中的View中访问和触发MediaElement中的事件?

时间:2015-10-22 01:19:07

标签: c# .net xaml mvvm windows-10

我正在创建一个Windows 10应用,我正在实现语音功能。用户需要能够收听整个语音,用语音响应,然后收到回复。但是,我在制作这个纯粹的MVVM时遇到了麻烦。

好的,对于MediaElement.Ended,我可以使用一种行为,对吧?将Ended行为设置为我自己的命令,它会触发我想要的方法吗?

至于将源设置为合成文本并将AutoPlay设置为true,我可以将它们绑定到我的ViewModel中的属性。

但是,MediaElement.Play()...如果我无法访问MediaElement,如何从ViewModel触发此方法?

我知道我可以做一些" hacks"使其工作或使用代码隐藏,但我的目标是做到这一点"纯粹的MVVM",其中我的ViewModel对视图和任何视图元素一无所知。

感谢任何人的帮助。

1 个答案:

答案 0 :(得分:0)

你可以这样做:

MVVM项目:

-ServiceLocator.cs

public class ServiceLocator
{
    public static ServiceLocator Instance = new ServiceLocator();

    private ServiceLocator()
    {
    }

    private readonly IDictionary<Type, Type> TypeMap = new Dictionary<Type, Type>();

    private readonly IDictionary<Type, object> TypeMapInstances = new Dictionary<Type, object>();

    public void Register<TInterface, TClass>()
    {
        TypeMap.Add(typeof(TInterface), typeof(TClass));
    }

    public void Register<TClass>(object instance)
    {
        TypeMapInstances.Add(typeof(TClass), instance);
    }

    public T GetService<T>()
    {
        Type type = typeof(T);
        object resolvedType = null;

        try
        {
            if (TypeMapInstances.ContainsKey(type))
            {
                resolvedType = TypeMapInstances[type];
            }
            else
            {
                resolvedType = Activator.CreateInstance(TypeMap[type]);
                TypeMapInstances.Add(type, resolvedType);
            }
        }
        catch (Exception)
        {
            return default(T);
            //throw new Exception(string.Format("Could not resolve type {0}", type.FullName));
        }

        return (T)resolvedType;
    }
}

-IMediaElementService.cs

public interface IMediaElementService
{
    void Play();
}

-YourVMClass.cs

public void Foo()
{
    var mediaElementService = ServiceLocator.Instance.GetService<IMediaElementService>();
    mediaElementService.Play();
}

客户项目:

-MediaElementService.cs

public class MediaElementService : IMediaElementService
{
    public void Play()
    {
        App.MediaElement.Play();
    }
}

-App.cs

public static MediaElement MediaElement;

private void OnLaunched(LaunchActivatedEventArgs e)
{
    ServiceLocator.Instance.Register<IMediaElementService, MediaElementService>();
}

-YourView.xaml

<MediaElement x:Name="_mediaElement" />

-YourView.xaml.cs

public YourView(){
    InitializeComponent();
    App.MediaElement = _mediaElement;
}

这就是全部,尽管这只是可以达到同样目的的几种方式之一。