2016-10-11 3 views
1

塗りつぶしパネルやその他のコントロールでアルファベットのアニメーションコントロールを使用したいが、コードが100%動作しない。 私のコードでアニメーションが点滅しています。 doublebuffered変数をtrueに設定すると、コントロールの背景が黒に置き換えられます。 Parent.Invalidateの代わりにMe.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

親絵画自体を見ることができるので、ひどくちらつきます。そのアーティファクトを取り除くにはダブルバッファリングが必要です。 ではなく、はダブルバッファリングを無効にするWS_EX_TRANSPARENTを使用します。 Controlクラスは、すでにこのようなその機能を活用し、十分に透明度をサポートしています。

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()のオーバーライドを削除します。 Parent.Invalidate()の代わりにMe.Invalidate()を呼び出します。そして、それは滑らかで滑らかです。

関連する問題