Avalonia中OnLoaded方法内修改ProgressBar值不更新问题
Avalonia等待窗口进度条不更新问题解决
我做了一个显示其他进程完成状态的等待窗口,其他进程完成时会设置一个布尔标志,判断标志状态的函数通过_signalCompletedFunction传入窗口。窗口里的循环进度条本应在等待期间从1到10反复变动,但实际进度条完全不更新。类似逻辑在WinForms里能正常运行(把OnLoaded换成OnActivated,再加个Refresh就行),但Avalonia里没有Refresh方法。
对应的代码如下:
public partial class winWait : Window { private readonly Func<bool> _signalCompletedFunction; public winWait() { InitializeComponent(); } public winWait(Func<bool> signalCompletedFunction) : this() { _signalCompletedFunction = signalCompletedFunction; this.prgWait.Minimum = 0; this.prgWait.Maximum = 10; } protected override void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); while (!_signalCompletedFunction()) { double mod = (this.prgWait.Value + 1) % this.prgWait.Maximum; this.prgWait.Value = mod == 0 ? this.prgWait.Maximum : mod; } this.Close(); } }
问题根源
OnLoaded方法运行在UI线程里,你写的while循环会一直阻塞UI线程,导致界面根本没机会刷新进度条的状态。WinForms里的Refresh是强制触发界面重绘,但Avalonia的UI更新依赖异步调度,不能用这种同步阻塞的方式。
解决方案
用异步方法配合Task.Delay实现非阻塞循环,让UI线程有时间处理更新:
修改后的代码:
public partial class winWait : Window { private readonly Func<bool> _signalCompletedFunction; public winWait() { InitializeComponent(); } public winWait(Func<bool> signalCompletedFunction) : this() { _signalCompletedFunction = signalCompletedFunction; prgWait.Minimum = 0; prgWait.Maximum = 10; } protected override async void OnLoaded(RoutedEventArgs e) { base.OnLoaded(e); while (!_signalCompletedFunction()) { double mod = (prgWait.Value + 1) % prgWait.Maximum; prgWait.Value = mod == 0 ? prgWait.Maximum : mod; // 让出UI线程给界面刷新,延迟时间可按需调整 await Task.Delay(100); } Close(); } }
关键说明
- 把
OnLoaded改成async void(UI事件处理方法允许使用该写法) - 每次循环后用
await Task.Delay(100),让UI线程能处理排队的渲染任务,进度条即可正常更新 - 延迟时间可根据需求调整,数值越小进度条滚动越快,100ms是比较适中的间隔
内容的提问来源于stack exchange,提问作者Dave Doknjas
相关产品推荐
相关产品推荐

