在关闭主 window 时在 ViewModel 中放置一个计时器
Disposing a timer inside a ViewModel, upon closing the main window
目前在我的应用程序中,我有一个 RelayCommand
,它调用一个启动 Timer
的动作。我有一个单独的命令,它调用 Dispose()
方法来摆脱 of/release 计时器。这一切都位于项目的 ViewModel 副本中。
使用 MVVM 模式,我将如何在关闭 window 时处理此 Timer
,以及执行关闭 window 的 regular/default 操作?
我也在使用 MVVM-Light 工具包,如果这对您有帮助的话。
我当前的解决方案示例如下所示:
视图模型
private static Timer dispatchTimer;
public MainViewModel()
{
this.StartTimerCommand = new RelayCommand(this.StartTimerAction);
this.StopTimerCommand = new RelayCommand(this.StopTimerAction);
}
public RelayCommand StartTimerCommand { get; private set; }
public RelayCommand StopTimerCommand { get; private set; }
private void StartTimerAction()
{
dispatchTimer = new Timer(new TimerCallback(this.IgnoreThis), null, 0, 15);
}
private void StopTimerAction()
{
dispatchTimer.Dispose();
}
查看 (xaml)
....
Height="896"
Width="1109"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid x:Name="mainGrid"
Width="Auto"
Height="Auto">
<Button x:Name="startTimerButton"
Content="Start Timer"
Command="{Binding StartTimerCommand}"/>
<Button x:Name="stopTimerButton"
Content="Stop Timer"
Command="{Binding StopTimerCommand}"/>
</Grid>
</Window>
查看(代码隐藏)
public MainWindow()
{
this.InitializeComponent();
//Would a 'Closing +=' event be called here?
}
您可以为 ViewModel
添加析构函数,如下所示
~public MainViewModel()
{
dispatchTimer.Dispose();
}
关闭 windows 可能会或可能不会处置您的视图模型,具体取决于您的注册方式。一种方法是绑定到视图中的 Loaded/Unloaded 事件并在那里完成工作:
查看:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding PageLoadedCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unloaded">
<i:InvokeCommandAction Command="{Binding PageUnLoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel:
public RelayCommand PageUnLoadedCommand { get; private set; }
...
PageUnLoadedCommand = new RelayCommand(() => OnPageUnLoadedCommand());
...
private void OnPageUnLoadedCommand()
{
//Unsubscribe and dispose here
}
目前在我的应用程序中,我有一个 RelayCommand
,它调用一个启动 Timer
的动作。我有一个单独的命令,它调用 Dispose()
方法来摆脱 of/release 计时器。这一切都位于项目的 ViewModel 副本中。
使用 MVVM 模式,我将如何在关闭 window 时处理此 Timer
,以及执行关闭 window 的 regular/default 操作?
我也在使用 MVVM-Light 工具包,如果这对您有帮助的话。
我当前的解决方案示例如下所示:
视图模型
private static Timer dispatchTimer;
public MainViewModel()
{
this.StartTimerCommand = new RelayCommand(this.StartTimerAction);
this.StopTimerCommand = new RelayCommand(this.StopTimerAction);
}
public RelayCommand StartTimerCommand { get; private set; }
public RelayCommand StopTimerCommand { get; private set; }
private void StartTimerAction()
{
dispatchTimer = new Timer(new TimerCallback(this.IgnoreThis), null, 0, 15);
}
private void StopTimerAction()
{
dispatchTimer.Dispose();
}
查看 (xaml)
....
Height="896"
Width="1109"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid x:Name="mainGrid"
Width="Auto"
Height="Auto">
<Button x:Name="startTimerButton"
Content="Start Timer"
Command="{Binding StartTimerCommand}"/>
<Button x:Name="stopTimerButton"
Content="Stop Timer"
Command="{Binding StopTimerCommand}"/>
</Grid>
</Window>
查看(代码隐藏)
public MainWindow()
{
this.InitializeComponent();
//Would a 'Closing +=' event be called here?
}
您可以为 ViewModel
添加析构函数,如下所示
~public MainViewModel()
{
dispatchTimer.Dispose();
}
关闭 windows 可能会或可能不会处置您的视图模型,具体取决于您的注册方式。一种方法是绑定到视图中的 Loaded/Unloaded 事件并在那里完成工作:
查看:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding PageLoadedCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unloaded">
<i:InvokeCommandAction Command="{Binding PageUnLoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel:
public RelayCommand PageUnLoadedCommand { get; private set; }
...
PageUnLoadedCommand = new RelayCommand(() => OnPageUnLoadedCommand());
...
private void OnPageUnLoadedCommand()
{
//Unsubscribe and dispose here
}