VB.Net WinForms表单OnPaint()透明度刷新

时间:2010-08-13 12:49:31

标签: .net vb.net winforms gdi+

长话短说,我正在尝试编写一些吐司式弹出式通知(类似于Growl),它应该出现在系统托盘和堆栈旁边。

我可以处理实例化/位置/等...但是我想为非矩形的Toast添加一个功能。我也想要Alpha透明度,所以吐司形式的半透明背景PNG会与桌面或窗口后面的窗口混合。

所以...为了明白这一点:

Form.TransparencyKey不足以满足我的需求,因为它是一个全有或全无透明效果,我希望在某些地方获得50/50前景/背景,在其他地方获得0/100,在其他地方获得100/0等。 / p>

我最初的方法是覆盖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

1 个答案:

答案 0 :(得分:1)

有一篇CodeProject文章展示了如何使用png作为表单的“皮肤”。显然,这支持部分透明度,而不是Form.TransparencyKey提供的50/50方法。

这是codeproject文章的link。我正在尝试在VB中上传项目,并会在完成后立即更新此答案。


修改

这是我上面引用的CodeProject文章的VB.NET版本的link http://www20.zippyshare.com/v/86701716/file.html

我会尝试检查您的代码,看看可以采取哪些措施来帮助您解决问题。