Vb.net 设置面板容器打开和关闭动画(使用添加的控件)的最佳方法是什么

Vb.net 设置面板容器打开和关闭动画(使用添加的控件)的最佳方法是什么,vb.net,animation,custom-controls,gdi+,panels,Vb.net,Animation,Custom Controls,Gdi+,Panels,我试图创建一个动画可折叠面板,它由三个不同的元素组成。每个元素都是从位于用户控件上的面板容器创建的。它由页眉面板、内容面板和页脚面板组成(页脚面板位于内容面板内): 在每个面板中,我会覆盖“绘制”事件并进行自己的自定义绘制。这包括圆角、绘制边框和填充背景(以及在页眉和页脚的情况下绘制文本) 该控件还允许用户在设计时和运行时嵌入到内容面板中 当放置在窗体上时,它看起来正是我想要的样子,但是,我似乎无法在无缝的“平滑”过渡中设置面板的动画。当展开面板时(即使没有内容),它会急促、紧张,看起来很可怕

我试图创建一个动画可折叠面板,它由三个不同的元素组成。每个元素都是从位于用户控件上的面板容器创建的。它由页眉面板、内容面板和页脚面板组成(页脚面板位于内容面板内):

在每个面板中,我会覆盖“绘制”事件并进行自己的自定义绘制。这包括圆角、绘制边框和填充背景(以及在页眉和页脚的情况下绘制文本)

该控件还允许用户在设计时和运行时嵌入到内容面板中

当放置在窗体上时,它看起来正是我想要的样子,但是,我似乎无法在无缝的“平滑”过渡中设置面板的动画。当展开面板时(即使没有内容),它会急促、紧张,看起来很可怕

它的工作方式是,当最小化时,内容面板(包括页脚面板)收缩到只有页眉面板的高度。然后,标题面板会重新绘制自身,使其看起来不同。然后,当最大化时,面板基本上以相反的方式执行所有操作

我的动画代码如下所示:

Dim m_Height As Integer = Me.Height
Dim m_HeaderHeight As Integer = 40
Dim m_FooterHeight As Integer = 35
Dim ShrinkStepSize As Integer = CInt((m_Height - m_HeaderHeight) / 10)
Dim ExpandStepSize As Integer = CInt((m_Height - m_HeaderHeight) / 4)

Private Sub picMinimize_Click(sender As Object, e As EventArgs) Handles picMinimize.Click
    While (Me.Height > m_HeaderHeight)
        Me.Height -= Math.Min(Me.Height - m_HeaderHeight, ShrinkStepSize)
        Application.DoEvents()
    End While

    picMaximise.Visible = True
    picMinimize.Visible = False
    m_Minimized = True
    Me.Invalidate(pnlHeader.ClientRectangle, True)
End Sub

Private Sub picMaximise_Click(sender As Object, e As EventArgs) Handles picMaximise.Click
    While (Me.Height < m_Height)
        Me.Height += Math.Min(m_Height - Me.Height, ExpandStepSize)
        Application.DoEvents()
    End While

    picMaximise.Visible = False
    picMinimize.Visible = True
    m_Minimized = False
    Me.Invalidate(pnlHeader.ClientRectangle, True)
End Sub
在此方面的任何帮助都将不胜感激。
感谢堆积。

“一次增加1个像素”。选择一个数字,任何数字,只要不是1。至少使用5。@HansPassant我尝试了多个值,这就是我最终被4除的原因。但是,即使在我删除动画并简单地设置一个高度值之后,我的绘画事件似乎被多次调用,仍然会产生闪烁效果。从匈牙利语判断,您使用的是Panel类。这不是一个好的选择,它被优化成一个容器。改用PictureBox。如果您需要滚动条,那么从面板派生您自己的类,并在构造函数中将ResizerDraw和DoubleBuffered属性设置为True。通过仅使用一个控件来进一步改进,以使绘制不同步不可见。而且一定要把DoEvents处理掉。谢谢Hans的反馈。因此,我将使用一个picturebox来容纳控件的全部内容,但我是否仍然能够像容器一样使用它来容纳其他控件/面板等?我不需要滚动条,因为控件需要手动调整大小以适应内容。我只是添加了DoEvents,因为它似乎有一点帮助,但这对我来说不是正常的做法。还有,我不知道你说的匈牙利人是什么意思??Thanks@HansPassant现在我重新绘制了我的控件,把所有东西画在空白画布上,不使用任何面板控件。它大大加快了速度,提高了绘图的性能。但我现在如何允许用户将控件嵌入到我的模拟面板控件中?
Private Sub pnlHeader_Paint(sender As Object, e As PaintEventArgs) Handles pnlHeader.Paint
    Dim rect As Rectangle = pnlHeader.ClientRectangle
    rect.X = rect.X + 1
    rect.Y = rect.Y + 1
    rect.Width -= 2
    rect.Height -= 2

    'Position the icon elements
    picClose.Location = New Point(rect.Width - (picClose.Width + 8), CInt(((rect.Height - picClose.Height) / 2) + 3))
    picOptions.Location = New Point(rect.Width - ((picClose.Width + picOptions.Width) + 10), CInt(((rect.Height - picOptions.Height) / 2) + 2))
    picMinimize.Location = New Point(rect.Width - ((picMinimize.Width + picOptions.Width + picClose.Width) + 15), CInt(((rect.Height - picMinimize.Height) / 2) + 3))
    picMaximise.Location = New Point(rect.Width - ((picMaximise.Width + picOptions.Width + picClose.Width) + 15), CInt(((rect.Height - picMaximise.Height) / 2) + 3))

    Dim path As Drawing2D.GraphicsPath = RoundRectangle(rect, CornerRadius, Me.CornerRounding)

    If m_Minimized Then
        'Draw the background
        Using br As Brush = New SolidBrush(Color.White)
            e.Graphics.FillPath(br, path)
        End Using

        'Draw the border
        Using br As Brush = New SolidBrush(BorderColour)
            e.Graphics.DrawPath(New Pen(br, 1), path)
        End Using
    End If

    'Draw the text
    Dim textRect As Rectangle = rect
    textRect.X += m_HeaderAdjustment

    Using string_format As New StringFormat()
        string_format.Alignment = StringAlignment.Near
        string_format.LineAlignment = StringAlignment.Center
        e.Graphics.DrawString(HeaderText, New Font("Segoe UI", 13, FontStyle.Bold, GraphicsUnit.Pixel), New SolidBrush(Color.FromArgb(157, 159, 162)), textRect, string_format)
    End Using
End Sub

Private Sub pnlContent_Paint(sender As Object, e As PaintEventArgs) Handles pnlContent.Paint
    Dim rect As Rectangle = pnlContent.ClientRectangle
    rect.X = rect.X + 1
    rect.Y = rect.Y + 1
    rect.Width -= 2
    rect.Height -= 2

    Dim path As Drawing2D.GraphicsPath = RoundRectangle(rect, CornerRadius, Me.CornerRounding)

    'Draw the background
    Using br As Brush = New SolidBrush(Color.White)
        e.Graphics.FillPath(br, path)
    End Using

    'Draw the border
    Using br As Brush = New SolidBrush(BorderColour)
        rect.Inflate(-1, -1)
        e.Graphics.DrawPath(New Pen(br, 1), path)
    End Using
End Sub

Private Sub pnlFooter_Paint(sender As Object, e As PaintEventArgs) Handles pnlFooter.Paint
    Dim rect As Rectangle = pnlFooter.ClientRectangle
    rect.X = rect.X + 1
    rect.Y = rect.Y + 1
    rect.Width -= 2
    rect.Height -= 2

    Dim rounding As Corners = Corners.BottomLeft Or Corners.BottomRight
    Dim path As Drawing2D.GraphicsPath = RoundRectangle(rect, CornerRadius, rounding)

    'Draw the background
    Using br As Brush = New SolidBrush(FooterBackColour)
        e.Graphics.FillPath(br, path)
    End Using

    'Draw the border
    Using br As Brush = New SolidBrush(BorderColour)
        e.Graphics.DrawPath(New Pen(br, 1), path)
    End Using

    'Draw the text
    Dim textRect As Rectangle = rect
    textRect.X += m_FooterAdjustment
    textRect.Y += 1

    Using string_format As New StringFormat()
        string_format.Alignment = StringAlignment.Near
        string_format.LineAlignment = StringAlignment.Center
        e.Graphics.DrawString(FooterText, New Font("Segoe UI", 11, FontStyle.Regular, GraphicsUnit.Pixel), New SolidBrush(FooterForeColour), textRect, string_format)
    End Using
End Sub