我想实现一些功能,当UserControl切换到另一个时,使用MVVM。到目前为止,我已经尝试过:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{Binding ClosingCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>ViewModel:
private ICommand _closingCommand;
public ICommand ClosingCommand
{
get
{
_closingCommand = new RelayCommand(new Action<object>(OnClosingCommand));
return _closingCommand;
}
set { SetProperty(ref _closingCommand, value); }
}
private void OnClosingCommand(object parameter)
{
//My functions here
}它适用于LoadedCommand,但不适用于Closing命令。
发布于 2021-06-30 19:20:55
Loaded事件是在FrameworkElement上定义的,UserControl是从它派生出来的。这就是在用户控件上引发此事件的原因。但是,Closing是在Window上定义的。由于UserControl不是从Window继承的,因此永远不会引发此事件,因为它甚至没有定义。
UserControl中没有可以可靠地用来检测视图是否已被替换的事件。甚至Unloaded事件在这里也可能是模棱两可的。
由于用户启动的系统主题更改,可能会在控件上同时引发已加载和未加载的
。主题更改会导致控件模板和所包含的可视化树无效,而这又会导致整个控件卸载并重新加载。因此,不能假定只有在导航离开页面时才会发生卸载。
请注意,在应用程序开始关闭后,不会引发Unloaded事件。
一种更安全的方法是为视图模型定义一个接口,该接口提供如下方法:
public interface IDisposableViewModel
{
void DisposeViewModel();
}在视图模型中实现此接口,以调用ClosingCommand的逻辑。然后,在您的主窗口中,或者在实现导航逻辑的任何地方,都可以通过此接口直接访问视图模型,并在导航之前、之后或同时显式调用DisposeViewModel()。如果这个逻辑是在视图中实现的,例如后面的代码,你可以访问你要替换的视图的DataContext,检查它是否实现了IDisposableViewModel并执行同样的操作,例如:
private void Navigate(UserControl currentView, UserControl nextView)
{
// ...this is just an example, your code definitely differs.
if (currrentView is IDisposableViewModel disposableViewModel)
disposableViewModel.DisposeViewModel();
RemoveView(currentView);
SetView(nextView);
}关键是在代码中的某处触发导航,在这一点上,您可以显式地清理或执行任何必要的代码,而不会发生任何其他事件。
https://stackoverflow.com/questions/68193523
复制相似问题