2016-10-11 4 views
1

Хотите использовать анимированные элементы alphablend на окрашенной панели или других элементах управления, но мой код не работает на 100%. Мой код теперь мерцает анимацией. Если я устанавливаю doublebuffered variable в true, мой фон управления заменяется на черный. Если я использую Me.Invalidate() вместо Parent.Invalidate моей анимированной живописи очень ошибок.Управление анимированным алфавитом VB.net на окрашенной панели

Imports System.Reflection 

Public Class Form1 
    Private Sub FlowLayoutPanel1_Paint(sender As Object, e As PaintEventArgs) 
     Dim TheControl As Control = CType(sender, Control) 
     Dim oRAngle As Rectangle = New Rectangle(0, 0, TheControl.Width, TheControl.Height) 
     Dim oGradientBrush As Brush = New Drawing.Drawing2D.LinearGradientBrush(oRAngle, Color.White, Color.SteelBlue, Drawing.Drawing2D.LinearGradientMode.ForwardDiagonal) 
     e.Graphics.FillRectangle(oGradientBrush, oRAngle) 
    End Sub 
    Public Shared Sub DoubleBufferedSet(ByVal dgv As Object, ByVal setting As Boolean) 
     Dim dgvType As Type = dgv.[GetType]() 
     Dim pi As PropertyInfo = dgvType.GetProperty("DoubleBuffered", BindingFlags.Instance Or BindingFlags.NonPublic) 
     pi.SetValue(dgv, setting, Nothing) 
    End Sub 
    Private Sub FlowLayoutPanel1_Resize(sender As Object, e As EventArgs) 
     sender.Invalidate() 
    End Sub 
    Dim flowlayoutpanel1 As New FlowLayoutPanels 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     flowlayoutpanel1.Dock = DockStyle.Fill 
     AddHandler flowlayoutpanel1.Paint, AddressOf FlowLayoutPanel1_Paint 
     AddHandler flowlayoutpanel1.Resize, AddressOf FlowLayoutPanel1_Resize 
     Me.Controls.Add(flowlayoutpanel1) 
     DoubleBufferedSet(flowlayoutpanel1, True) 
     Dim testc1 As New OpaqControl 
     testc1.Size = New Size(300, 100) 
     flowlayoutpanel1.Controls.Add(testc1) 
     Dim testc2 As New OpaqControl 
     testc2.Size = New Size(300, 100) 
     flowlayoutpanel1.Controls.Add(testc2) 
    End Sub 
End Class 
Public Class OpaqControl 
    Inherits Control 
    Private Timer1 As New Timer() 
    Dim up As Boolean = True 
    Dim poss As Integer = 1 
    Public Sub New() 
     'DoubleBuffered = True 
     AddHandler Timer1.Tick, AddressOf TickHandler 
     Me.Timer1.Interval = 10 
    End Sub 
    Protected Sub TickHandler(sender As Object, e As EventArgs) 
     If up Then 
      poss += 2 
      If poss >= 80 Then Me.Timer1.Enabled = False 
     Else 
      poss -= 2 
      If poss <= 0 Then Me.Timer1.Enabled = False 
     End If 
     Parent.Invalidate(New Rectangle(Me.Location, Me.Size), True) 
     'Me.Invalidate() 
    End Sub 
    Protected Overrides Sub OnMouseEnter(e As EventArgs) 
     up = True 
     Me.Timer1.Enabled = True 
     MyBase.OnMouseEnter(e) 
    End Sub 
    Protected Overrides Sub OnMouseLeave(e As EventArgs) 
     up = False 
     Me.Timer1.Enabled = True 
     MyBase.OnMouseLeave(e) 
    End Sub 
    Protected Overrides ReadOnly Property CreateParams() As CreateParams 
     Get 
      Dim cp As CreateParams = MyBase.CreateParams 
      cp.ExStyle = cp.ExStyle Or &H20 
      Return cp 
     End Get 
    End Property 
    Protected Overrides Sub OnPaintBackground(pevent As PaintEventArgs) 
    End Sub 
    Protected Overrides Sub OnPaint(e As PaintEventArgs) 
     e.Graphics.FillRectangle(New SolidBrush(Color.FromArgb(50, 0, 100, 255)), New Rectangle(0, 0, 300, 100)) 
     e.Graphics.FillRectangle(New SolidBrush(Color.FromArgb(50, 0, 0, 0)), New Rectangle(0, 100 - poss, 300, 80)) 
     e.Graphics.DrawString("Test", Font, Brushes.Yellow, New Point(100, 100 - poss)) 
    End Sub 
End Class 

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

Я использую VB 2015. Я не хочу использовать dll третьей стороны. Я не хочу использовать WPF.

ответ

1

Это плохо мерцает, потому что вы можете сами увидеть родительскую картину. Для избавления от этого артефакта требуется двойная буферизация. Do не WS_EX_TRANSPARENT, который побеждает двойную буферизацию. Класс управления уже поддерживает прозрачность хорошо, воспользоваться этой функцией, как это:

Public Sub New() 
    Me.DoubleBuffered = True 
    Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True) 
    Me.BackColor = Color.Transparent 
    AddHandler Timer1.Tick, AddressOf TickHandler 
    Me.Timer1.Interval = 10 
End Sub 

Удалите CreateParams() и OnPaintBackground() переопределение. Вызовите Me.Invalidate() вместо Parent.Invalidate(). И он шелковисто-гладкий.