У меня есть универсальная/портативная библиотека C# для Windows Phone 8 и Windows 8. На библиотеку будут ссылаться приложения для каждой платформы. В библиотеке есть модель представления, и я пытаюсь поместить таймер в модель представления. Единственным «таймером», доступным в библиотеке для обеих платформ, является System.Threading.Timer (без DispatcherTimer). Однако я не могу обойти проблемы с перекрестными потоками. Есть ли способ сделать это или мне нужно создать таймер в каждом приложении в коде страницы?Таймер в MVVM для Windows Phone 8 и Windows 8
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; }
}
В моем представлении базовый класс модели в PCL Я использую метод 'protected abstract void DispatcherInvoke (Action action)', который реализуется производными классами класса модели, ориентированными на платформу. – Clemens