【问题标题】:How to fire Closing event on UserControl WPF MVVM如何在 UserControl WPF MVVM 上触发关闭事件
【发布时间】:2021-06-30 11:01:16
【问题描述】:

我想在 UserControl 使用 MVVM 更改为另一个时实现一些功能。到目前为止,我已经尝试过:

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

视图模型:

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 命令。

【问题讨论】:

标签: c# wpf xaml mvvm eventtrigger


【解决方案1】:

Loaded 事件是在 FrameworkElement 上定义的,UserControl 是从它派生的。这就是在用户控件上引发此事件的原因。 但是,Closing 是在 Window 上定义的。由于 UserControl 没有从 Window 继承,因此永远不会引发此事件,因为它甚至没有定义。

UserControl 中没有可以可靠地用于检测视图已被替换的事件。即使Unloaded 事件在这里也可能是模棱两可的。

由于用户启动的系统主题更改,控件上可能会同时引发 Loaded 和 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);
}

这一切的关键在于您在代码中的某处触发导航,这就是您可以在没有任何其他事件的情况下显式清理或执行任何必要代码的地方。

【讨论】:

  • 不适合我。我只是在 MainWindow contentControl 中的不同视图模型(UserControl)之间切换,并没有真正关闭 MainWindow。
  • @NicholasLeong 好的,他们的问题完全不同。问题不在于从用户控件处理窗口的Closing 事件,而是在视图中替换用户控件时调用命令。我说的对吗?
  • 是的,我只是想在同一个窗口切换到UserControl B时在UserControl A中添加一些方法。
  • @NicholasLeong 改编了答案。
猜你喜欢
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 2013-01-06
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多