如何在C# WPF中从其他ViewModel更新文本块和进度条?
核心问题原因
- XAML绑定错误:进度提示文本控件硬编码了测试文案,未绑定ViewModel对应属性
- UI线程阻塞:所有配置逻辑为同步执行,占用UI线程导致属性变更通知无法触发UI刷新
- 进度更新链路中断:ProgressChanged事件无对应实现,进度值没有传递给进度对话框绑定的ViewModel实例
分步修复方案
1. 修复ProgressDialogView的绑定错误
ProgressDialogView.xaml中的TextBlock同时写了x:Name="ProgressMessage"和硬编码的Text属性,硬编码内容会覆盖Caliburn.Micro的自动命名绑定规则,修改代码如下:
<TextBlock x:Name="ProgressMessage" HorizontalAlignment="Center" Margin="0 0 0 10" Style="{StaticResource ProgressMessage}"/>
也可以显式写绑定保证兼容性:
<TextBlock Text="{Binding ProgressMessage}" HorizontalAlignment="Center" Margin="0 0 0 10" Style="{StaticResource ProgressMessage}"/>
2. 改造耗时逻辑为后台异步执行
不要在UI线程同步运行Configure相关方法,改为放到后台线程执行,避免阻塞UI刷新:
await _events.PublishOnUIThreadAsync(new ConfigureServerEvent()); // 配置逻辑移到后台线程执行 await Task.Run(() => Configure(model));
IProgressProgressChanged回调抛到创建它的线程,只要你在UI线程创建Progress实例,回调就会自动在UI线程执行,不需要额外做线程调度。
3. 实现Progress_ProgressChanged事件同步进度
在DeviceConfigureViewModel中注入全局单例的ProgressDialogViewModel实例,在回调中更新进度属性:
// 构造函数注入单例的进度页ViewModel public DeviceConfigureViewModel(ProgressDialogViewModel progressVM, IEventAggregator events) { _progressVM = progressVM; _events = events; } // 实现进度变更回调 private void Progress_ProgressChanged(object sender, ProgressReportModel e) { _progressVM.CurrentProgress = e.CurrentProgress; _progressVM.ProgressMessage = e.ProgressMessage; }
如果不想直接跨ViewModel依赖,也可以通过EventAggregator发布进度更新事件,让ProgressDialogViewModel订阅事件自行更新属性,两种方案都可行。
内容的提问来源于stack exchange,提问作者Harlan
相关产品推荐
相关产品推荐

