You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF:以符合MVVM规范的方式从ViewModel关闭窗口

在VM-first模式下从ViewModel关闭窗口的MVVM合规方案

核心思路

通过定义视图无关的接口让ViewModel发出关闭请求,由WindowService负责监听并执行窗口关闭操作,完全遵循MVVM的解耦原则,ViewModel无需依赖任何WPF视图层类型。

具体实现步骤

1. 定义关闭请求接口

创建通用接口标记需要触发窗口关闭的ViewModel:

namespace DevPortal.Interfaces
{
    public interface ICloseableViewModel
    {
        // 触发关闭请求的事件
        event EventHandler RequestClose;
    }
}

2. 让ViewModel实现接口并触发关闭请求

在EditTicketViewModel中实现接口,在业务逻辑完成后(比如保存操作)触发关闭事件:

public class EditTicketViewModel : ViewModelBase, ICloseableViewModel
{
    // 实现接口的事件
    public event EventHandler RequestClose;

    [RelayCommand]
    private void SaveAndClose()
    {
        // 执行保存等业务逻辑...
        
        // 触发窗口关闭请求
        RequestClose?.Invoke(this, EventArgs.Empty);
    }

    // 其他ViewModel逻辑...
}

3. 修改WindowService监听关闭请求

更新WindowService,在创建窗口时检查ViewModel是否实现了ICloseableViewModel,订阅事件并处理窗口关闭:

public void ShowWindow(object viewModel, bool showDialog)
{
    var window = new ChromelessWindow();
    window.ResizeMode = ResizeMode.NoResize;
    SfSkinManager.SetTheme(window, new Theme("FluentDark"));
    window.Content = viewModel;
    window.SizeToContent = SizeToContent.WidthAndHeight;
    window.Title = viewModel.GetType().GetProperty("Title").GetValue(viewModel).ToString();
    window.ShowIcon = false;

    // 监听ViewModel的关闭请求
    if (viewModel is ICloseableViewModel closeableVm)
    {
        void OnRequestClose(object sender, EventArgs e)
        {
            window.Close();
            // 取消订阅避免内存泄漏
            closeableVm.RequestClose -= OnRequestClose;
        }

        closeableVm.RequestClose += OnRequestClose;

        // 窗口关闭时再次取消订阅,双重保障
        window.Closed += (s, e) => closeableVm.RequestClose -= OnRequestClose;
    }

    if (showDialog)
    {
        window.ShowDialog();
    }
    else
    {
        window.Show();
    }
}

方案优势

  • 严格遵循MVVM:ViewModel仅负责业务逻辑和发出请求,不依赖任何WPF视图组件,可独立测试、复用。
  • 职责清晰:窗口关闭的具体操作由WindowService统一处理,视图层与ViewModel层完全解耦。
  • 避免内存泄漏:通过双重取消订阅逻辑,防止ViewModel与窗口的引用残留导致内存泄漏。

内容的提问来源于stack exchange,提问作者f.lechleitner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 13:31:13