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

在Caliburn.Micro与Ninject的MVVM架构中重新加载视图的问题

问题分析与解决方案

核心问题拆解

你遇到的两个关键问题:一是修改行列数后视图未更新,二是主窗口关闭后进程无法正常结束,本质分别是属性变更通知缺失/视图实例未重建、资源未正确释放导致的。


1. 修复视图不更新问题

(1)确保ViewModel属性触发变更通知

Caliburn.Micro依赖INotifyPropertyChanged实现视图绑定更新,你的MyGridViewModel需确保RowCount/ColumnCount属性修改时触发通知:

private int _rowCount;
public int RowCount
{
    get => _rowCount;
    set
    {
        if (_rowCount != value)
        {
            _rowCount = value;
            NotifyOfPropertyChange(() => RowCount);
        }
    }
}

// ColumnCount属性同理实现

注:继承Caliburn.Micro的PropertyChangedBase或Screen基类,可直接使用NotifyOfPropertyChange方法。

(2)完善GridHelpers的附加属性逻辑

自定义的GridHelpers必须监听附加属性的变化,在属性值更新时重新生成Grid的行列定义:

public static class GridHelpers
{
    public static readonly DependencyProperty RowCountProperty =
        DependencyProperty.RegisterAttached(
            "RowCount",
            typeof(int),
            typeof(GridHelpers),
            new PropertyMetadata(0, OnRowCountChanged));

    public static void SetRowCount(DependencyObject element, int value)
        => element.SetValue(RowCountProperty, value);

    public static int GetRowCount(DependencyObject element)
        => (int)element.GetValue(RowCountProperty);

    private static void OnRowCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is not Grid grid || e.NewValue is not int newCount) return;
        
        grid.RowDefinitions.Clear();
        for (int i = 0; i < newCount; i++)
        {
            grid.RowDefinitions.Add(new RowDefinition());
        }
    }

    // ColumnCount附加属性同理实现OnColumnCountChanged回调
}

(3)主动重建视图实例(若需完全刷新)

如果Grid结构变化涉及复杂控件重建,需在主VM中替换ContentControl绑定的VM实例:

// Main2ViewModel代码
private MyGridViewModel _currentGridViewModel;
public MyGridViewModel CurrentGridViewModel
{
    get => _currentGridViewModel;
    set
    {
        _currentGridViewModel = value;
        NotifyOfPropertyChange(() => CurrentGridViewModel);
    }
}

// 确认按钮触发的方法
public void ConfirmRowColumnChange()
{
    // 从Ninject获取新的VM实例(需确保绑定为InTransientScope)
    var newVm = Kernel.Get<MyGridViewModel>();
    newVm.RowCount = YourUpdatedRowCount;
    newVm.ColumnCount = YourUpdatedColumnCount;
    CurrentGridViewModel = newVm;
}

同时确保Ninject绑定配置正确:

Bind<MyGridViewModel>().ToSelf().InTransientScope();

2. 解决进程无法正常结束问题

(1)在VM生命周期中释放资源

在Main2ViewModel的OnDeactivate方法中清理视图绑定的VM:

protected override void OnDeactivate(bool close)
{
    if (close)
    {
        CurrentGridViewModel?.TryClose();
        CurrentGridViewModel = null;
    }
    base.OnDeactivate(close);
}

(2)释放Ninject容器

在应用退出时手动释放Ninject内核:

// App.xaml.cs代码
protected override void OnExit(ExitEventArgs e)
{
    Kernel?.Dispose();
    base.OnExit(e);
}

额外检查项

  • 确认XAML中Grid的附加属性绑定语法正确:
    <Grid local:GridHelpers.RowCount="{Binding RowCount}"
          local:GridHelpers.ColumnCount="{Binding ColumnCount}">
    
  • 避免直接操作视图控件,所有逻辑尽量放在ViewModel层,符合MVVM规范。

内容的提问来源于stack exchange,提问作者Frenchy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 18:47:27