提问者:小点点

当视图关闭时,如何停止viewmodel中的dispatchtimer?


我想在视图关闭时关闭ViewModel内的计时器。

我的代码:

主流indow.xaml.cs:

 public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new UnitViewModel();
            Console.WriteLine(System.AppDomain.CurrentDomain.BaseDirectory);
        }

UnitViewModel。反恐精英

class UnitViewModel : ObservableObject
    {
        DispatcherTimer dispatcherTimer = new DispatcherTimer();
  public UnitViewModel()
        {
          StartTimer();
        }

        private void StartTimer()
        {
            dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
            dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 600);
            dispatcherTimer.Start();
        }

        private void dispatcherTimer_Tick(object sender, EventArgs e)
        {
            UpdateUnit();
        }
}

当主窗口关闭时,有没有办法停止此计时器?或者不再打开。我更喜欢在我的viewModel中包含这段代码,有没有一种好的方法可以在MVVM中解决这个问题?


共3个答案

匿名用户

向视图模型添加某种类型的公共API以停止计时器:

public void Stop() => dispatcherTimer.Stop();

从视图中以某种方式调用此方法。

例如,您可以在代码隐藏中处理事件或重写方法:

protected override void OnClosing(CancelEventArgs e)
{
    base.OnClosing(e);
    (DataContext as UnitViewModel)?.Stop();
}

...或者在调用命令的XAML标记中使用EventTrigger

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Closing" >
        <i:InvokeCommandAction Command="{Binding StopCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

这两种方法都符合MVVM设计模式。

匿名用户

只需将窗口传递给ViewModel并将关闭事件绑定到OnClosing方法:

public class UnitViewModel
{
    public UnitViewModel(Window w)
    {
        mainWindow = w;
        mainWindow.Closing += OnMainWindowClosing;
    }

    private Window mainWindow;

    private void OnMainWindowClosing(object sender, EventArgs e)
    {
        dispatcherTimer.Stop();
        //anything else you want
    }
}
public MainWindow()
{
    InitializeComponent();
    this.DataContext = new UnitViewModel(MainWindow);
    Console.WriteLine(System.AppDomain.CurrentDomain.BaseDirectory);
}

匿名用户

就我个人而言,我根本不会在viewmodel中使用dispatcher计时器。我可能会使用异步和循环。600毫秒的延迟将由

await Task.Delay(600);

这将是一个最好的循环。

我也会首先在一个窗口应用程序中使用view模型,这样视图就可以从该view模型中模板化。处置视图模型,视图就会消失。

如果它绝对必须是一个带有viewmodel的单独窗口,则使viewmodel成为该视图的私有成员。关闭窗口,viewmodel即被释放。如有必要,使用弱引用/事件将viewmodel与任何模型解耦。但我的模型通常是一个web api。