来自ViewModel的RelayCommand& DispatchTimer

时间:2014-09-05 22:03:59

标签: c# wpf mvvm viewmodel relaycommand

下午好,

我试图在viewmodel中触发ICommand ...从viewmodel而不是从UI。

该命令在UI xaml中运行良好,但是,在这种不同的情况下,它没有。

private DispatcherTimer telTimer;

public RelayCommand StartT_Command { get { return new RelayCommand(Exe_StartT_Command); } }

void Exe_StartT_Command(object parameter)
{
   if (telTimer != null && telTimer.IsEnabled)
   {
      telTimer.Stop();
      return;
   }
   telTimer = new DispatcherTimer();
   telTimer.Tick += new EventHandler(TelTimerTick);
   telTimer.Interval = new TimeSpan(0, 0, 0, 0, 10);
   telTimer.Start();
}

private void TelTimerTick(object sender, EventArgs e) //Every Tick
{
        Data.Te(Td);
}

就像我说的,它从UI运行良好,然而,当被调用(见下文)时,它一直运行telTimer.Start();然后......没有。

void KeyDown(int vKey)
{
   if (vKey == 0x6A) //Num Pad * Key
   {
      this.StartT_Command.Execute(null);
   }
}

任何想法??

提前致谢。

EDIT1:我检查了.IsEnabled,启用了定时器IS。但是,TelTimerTick()没有运行。

EDIT2:我没有提到KeyDown是从不同的Thread调用的。这对影响TelTimerTick()的事件有影响吗?

1 个答案:

答案 0 :(得分:2)

我不确定我是否关注,但是如果你只是想从你的viewmodel中调用一些命令?

正如MvGarnagle在他的回答中指出的那样,你每次都会分配一个新的命令,做他做的事情或者:

private ICommand startCommand;
public ICommand StartTCommand
{
   get { return startCommand ?? (startCommand = new RelayCommand(ExeStartTCommand)); }
}

修改     DispatcherTimer telTimer; //未分配     void ExeStartTCommand()     {         //可能为空         如果telTimer!= null&& telTimer.IsEnabled)         {            telTimer.Stop();            返回;          }          telTimer = new DispatcherTimer();          telTimer.Tick + = TelTimerTick;          telTimer.Interval = new TimeSpan(0,0,0,0,10);          telTimer.Start();     }

private void TelTimerTick(object sender, EventArgs e) //Every Tick
{
    Data.Te(Td);
}

在你的viewmodel中直接调用ExeStartTCommand,不要激活命令,不需要这样做。 现在,如果这是一个类似于自定义控件的DO,则必须触发命令,以便使用控件的视图将使用这些命令或更常见的路由事件。

修改

现在代码

// how is this hooked up? W32 wrap?
void KeyDown(int vKey)
{
   if (vKey == 0x6A) //Num Pad * Key
     // Have the dispatchers in your viewmodelbaseclass, this is just for simplicity
     App.Current.Dispatcher.BeginInvoke(new Action(ExeStartTCommand)); 
}

您的基类中应该有一个Dispatcher,它设置为您希望它运行的调度程序,并使用该属性而不是上面的属性。如果你正在处理一个线程问题,我需要你更多的背景,在黑暗中拍摄:)

干杯,

了Stian