用于 Windows Phone 8 和 Windows 8 的 MVVM 中的计时器 [英] Timer in MVVM for Windows Phone 8 and Windows 8

查看:21
本文介绍了用于 Windows Phone 8 和 Windows 8 的 MVVM 中的计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个适用于 Windows Phone 8 和 Windows 8 的通用/便携式 C# 库.该库将由每个平台的应用程序引用.库中有一个视图模型,我试图在视图模型中放置一个计时器.两个平台的库中唯一可用的计时器"是 System.Threading.Timer(无 DispatcherTimer).但是,我无法解决跨线程问题.有没有办法做到这一点,还是我必须在后面的页面代码中的每个应用程序中创建一个计时器?

I have a Universal/Portable C# library for Windows Phone 8 and Windows 8. The library will be referenced by apps for each platform. In the library is a view model and I'm trying to put a timer in the view model. The only "Timer" available in the library for both platforms is the System.Threading.Timer (no DispatcherTimer). However, I cannot work around the cross threading issues. Is there a way to do this or do I have to create a timer in each app in the page code behind?

public class DefaultViewModel : INotifyPropertyChanged
{
    System.Threading.Timer _Timer;

    public DefaultViewModel()
    {
        this.ToggleStartStopCommand = new Command(ToggleStartStop, true);
    }

    private TimeSpan _Duration;
    public TimeSpan Duration
    {
        get { return this._Duration; }
        set
        {
            if (value != this._Duration)
            {
                this._Duration = value;
                this.RaisePropertyChanged("Duration"); // Error occurs here
            }
        }
    }

    private bool _IsRunning;
    public bool IsRunning
    {
        get { return this._IsRunning; }
        set
        {
            if (value != this._IsRunning)
            {
                this._IsRunning = value;
                this.RaisePropertyChanged("IsRunning");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if (null != propertyChanged)
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public void Start()
    {
        this.IsRunning = true;
        this._Timer = new Timer(TimerTick, this, 0, 1000);
    }

    private DateTime _StartTime;
    public DateTime StartTime
    {
        get { return this._StartTime; }
        set
        {
            if (value != this._StartTime)
            {
                this._StartTime = value;
                this.RaisePropertyChanged("StartTime");
            }
        }
    }

    public void Stop()
    {
        this._Timer.Dispose();
        this.IsRunning = false;
    }

    private void TimerTick(object o)
    {
        var defaultViewModel = (DefaultViewModel)o;
        defaultViewModel.Duration = DateTime.Now - defaultViewModel.StartTime;
    }

    public void ToggleStartStop()
    {
        if (this.IsRunning)
            this.Stop();
        else
            this.Start();
    }

    public Command ToggleStartStopCommand { get; private set; }
}

推荐答案

两个可能的解决方案:

  1. 如果您的目标是 Windows 8 和 Windows Phone 8.1(不是 Phone 8.0 Silverlight),请考虑使用包含共享项目的通用应用 而不是便携式类库来托管您的 Viewmodel.共享项目仅与 WinRT 项目兼容,但支持完整的 WinRT 框架.在这种情况下,直接在 Viewmodel 中实例化 DispatcherTimer 应该不成问题.

  1. If you're targeting Windows 8 and Windows Phone 8.1 (not Phone 8.0 Silverlight), consider using a Universal App containing a Shared Project instead of a Portable Class Library to host your Viewmodels. Shared projects are only compatible with WinRT projects, but support the full WinRT framework. In that case, it should not be a problem to instantiate a DispatcherTimer directly within the Viewmodel.

否则(在真正的可移植类库中),恐怕唯一的方法是在提供最重要定时器功能的 PCL 中创建一个接口,以及实现此接口的两个特定于平台的定时器类.实际上,除了文件开头的 using 语句外,这两个实现是相同的,因为 Windows Phone Silverlight 的 DispatcherTimer 位于 System.Windows 中.Threading 命名空间,而在 WinRT 上它位于 Windows.UI.Xaml,但两者都具有相同的功能 - 所以它基本上是一个复制/粘贴工作.

Otherwise (within a real Portable Class Library), I'm afraid the only way is to create an interface within the PCL that provides the most important timer functions, and two platform-specific timer classes that implement this interface. In practice, these two implementations will be identical except for the using statements at the beginning of the file, because Windows Phone Silverlight's DispatcherTimer lives within the System.Windows.Threading namespace while on WinRT it's located at Windows.UI.Xaml but both have the same functionality - so it's basically a copy/paste job.

作为 MVVMbasics 框架的一部分,我已经意识到这样一个拆分的实现,也许 Codeplex 上的可用资源 很有帮助!

I've realized such a splitted implementation as part of the MVVMbasics framework, maybe the sources avaiable at Codeplex are of any help!

这篇关于用于 Windows Phone 8 和 Windows 8 的 MVVM 中的计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆