wpf webview2动态修改下载文件的下载路径 文件下载路径选择 同步上下文
通过webview2下载文件时候会将文件保存在用户的默认下载目录,
如果想调整成通过弹窗选择下载路径的方式则需要将默认行为做出修改。
本文通过CoreWebView2_DownloadStarting 这个事件来调整下载路径,
基本思路为通过弹窗让用户选择需要保存的路径,如果用户取消了此操作则通过这个事件提供的Handled句柄取消下载行为。
如果输入下载文件的路径、文件名后则只是修改此事件的目标文件名,而不影响其他逻辑。
在webview2控件的CoreWebView2InitializationCompleted事件中注入下载逻辑,另外注意需要使用System.Threading.SynchronizationContext.Current.Post执行,否则可能会导致
程序崩溃。
相关代码如下
private void webView2_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
webView2.CoreWebView2.DownloadStarting += CoreWebView2_DownloadStarting;
}
private void CoreWebView2_DownloadStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2DownloadStartingEventArgs e)
{
// Developer can obtain a deferral for the event so that the CoreWebView2
// doesn't examine the properties we set on the event args until
// after the deferral completes asynchronously.
CoreWebView2Deferral deferral = e.GetDeferral();
// We avoid potential reentrancy from running a message loop in the download
// starting event handler by showing our download dialog later when we
// complete the deferral asynchronously.
System.Threading.SynchronizationContext.Current.Post((_) =>
{
using (deferral)
{
//string fileName = e.ResultFilePath;
//string downloadUrl = e.DownloadOperation.Uri;
// 弹出保存文件对话框,让用户选择保存路径和文件名
Trace.WriteLine("download starting");
var saveFileDialog = new System.Windows.Forms.SaveFileDialog();
saveFileDialog.Filter = "*.*|*.*";
saveFileDialog.FileName = e.ResultFilePath;
if (saveFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
//取消默认下载的行为
e.Cancel = true;
return;
}
else
{
//重置下载路径后使用原webview行为继续下载
e.ResultFilePath = saveFileDialog.FileName;
}
}
}, null);
}
private void webView2_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
webView2.CoreWebView2.DownloadStarting += CoreWebView2_DownloadStarting;
//webView2.CoreWebView2.DownloadStarting += CoreWebView2_DownloadStartingTest;
}
如果需要自己显示进度,可用通过DownloadStarting事件中CoreWebView2DownloadStartingEventArgs类型对象中的相关属性实现,
private void CoreWebView2_DownloadStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2DownloadStartingEventArgs e)
{
e.DownloadOperation.BytesReceivedChanged += Downloadoperation_BytesReceivedChanged; ; // subscribe to bytesreceivedchanged event
e.DownloadOperation.EstimatedEndTimeChanged += Downloadoperation_EstimatedEndTimeChanged; ; // subsribe to estimatedendtimechanged event
// Developer can obtain a deferral for the event so that the CoreWebView2
// doesn't examine the properties we set on the event args until
// after the deferral completes asynchronously.
CoreWebView2Deferral deferral = e.GetDeferral();
// We avoid potential reentrancy from running a message loop in the download
// starting event handler by showing our download dialog later when we
// complete the deferral asynchronously.
System.Threading.SynchronizationContext.Current.Post((_) =>
{
using (deferral)
{
//string fileName = e.ResultFilePath;
//string downloadUrl = e.DownloadOperation.Uri;
// 弹出保存文件对话框,让用户选择保存路径和文件名
Trace.WriteLine("download starting");
var saveFileDialog = new System.Windows.Forms.SaveFileDialog();
saveFileDialog.Filter = "*.*|*.*";
saveFileDialog.FileName = e.ResultFilePath;
if (saveFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
//取消默认下载的行为
e.Cancel = true;
return;
}
else
{
//重置下载路径后使用原webview行为继续下载
e.ResultFilePath = saveFileDialog.FileName;
}
}
}, null);
}
private void Downloadoperation_EstimatedEndTimeChanged(object sender, object e)
{
if (sender is CoreWebView2DownloadOperation download)
{
var totalByte = download.TotalBytesToReceive;
var receiveByte = download.TotalBytesToReceive;
}
}
private void Downloadoperation_BytesReceivedChanged(object sender, object e)
{
}
另外需要注意给webview2控件进行销毁,例如在usercontrol的unloaded事件中处理
private void CommonWebContainer_Unloaded(object sender, RoutedEventArgs e)
{
webView2?.Dispose();
}
留待后查,同时方便他人
联系我:renhanlinbsl@163.com
联系我:renhanlinbsl@163.com
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!