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

Caliburn.Micro中ShellView创建ViewModel显示遇栈溢出问题求助

解决ShellView中通知栏显示及栈溢出问题

咱们先拆解你遇到的两个核心问题:无限循环导致的栈溢出和通知栏无法正确显示,一步步来修复:

1. 先解决栈溢出的致命循环

你的代码里存在一个恶性循环逻辑:

  • 当IsNotificationVisible的getter被调用时,你执行了this.NotificationMessage = new NotificationViewModel();
  • 而NotificationMessage的setter又触发了NotifyOfPropertyChange(() => IsNotificationVisible);
  • 这会再次触发IsNotificationVisible的getter,无限循环最终导致栈溢出

修复方案:把属性赋值逻辑移出getter,getter只负责返回状态,不要修改其他属性。

2. 正确初始化NotificationViewModel

现在你的NotificationMessage getter每次访问都会新建实例,这会导致绑定的状态丢失,应该只初始化一次:

修改ViewModel代码

private NotificationViewModel _notificationMessage;
private bool _isNotificationVisible;

// 懒加载且只初始化一次NotificationViewModel
public NotificationViewModel NotificationMessage {
    get {
        if (_notificationMessage == null)
            _notificationMessage = new NotificationViewModel();
        return _notificationMessage;
    }
    set {
        _notificationMessage = value;
        NotifyOfPropertyChange(() => NotificationMessage);
    }
}

// 用字段存储显示状态,避免在getter里触发逻辑
public bool IsNotificationVisible {
    get => _isNotificationVisible;
    set {
        _isNotificationVisible = value;
        NotifyOfPropertyChange(() => IsNotificationVisible);
    }
}

3. 统一绑定属性名

你的XAML里绑定的是IsNotificationMessageVisible,但ViewModel里定义的是IsNotificationVisible,这会导致绑定失效,修改XAML:

<!-- Notification Bar -->
<UserControl x:Name="NotificationMessage" 
             Visibility="{Binding IsNotificationVisible, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}" 
             Grid.Row="0" Grid.Column="1" />
<!-- Main Frame -->
<Frame x:Name="ActiveItem" NavigationUIVisibility="Hidden" Padding="10" Grid.Row="1" Grid.Column="1" />

4. 在ShellViewModel中主动触发通知显示

现在你需要一个方法来检测并显示通知,比如在构造函数或者收到新通知事件时调用:

private void CheckAndShowNotification()
{
    var notification = Database.GetNotification();
    if (!string.IsNullOrEmpty(notification.Title))
    {
        // 更新NotificationViewModel的内容
        NotificationMessage.Title = notification.Title;
        NotificationMessage.Content = notification.Content;
        // 显示通知栏
        IsNotificationVisible = true;
    }
    else
    {
        IsNotificationVisible = false;
    }
}

额外注意事项

  • 确保NotificationViewModel继承了Caliburn.Micro的PropertyChangedBase(或实现INotifyPropertyChanged),这样属性变化才能正确通知到视图
  • 如果需要自动隐藏通知,可以在CheckAndShowNotification里加入定时器,一段时间后设置IsNotificationVisible = false

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:54:06