想要打造一个属于自己的浏览器?用WinForm配合WebView2控件可能是最简单的入门方式。我去年接手过一个企业内网工具项目,需要在桌面应用中嵌入浏览器功能,当时对比了多种方案后选择了WebView2,实测开发效率比传统CEF方案提升至少3倍。
首先需要安装Visual Studio 2019或更高版本。这里有个小技巧:安装时务必勾选".NET桌面开发"和"使用C++的桌面开发"工作负载,因为WebView2运行时依赖VC++组件。我遇到过不少初学者因为漏装这个导致后续步骤报错。
新建项目时选择"Windows窗体应用(.NET Framework)"模板,注意不是".NET Core"版本。命名建议采用"公司名+产品名"的格式,比如"AcmeBrowser"。框架版本要选4.7.2以上,最近微软文档推荐直接用4.8版本最稳定。
好的浏览器界面应该符合用户习惯。参考主流浏览器布局,我们可以用TableLayoutPanel划分这几个区域:
实际开发中我发现一个细节:WebView2控件默认没有边框,最好手动设置BorderStyle为FixedSingle并调整边距。曾经有个项目因为没加边框,测试人员误以为功能没加载出来。
图标资源可以从Iconfont或Flaticon获取,建议使用24x24像素的PNG格式。有个实用技巧:将图标存入Resources.resx文件后,可以直接通过Properties.Resources调用,比文件路径引用更可靠。
通过NuGet安装Microsoft.Web.WebView2包时,要注意版本选择。当前稳定版是1.0.1587,但如果你需要试用最新功能,可以选preview版本。我在生产环境踩过坑:preview版某些API在正式版会有变动,建议新手先用稳定版。
核心初始化代码要放在Form_Load事件中:
csharp复制private async void Form1_Load(object sender, EventArgs e)
{
var env = await CoreWebView2Environment.CreateAsync();
await webView21.EnsureCoreWebView2Async(env);
webView21.Source = new Uri("https://www.bing.com");
}
这里有个关键点:EnsureCoreWebView2Async是异步方法,如果不加await会导致后续操作报错。我见过有人用.Wait()强制同步,这可能在UI线程造成死锁。
导航控制是最常用的功能,这段代码实现了地址栏与网页的同步:
csharp复制private void btnGo_Click(object sender, EventArgs e)
{
if (Uri.IsWellFormedUriString(txtUrl.Text, UriKind.Absolute))
webView21.CoreWebView2.Navigate(txtUrl.Text);
else
webView21.CoreWebView2.Navigate("https://www.bing.com/search?q=" + txtUrl.Text);
}
private void webView21_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
txtUrl.Text = webView21.Source.ToString();
}
多标签页是浏览器的灵魂功能。我的实现方案是用TabControl+WebView2动态生成:
csharp复制private void AddNewTab(string url)
{
var tabPage = new TabPage("新标签");
var webView = new WebView2 { Dock = DockStyle.Fill };
tabPage.Controls.Add(webView);
tabControl1.TabPages.Add(tabPage);
tabControl1.SelectedTab = tabPage;
webView.CoreWebView2InitializationCompleted += (s, e) =>
{
webView.CoreWebView2.Navigate(url);
};
}
收藏夹功能需要结合JSON序列化和文件操作:
csharp复制// 保存收藏夹
var favorites = new List<FavoriteItem>();
File.WriteAllText("favorites.json", JsonConvert.SerializeObject(favorites));
// 加载收藏夹
if(File.Exists("favorites.json"))
{
favorites = JsonConvert.DeserializeObject<List<FavoriteItem>>(
File.ReadAllText("favorites.json"));
}
下载管理器是另一个实用功能。通过监听DownloadStarting事件可以实现:
csharp复制webView21.CoreWebView2.DownloadStarting += (s, e) =>
{
var saveDialog = new SaveFileDialog();
if(saveDialog.ShowDialog() == DialogResult.OK)
{
e.ResultFilePath = saveDialog.FileName;
e.Handled = true;
}
};
F12开发者工具是调试利器,通过这段代码可以启用:
csharp复制webView21.CoreWebView2.OpenDevToolsWindow();
性能优化方面,我推荐这几个配置:
csharp复制webView21.CoreWebView2.Settings = new CoreWebView2Settings
{
AreDevToolsEnabled = true,
IsZoomControlEnabled = false,
AreDefaultContextMenusEnabled = false
};
内存管理特别重要,每个WebView2实例都要正确释放:
csharp复制protected override void Dispose(bool disposing)
{
if (disposing)
{
webView21?.Dispose();
}
base.Dispose(disposing);
}
客户端必须安装WebView2运行时。有两种方案:
我通常用Inno Setup制作安装包,添加这个检测逻辑:
ini复制[Files]
Source: "MicrosoftEdgeWebview2Setup.exe"; DestDir: "{tmp}"; \
Check: not IsWebView2Installed
[Code]
function IsWebView2Installed: Boolean;
begin
Result := RegKeyExists(HKLM, 'SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}');
end;
最近给某客户部署时发现,他们的内网机器无法连接微软服务器,最后只能选择静态打包方案。所以部署前一定要了解目标环境。