长话短说,我正在尝试编写一些 toast 样式的弹出通知(类似于 Growl),它们应该出现在系统托盘和适当的堆栈旁边。
我可以处理实例化/位置/等...但我想为非矩形 toast 添加功能。我还希望具有 Alpha 透明度,以便 toast 表单上的半透明背景 PNG 可以与其后面的桌面或窗口混合。
所以......为了让显而易见的事情消失:
Form.TransparencyKey 不足以满足我的需求,因为它是全有或全无的透明效果,我希望在某些地方获得 50/50 前景/背景,在其他地方获得 0/100,在其他地方获得 100/0 等等。
我最初的方法是重写 OnBackgroundPaint() 方法,注释掉对 MyBase.OnBackgroundPaint 的调用,并使用 eventargs 中的图形对象准确地绘制我想要的表单。
这似乎开始工作 - 目前,我只是为了测试目的绘制了一些矩形,所以 PNG 可能会带来新的困难,但我还没有做到。
我无法完成的是更新图形 - 第一次呈现表单时,它完美地显示为我所期望的(没有边框,只有一些矩形漂浮在桌面上)。如果我将窗口移到透明窗口后面,透明窗口不会更新/重新绘制
我相信我需要调用 Me.Invalidate() 来强制重新绘制,但不确定何时应该调用 - 我如何知道我身后的窗口已更改其内容?
我采取了错误的方法吗?
非常感谢
编辑:我尝试将 Me.Invalidate() 放入计时器中,只是为了测试重绘是如何发生的——似乎它确实触发了重绘,但重绘操作覆盖了现有的表单背景——即原本为 50% 的区域不透明现在是 75% 不透明(50% + 之前的 50%)
所以,在几个 Invalidate() 之后,我的表单显示为一个黑框 - 我需要在重新绘制之前清除表单的背景,但 Graphics.Clear(Color) 似乎只是用指定的颜色进行填充- 显然,出于这个问题的目的,Colors.Transparent 并不真正意味着透明 - 这似乎是在渲染窗口以“显示其下方的控制内容”时使用的技巧,当我们处理表单本身
如果有人想轻松复制,我的表单代码如下:
Imports System.Drawing
Public Class TransparentForm
Private Timer As Timers.Timer
Private Sub TransparentForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer = New Timers.Timer
AddHandler Timer.Elapsed, AddressOf Timer_Tick
Timer.Interval = 100
Timer.Start()
End Sub
Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
''MyBase.OnPaintBackground(e)
Console.WriteLine("BackgroundPainted")
For x = 0 To 9
e.Graphics.FillRectangle(
New SolidBrush(Color.FromArgb(CInt(x / 10 * 255), 127, 127, 127)),
CInt(x * Me.Width / 10),
0,
CInt(Me.Width / 10),
Me.Height
)
Next
End Sub
Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
Me.Invalidate()
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Console.WriteLine("Painted")
End Sub
Protected Overrides Sub OnInvalidated(ByVal e As System.Windows.Forms.InvalidateEventArgs)
MyBase.OnInvalidated(e)
Console.WriteLine("Invalidated")
End Sub
End Class
最佳答案
有一篇 CodeProject 文章展示了如何使用 png 作为表单的“皮肤”。显然,这支持部分透明而不是 Form.TransparencyKey
提供的 50/50 方法。 .
这是link到 codeproject 文章。我正在尝试在 VB 中上传项目,并会在完成后立即更新此答案。
编辑
这是link到我上面引用的 CodeProject 文章的 VB.NET 版本。
http://www20.zippyshare.com/v/86701716/file.html
我将尝试查看您的代码,看看可以做些什么来帮助您解决问题。
关于.net - VB.Net WinForms 表单 OnPaint() 透明度刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3476950/