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
相关产品推荐
相关产品推荐

