.NET Framework 4.8 C# WinForm带WebView2控件如何动态修改透明度
我通过Visual Studio 2019创建了一个简单的WinForms(.NET Framework 4.8)应用,添加了WebView2浏览器控件,以此实现了一个自定义浏览器。
在InitializeComponent方法中我做了以下操作:
- 成功将窗体的Opacity设置为0.5,整个窗体及子控件WebView2均符合预期生效,我可以在看到展示的网页的同时透过窗体看到下方的其他窗口。
- 尝试单独设置WebView2浏览器控件的透明度失败,VS智能提示没有该属性,看起来也不需要单独设置该属性。
但应用运行并展示我需要的网页后,我再修改Opacity属性没有任何效果!
我在Form1中通过跟踪语句确认已经动态修改了Form1的Opacity属性,修改后还分别调用了Form1和WebView2控件的Invalidate、Update方法,但依旧无法让透明度修改生效。
我如何不重启应用,就能让Form1及其子控件WebView2的透明度动态修改生效?
2021年8月27日周五更新:附上C#代码
InitializeComponent方法中设置的透明度确实生效,我可以透过浏览器展示内容看到下方窗口。但我的跟踪语句显示鼠标滚轮操作已经成功修改了C#中的opacity属性值,实际界面透明度却没有变化。
private void InitializeComponent() { this.wvc = new Microsoft.Web.WebView2.WinForms.WebView2(); ((System.ComponentModel.ISupportInitialize)(this.wvc)).BeginInit(); this.SuspendLayout(); // // wvc // this.wvc.CreationProperties = null; this.wvc.DefaultBackgroundColor = System.Drawing.Color.White; this.wvc.Location = new System.Drawing.Point(2, 91); this.wvc.Name = "wvc"; this.wvc.Size = new System.Drawing.Size(2139, 842); this.wvc.Source = new System.Uri("https://bing.com", System.UriKind.Absolute); this.wvc.TabIndex = 0; this.wvc.ZoomFactor = 1D; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(2139, 932); this.SizeChanged += (object sender, System.EventArgs e) => { wvc.Size = ((Form1)sender).Size; }; this.Controls.Add(this.wvc); this.Name = "Form1"; this.Opacity = 0.5D; // 该处设置生效 this.Text = "Form1"; ((System.ComponentModel.ISupportInitialize)(this.wvc)).EndInit(); this.ResumeLayout(false); } const ulong MK_MBUTTON = 0x10; protected override void WndProc(ref Message m) { base.WndProc(ref m); switch (m.Msg) { case 0x20a: // WM_MOUSEWHEEL mbuttonDown = (((UInt64)m.WParam & MK_MBUTTON) == MK_MBUTTON); if (mbuttonDown) this.opacity += 0.1d; // 该处修改不生效 break; default: break; } Trace.WriteLine("opacity="+this.opacity+" "+m.Msg.ToString() + ": " +m.ToString()); }
1. 核心错误修正
你代码中修改的是自定义的小写opacity字段,并不是WinForm窗体原生的Opacity属性(首字母大写),你跟踪输出的也是这个自定义变量的值,本质上从未修改过窗体的实际透明度属性,所以界面不会有任何变化。
2. 补充WebView2适配设置
初始化WebView2时将默认背景色设为透明,避免默认白色背景遮挡窗体透明效果:
this.wvc.DefaultBackgroundColor = System.Drawing.Color.Transparent;
3. 完善逻辑适配
Opacity属性的合法取值范围是0~1,建议添加范围限制避免无效赋值,修改后的WndProc代码参考:
const ulong MK_MBUTTON = 0x10; protected override void WndProc(ref Message m) { base.WndProc(ref m); switch (m.Msg) { case 0x20a: // WM_MOUSEWHEEL bool mbuttonDown = (((UInt64)m.WParam & MK_MBUTTON) == MK_MBUTTON); if (mbuttonDown) { // 直接修改窗体原生Opacity属性,首字母大写 this.Opacity += 0.1d; // 限制取值范围在0~1之间 if (this.Opacity > 1) this.Opacity = 1; if (this.Opacity < 0) this.Opacity = 0; } break; default: break; } // 输出实际窗体透明度值 Trace.WriteLine("实际窗体透明度=" + this.Opacity + " " + m.Msg.ToString() + ": " + m.ToString()); }
修改完成后无需额外调用Invalidate、Update方法,Opacity属性变更会自动触发窗体重绘,动态修改即可生效。
内容的提问来源于stack exchange,提问作者Siegfried

