如何在CefSharp中为下载处理器添加进度条
实现带进度条的下载通知窗口
针对你用CefSharp开发浏览器时需要添加带进度条的下载窗口需求,以下是基于WinForms的实现方案(WPF思路类似,只需调整UI控件的线程更新方式):
1. 创建下载进度窗口
新建一个WinForms窗体(命名为DownloadProgressForm),添加以下控件:
Label(命名lblFileName):显示下载文件名ProgressBar(命名progressBar):显示下载进度Label(命名lblStatus):显示下载速度、百分比Label(命名lblComplete):显示下载完成提示(默认隐藏)
窗体核心代码如下:
using System; using System.Windows.Forms; namespace new_browser { public partial class DownloadProgressForm : Form { public DownloadProgressForm(string fileName) { InitializeComponent(); lblFileName.Text = $"正在下载:{fileName}"; lblComplete.Visible = false; } // 跨线程更新UI的方法 public void UpdateDownloadProgress(int percentComplete, long currentSpeed, bool isComplete) { if (InvokeRequired) { Invoke(new Action<int, long, bool>(UpdateDownloadProgress), percentComplete, currentSpeed, isComplete); return; } progressBar.Value = percentComplete; lblStatus.Text = $"速度:{FormatFileSize(currentSpeed)}/s | 进度:{percentComplete}%"; if (isComplete) { lblStatus.Text = "下载完成"; lblComplete.Visible = true; // 可选:3秒后自动关闭窗口 // Timer timer = new Timer(); // timer.Interval = 3000; // timer.Tick += (s, e) => { Close(); timer.Dispose(); }; // timer.Start(); } } // 格式化文件大小为易读格式 private string FormatFileSize(long bytes) { if (bytes < 1024) return $"{bytes} B"; if (bytes < 1048576) return $"{bytes / 1024:F2} KB"; return $"{bytes / 1048576:F2} MB"; } } }
2. 修改自定义下载处理器
更新你的MyCustomDownloadHandler,移除控制台输出,改为触发进度窗口的创建和更新:
using CefSharp; using System; using System.Windows.Forms; namespace new_browser { class MyCustomDownloadHandler : IDownloadHandler { private DownloadProgressForm _progressForm; public bool CanDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, string url, string requestMethod) { return true; } public void OnBeforeDownload(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IBeforeDownloadCallback callback) { if (!callback.IsDisposed && downloadItem.IsValid) { using (callback) { // 弹出系统保存对话框,让用户选择保存路径 callback.Continue(downloadItem.SuggestedFileName, showDialog: true); } // 在UI线程创建进度窗口 Application.Current?.Invoke(() => { _progressForm = new DownloadProgressForm(downloadItem.SuggestedFileName); _progressForm.Show(); }); } } public void OnDownloadUpdated(IWebBrowser chromiumWebBrowser, IBrowser browser, DownloadItem downloadItem, IDownloadItemCallback callback) { if (downloadItem.IsValid && _progressForm != null && !_progressForm.IsDisposed) { if (downloadItem.IsInProgress && downloadItem.PercentComplete != 0) { _progressForm.UpdateDownloadProgress(downloadItem.PercentComplete, downloadItem.CurrentSpeed, false); } else if (downloadItem.IsComplete) { _progressForm.UpdateDownloadProgress(100, 0, true); } } } // 保留原事件(若需其他模块订阅下载状态可继续使用) public event EventHandler<DownloadItem> OnBeforeDownloadFired; public event EventHandler<DownloadItem> OnDownloadUpdatedFired; } }
3. 关键注意事项
- 线程安全:CefSharp的下载事件运行在非UI线程,必须用
Invoke/BeginInvoke更新UI控件,否则会抛出跨线程异常。 - 窗口生命周期:可根据需求设置下载完成后自动关闭窗口,或让用户手动关闭。
- 多下载处理:若需支持同时下载多个文件,需为每个下载项创建独立的进度窗口,避免复用同一个实例。
内容的提问来源于stack exchange,提问作者Adit Gadkary
相关产品推荐
相关产品推荐

