ReactiveUI订阅事件与过滤列表问题:修改LogLevel后列表未更新
解决方案
问题出在原过滤逻辑仅绑定了初始化时的LogLevel值,当LogLevel更新后,过滤条件未重新应用到已有的日志条目。以下是基于ReactiveUI + DynamicData的修复方案:
private readonly ReadOnlyObservableCollection<ILogEventArgs> _filteredLogs; private readonly SourceList<ILogEventArgs> _allLogs = new(); private LogLevel _logLevel; public LogPanelViewModel(ILogger logger, IConfigurationService<ILogPanelConfiguration> configurationService) { Logger = logger; LogLevel = configurationService.Configuration.LogLevel ?? LogLevel.Info; // 监听日志事件并收集全量日志 var logDisposable = Observable.FromEventPattern<ILogEventArgs>( handler => logger.OnLog += handler, handler => logger.OnLog -= handler) .Select(eventPattern => eventPattern.EventArgs) .Do(_allLogs.Add) .Subscribe(); Cleanup.Add(logDisposable); // 监听LogLevel变化,动态更新过滤规则 var logLevelObservable = this.WhenAnyValue(x => x.LogLevel); var filteredDisposable = logLevelObservable // 每次LogLevel变更时,基于全量日志重新生成过滤流 .Select(currentLevel => _allLogs.Connect() .Filter(entry => entry.LogLevel >= currentLevel) .Bind(out _filteredLogs) ) // 自动切换到新的过滤流,取消旧订阅 .Switch() .Subscribe(); Cleanup.Add(filteredDisposable); } public LogLevel LogLevel { get => _logLevel; set => this.RaiseAndSetIfChanged(ref _logLevel, value); } public ReadOnlyObservableCollection<ILogEventArgs> FilteredLogs => _filteredLogs;
核心修改说明
- 监听LogLevel变化:通过
this.WhenAnyValue(x => x.LogLevel)创建可观察序列,捕捉LogLevel的每一次变更。 - 动态生成过滤流:每当
LogLevel改变时,基于全量日志集合重新构建过滤逻辑,确保所有历史日志都能被重新评估。 - Switch操作符:自动取消上一次的过滤订阅,切换到新的过滤流,保证UI始终展示符合当前级别要求的所有日志(包括历史和新增条目)。
内容的提问来源于stack exchange,提问作者horotab
相关产品推荐
相关产品推荐

