VB.Net WinForms Форма OnPaint () Обновление прозрачности - PullRequest
5 голосов
/ 13 августа 2010

Короче говоря, я пытаюсь написать всплывающие уведомления в стиле тоста (по аналогии с Growl), которые должны появиться рядом с панелью задач и складываться соответствующим образом.

Я могу обработать экземпляр / местоположение / и т.д. ... но я хочу добавить возможность для непрямоугольных тостов. Мне также хотелось бы иметь альфа-прозрачность, чтобы полупрозрачный фоновый PNG на форме тоста сочетался с рабочим столом или окнами позади него.

Итак ... Чтобы убрать очевидное с пути:

Form.TransparencyKey не подходит для моих нужд, так как это эффект прозрачности "все или ничего". Я хочу получить 50/50 переднего плана / фона в некоторых местах, 0/100 в других, 100/0 в других и т. Д.

Мой первоначальный подход - переопределить метод OnBackgroundPaint (), закомментировать вызов MyBase.OnBackgroundPaint и использовать графический объект в аргументах событий для рисования именно того, что я хочу, в форме.

Похоже, с самого начала это работает - на данный момент я просто рисую какой-то прямоугольник для целей тестирования, поэтому 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 Ответ

1 голос
/ 13 августа 2010

Существует одна статья CodeProject, в которой показано, как использовать png в качестве «обложки» формы. Очевидно, это поддерживает частичную прозрачность вместо подхода 50/50, предлагаемого Form.TransparencyKey.

Это ссылка на статью проекта кода. Я пытаюсь загрузить проект в VB и обновлю этот ответ, как только это будет сделано.


EDIT

Вот ссылка на VB.NET-версию статьи CodeProject, которую я цитировал выше.
http://www20.zippyshare.com/v/86701716/file.html

Я постараюсь просмотреть ваш код и посмотреть, что можно сделать, чтобы помочь вашей ситуации.

...