none
版主您好:求教旋转绘图的方法,谢谢!!! RRS feed

  • 问题

  • 求教下面的代码会画的图形为L形自定义控件:我想是否有方法(不重写绘图代码),把控件反方向来用(即竖线在左边,原竖线在右边),谢谢!!!

    Drawing.Drawing2D.Matrix 不知是否有此功能,谢谢!!!

    Dim p11 As New Point(Me.mBorderWidth / 2 + 5, 5)
                            Dim p21 As New Point(Me.mBorderWidth / 2 + 5, Me.Height - Me.mBorderWidth * 2 - 5)
                            Dim p31 As New Point(Me.Width - Me.mBorderWidth * 3, Me.Height - mPen.Width * 2 - 5)
                            Dim ps As Point() = {p11, p21, p31}
                            '   Dim vcd As Integer = mPen.Width
                            e.Graphics.DrawLines(mPen, ps)
                            If vcd < 2 Then
                                Dim p1112 As New Point(p11.X, 0)
                                Dim p3112 As New Point(p11.X - 4, p11.Y + 5)
                                Dim p2112 As New Point(p11.X + 4, p11.Y + 5) '
                                Dim ps112 As Point() = {p1112, p2112, p3112}
                                e.Graphics.FillPolygon(mbushs, ps112)
                                Dim p111 As New Point(p31.X - 5, p31.Y - 4)
                                Dim p311 As New Point(p31.X - 5, p31.Y + 4)
                                Dim p211 As New Point(p31.X + Me.mBorderWidth * 2.5, p31.Y) '
                                Dim ps11 As Point() = {p111, p211, p311}
                                e.Graphics.FillPolygon(mbushs, ps11)
                                Dim p1 As New Point(p11.X, 0)
                                Dim p2 As New Point(p11.X + 5, p11.Y + 6)
                                Dim p3 As New Point(p11.X + mPen.Width / 2 + 1, p11.Y + 6)
                                Dim p4 As New Point(p11.X + mPen.Width / 2 + 1, p31.Y - 5)
                                Dim p5 As New Point(p31.X - 4, p31.Y - 1)
                                Dim p55 As New Point(p31.X - 4, p31.Y - 5)
                                Dim p6 As New Point(Me.Width, p31.Y)
                                Dim p7 As New Point(p31.X - 4, p31.Y + 5)
                                Dim p8 As New Point(p31.X - 4, p31.Y + 1)
                                Dim p9 As New Point(p11.X - mPen.Width / 2 - 1, p31.Y + 1)
                                Dim p10 As New Point(p11.X - mPen.Width / 2 - 1, p11.Y + 6)
                                Dim p119 As New Point(0, p11.Y + 6)

                                Dim ps1 As Point() = {p1, p2, p3, p4, p5, p55, p6, p7, p8, p9, p10, p119}
                                m_path.AddPolygon(ps1)
                            Else
                                Dim p1112 As New Point(p11.X, 0)
                                Dim p3112 As New Point(p11.X - 1.5 * vcd, p11.Y + 2.5 * vcd)
                                Dim p2112 As New Point(p11.X + 1.5 * vcd, p11.Y + 2.5 * vcd) '
                                Dim ps112 As Point() = {p1112, p2112, p3112}
                                e.Graphics.FillPolygon(mbushs, ps112)
                                '当宽度大于4,则根据宽度来决定箭头大小,看起来较为美观
                                Dim p111 As New Point(p31.X, p31.Y - 2 * vcd)
                                Dim p311 As New Point(p31.X, p31.Y + 2 * vcd)
                                Dim p211 As New Point(Me.Width, p31.Y) '
                                Dim ps11 As Point() = {p111, p211, p311}
                                e.Graphics.FillPolygon(mbushs, ps11)
                                Dim p1 As New Point(p11.X, 0)
                                Dim p2 As New Point(p11.X + 1.5 * vcd, p11.Y + 2.5 * vcd)
                                Dim p3 As New Point(p11.X + 0.5 * vcd + 1, p11.Y + 2.5 * vcd)
                                Dim p4 As New Point(p11.X + 0.5 * vcd + 1, p31.Y - vcd / 2 - 1)
                                Dim p5 As New Point(Me.Width, p31.Y - 2 * vcd - 1)
                                Dim p6 As New Point(Me.Width, p31.Y)
                                Dim p7 As New Point(p31.X - 4, p31.Y + 2 * vcd + 1)
                                Dim p8 As New Point(p31.X - 4, p31.Y + vcd / 2 + 1)
                                Dim p9 As New Point(p11.X - 0.5 * vcd - 1, p31.Y + vcd / 2 + 1)
                                Dim p10 As New Point(p11.X - 0.5 * vcd - 1, p11.Y + 2.5 * vcd)
                                Dim p119 As New Point(0, p11.Y + 2.5 * vcd)
                                Dim ps1 As Point() = {p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p119}
                                m_path.AddPolygon(ps1)
                            End If
                            Dim m_region As New Region(m_path)
                            Me.Region = m_region

    2012年5月9日 3:44

答案

  • 你好,

    请参考以下代码,在这里我定义了一个Bool类型的变量reserved来判断是否将控件反向,然后做相应的计算处理。

    #Region "Reserved"
        Private reserved As Boolean = False
        Public Property IsReserverd As Boolean
            Get
                Return reserved
            End Get
            Set(value As Boolean)
                reserved = value
            End Set
        End Property
    #End Region
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim myColor As Color
            Dim mPen As New Pen(myColor)
            mPen.Color = Me.ForeColor
            mPen.Width = mBorderWidth
            Dim mbushs As Brush = New SolidBrush(Me.ForeColor)
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            '我对此处代码做了一些修改,根据reserved的值来给每个点赋相应的值
            '另外,我测试的时候发现当线条小于4的时候,会出现箭头显示不全的情况,是因为线条的长度设置的有些问题,你可以在这里也加入vcd小于4的处理
            Dim p11 As New Point(CInt(Math.Abs(Me.Width * IIf(reserved, 1, 0) - 10 + Me.mBorderWidth / 2)), 10)
            Dim p21 As New Point(CInt(Math.Abs(Me.Width * IIf(reserved, 1, 0) - 10 + Me.mBorderWidth / 2)), Me.Height - Me.mBorderWidth * 1.5)
    
            Dim p31 As New Point(CInt(Math.Abs(Me.Width * IIf(reserved, 0, 1) - Me.mBorderWidth * 2.5)), Me.Height - mPen.Width * 1.5)
            Dim ps As Point() = {p11, p21, p31}
            Dim vcd As Integer = mPen.Width
            e.Graphics.DrawLines(mPen, ps)
    
            '根据线条的宽度来画箭头
            '如果线宽小于4,则为其指定箭头大小,因为宽度为1或者2的时候,箭头几乎看不到
            If vcd < 4 Then
                Dim p111 As New Point(p31.X, p31.Y - 6)
                Dim p311 As New Point(p31.X, p31.Y + 6)
                Dim p211 As New Point(p31.X + 10 * IIf(reserved, -1, 1), p31.Y) '
                Dim ps11 As Point() = {p111, p211, p311}
                e.Graphics.FillPolygon(mbushs, ps11)
            Else
                '当宽度大于4,则根据宽度来决定箭头大小,看起来较为美观
                Dim p111 As New Point(p31.X, p31.Y - 1.5 * vcd)
                Dim p311 As New Point(p31.X, p31.Y + 1.5 * vcd)
                Dim p211 As New Point(p31.X + 2.5 * vcd * IIf(reserved, -1, 1), p31.Y) '
                Dim ps11 As Point() = {p111, p211, p311}
                e.Graphics.FillPolygon(mbushs, ps11)
            End If
        End Sub

    另外,我测试的时候,发现我上一个回复中当线条宽度小于4的时候,可能会出现箭头显示不全的情况,如果你使用了那些代码,请注意修改。

    Regards,


    Shanks Zen
    MSDN Community Support | Feedback to us

    • 已标记为答案 YQY888 2012年5月10日 9:58
    2012年5月10日 6:36
    版主
  • 您好,

    请参考以下代码,我在里面加入了另一个新的参数Solid,来决定是否显示空心的图案,代码部分略显臃肿,见谅。

    Public Class UserControl1
        Public Sub New()
            MyBase.New()
            Me.Size = New Size(500, 500)
            Me.BorderStyle = Windows.Forms.BorderStyle.None
        End Sub
    
    #Region "BorderWidth"
        Private mBorderWidth As Short = 10
    
        Public Property BorderWidth() As Short
            Get
                Return mBorderWidth
            End Get
            Set(ByVal value As Short)
                mBorderWidth = value
                Me.Invalidate()
            End Set
        End Property
    
    #End Region
        '实心空心开关
    #Region "IsSolid"
        Private isSolid As Boolean = False
    
        Public Property mSolid As Boolean
            Get
                Return isSolid
            End Get
            Set(value As Boolean)
                isSolid = value
            End Set
        End Property
    #End Region
        '设置空心时的线条间距
    #Region "LineWidth"
        Private mLineWidth As Short = 19
    
        Public Property LineWidth() As Short
            Get
                Return mLineWidth
            End Get
            Set(ByVal value As Short)
                mLineWidth = value
                Me.Invalidate()
            End Set
        End Property
    #End Region
        '反向开关
    #Region "Reserved"
        Private reserved As Boolean = False
        Public Property IsReserverd As Boolean
            Get
                Return reserved
            End Get
            Set(value As Boolean)
                reserved = value
            End Set
        End Property
    #End Region
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim myColor As Color
            Dim mPen As New Pen(myColor)
            mPen.Color = Me.ForeColor
            mPen.Width = mBorderWidth
            Dim mbushs As Brush = New SolidBrush(Me.ForeColor)
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            Dim ps As Point()
            Dim vcd As Integer = mPen.Width
    
            '加入这段是因为要判断线条宽度,和线条间距是图形显示完整
            If vcd < 4 And mLineWidth < 4 Then
                Me.mBorderWidth = 4
            ElseIf vcd > mLineWidth Then
            Else
                Me.mBorderWidth = mLineWidth
            End If
    
            '我对此处坐标轴代码做了一些修改,使线条宽度较大时箭头也可以正常显示
            Dim p11 As New Point(10 + Me.mBorderWidth / 2, 10)
            Dim p21 As New Point(10 + Me.mBorderWidth / 2, Me.Height - Me.mBorderWidth * 1.5 - 10)
            Dim p31 As New Point(Me.Width - Me.mBorderWidth * 2.5, Me.Height - Me.mBorderWidth * 1.5 - 10)
            Me.mBorderWidth = mPen.Width
    
    
            '如果是实体的图形,就还是和之前的代码一样了
            If isSolid Then
                ps = {p11, p21, p31}
                e.Graphics.DrawLines(mPen, ps)
                If vcd < 4 Then
                    Dim p111 As New Point(p31.X, p31.Y - 6)
                    Dim p311 As New Point(p31.X, p31.Y + 6)
                    Dim p211 As New Point(p31.X + 10, p31.Y) '
                    Dim ps11 As Point() = {p111, p211, p311}
                    e.Graphics.FillPolygon(mbushs, ps11)
                Else
                    '当宽度大于4,则根据宽度来决定箭头大小,看起来较为美观
                    Dim p111 As New Point(p31.X, p31.Y - 1.5 * vcd)
                    Dim p311 As New Point(p31.X, p31.Y + 1.5 * vcd)
                    Dim p211 As New Point(p31.X + 2.5 * vcd, p31.Y) '
                    Dim ps11 As Point() = {p111, p211, p311}
                    e.Graphics.FillPolygon(mbushs, ps11)
                End If
    
                '如果不是实心的图形,需要多一些的运算,因为连线的点变多了,另外还需要声明一个变量来制定空心线条之间的距离。
            Else
                If vcd < 4 And mLineWidth < 4 Then
                    Me.mBorderWidth = 4
                ElseIf vcd > mLineWidth Then
                Else
                    Me.mBorderWidth = mLineWidth
                End If
                Dim p11s As New Point(10 + Me.mBorderWidth / 2 + LineWidth, 10)
                Dim p21s As New Point(10 + Me.mBorderWidth / 2 + LineWidth, Me.Height - Me.mBorderWidth * 1.5 - LineWidth - 10)
                Dim p31s As New Point(Me.Width - Me.mBorderWidth * 2.5, Me.Height - Me.mBorderWidth * 1.5 - LineWidth - 10)
                Me.mBorderWidth = mPen.Width
                If mLineWidth < 4 Then
                    Dim p111 As New Point(p31.X, p31s.Y - 6)
                    Dim p311 As New Point(p31.X, p31.Y + 6)
                    Dim p211 As New Point(p31.X + 10, p31.Y - 3) '
    
                    ps = {p11, p11s, p21s, p31s, p111, p211, p311, p31, p21, p11}
                    e.Graphics.DrawLines(mPen, ps)
                    'Dim ps11 As Point() = {p111, p211, p311}
                    'e.Graphics.FillPolygon(mbushs, ps11)
                Else
                    Dim p111 As New Point(p31.X, p31s.Y - 1.5 * mLineWidth)
                    Dim p311 As New Point(p31.X, p31.Y + 1.5 * mLineWidth)
                    Dim p211 As New Point(p31.X + 2.3 * mLineWidth, p31.Y - 0.5 * mLineWidth) '
                    ps = {p11, p11s, p21s, p31s, p111, p211, p311, p31, p21, p11}
                    e.Graphics.DrawLines(mPen, ps)
                End If
            End If
    
        End Sub
    End Class
    Regards,


    Shanks Zen
    MSDN Community Support | Feedback to us

    2012年5月11日 5:33
    版主

全部回复

  • 你好,

    请参考以下代码,在这里我定义了一个Bool类型的变量reserved来判断是否将控件反向,然后做相应的计算处理。

    #Region "Reserved"
        Private reserved As Boolean = False
        Public Property IsReserverd As Boolean
            Get
                Return reserved
            End Get
            Set(value As Boolean)
                reserved = value
            End Set
        End Property
    #End Region
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim myColor As Color
            Dim mPen As New Pen(myColor)
            mPen.Color = Me.ForeColor
            mPen.Width = mBorderWidth
            Dim mbushs As Brush = New SolidBrush(Me.ForeColor)
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            '我对此处代码做了一些修改,根据reserved的值来给每个点赋相应的值
            '另外,我测试的时候发现当线条小于4的时候,会出现箭头显示不全的情况,是因为线条的长度设置的有些问题,你可以在这里也加入vcd小于4的处理
            Dim p11 As New Point(CInt(Math.Abs(Me.Width * IIf(reserved, 1, 0) - 10 + Me.mBorderWidth / 2)), 10)
            Dim p21 As New Point(CInt(Math.Abs(Me.Width * IIf(reserved, 1, 0) - 10 + Me.mBorderWidth / 2)), Me.Height - Me.mBorderWidth * 1.5)
    
            Dim p31 As New Point(CInt(Math.Abs(Me.Width * IIf(reserved, 0, 1) - Me.mBorderWidth * 2.5)), Me.Height - mPen.Width * 1.5)
            Dim ps As Point() = {p11, p21, p31}
            Dim vcd As Integer = mPen.Width
            e.Graphics.DrawLines(mPen, ps)
    
            '根据线条的宽度来画箭头
            '如果线宽小于4,则为其指定箭头大小,因为宽度为1或者2的时候,箭头几乎看不到
            If vcd < 4 Then
                Dim p111 As New Point(p31.X, p31.Y - 6)
                Dim p311 As New Point(p31.X, p31.Y + 6)
                Dim p211 As New Point(p31.X + 10 * IIf(reserved, -1, 1), p31.Y) '
                Dim ps11 As Point() = {p111, p211, p311}
                e.Graphics.FillPolygon(mbushs, ps11)
            Else
                '当宽度大于4,则根据宽度来决定箭头大小,看起来较为美观
                Dim p111 As New Point(p31.X, p31.Y - 1.5 * vcd)
                Dim p311 As New Point(p31.X, p31.Y + 1.5 * vcd)
                Dim p211 As New Point(p31.X + 2.5 * vcd * IIf(reserved, -1, 1), p31.Y) '
                Dim ps11 As Point() = {p111, p211, p311}
                e.Graphics.FillPolygon(mbushs, ps11)
            End If
        End Sub

    另外,我测试的时候,发现我上一个回复中当线条宽度小于4的时候,可能会出现箭头显示不全的情况,如果你使用了那些代码,请注意修改。

    Regards,


    Shanks Zen
    MSDN Community Support | Feedback to us

    • 已标记为答案 YQY888 2012年5月10日 9:58
    2012年5月10日 6:36
    版主
  • 您太厉害了,谢谢!!!我以前自己琢磨写了一个股票分析系统(自己用),但我就是觉得运算速度和专业的无法相比,不知您是否有时间帮助我一下,谢谢!!!

    http://www.mndsoft.com/blog/DoNet/stock2011.html

    2012年5月10日 9:58
  • 谢谢版主,我修改过了,谢谢!!!

    还请教:

    我想在控件显示时,只显示线条和箭头,其他部位为透明的,我原先用下面方式来实现的,但很麻烦,可用了你的却不知如何做了,还请教您,谢谢!!!

     Dim m_path As Drawing2D.GraphicsPath
            m_path = New Drawing2D.GraphicsPath(Drawing2D.FillMode.Winding)

    Dim p1 As New Point(p11.X, 0)
                Dim p2 As New Point(p11.X + 5, p11.Y + 6)
                Dim p3 As New Point(p11.X + mPen.Width / 2 + 1, p11.Y + 6)
                Dim p4 As New Point(p11.X + mPen.Width / 2 + 1, Me.Height - mPen.Width - 1)
                Dim p5 As New Point(Me.Width, Me.Height - mPen.Width - 1)
                Dim p6 As New Point(Me.Width, Me.Height)
                Dim p7 As New Point(p11.X - 5, Me.Height)
                Dim p8 As New Point(p11.X - 5, p11.Y + 6)
                Dim p9 As New Point(0, p11.Y + 5)
                Dim ps1 As Point() = {p1, p2, p3, p4, p5, p6, p7, p8, p9}
                m_path.AddPolygon(ps1)
                Dim m_region As New Region(m_path)
                Me.Region = m_region

    2012年5月10日 11:16
  • 您好,

    请参考以下代码,我在里面加入了另一个新的参数Solid,来决定是否显示空心的图案,代码部分略显臃肿,见谅。

    Public Class UserControl1
        Public Sub New()
            MyBase.New()
            Me.Size = New Size(500, 500)
            Me.BorderStyle = Windows.Forms.BorderStyle.None
        End Sub
    
    #Region "BorderWidth"
        Private mBorderWidth As Short = 10
    
        Public Property BorderWidth() As Short
            Get
                Return mBorderWidth
            End Get
            Set(ByVal value As Short)
                mBorderWidth = value
                Me.Invalidate()
            End Set
        End Property
    
    #End Region
        '实心空心开关
    #Region "IsSolid"
        Private isSolid As Boolean = False
    
        Public Property mSolid As Boolean
            Get
                Return isSolid
            End Get
            Set(value As Boolean)
                isSolid = value
            End Set
        End Property
    #End Region
        '设置空心时的线条间距
    #Region "LineWidth"
        Private mLineWidth As Short = 19
    
        Public Property LineWidth() As Short
            Get
                Return mLineWidth
            End Get
            Set(ByVal value As Short)
                mLineWidth = value
                Me.Invalidate()
            End Set
        End Property
    #End Region
        '反向开关
    #Region "Reserved"
        Private reserved As Boolean = False
        Public Property IsReserverd As Boolean
            Get
                Return reserved
            End Get
            Set(value As Boolean)
                reserved = value
            End Set
        End Property
    #End Region
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim myColor As Color
            Dim mPen As New Pen(myColor)
            mPen.Color = Me.ForeColor
            mPen.Width = mBorderWidth
            Dim mbushs As Brush = New SolidBrush(Me.ForeColor)
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            Dim ps As Point()
            Dim vcd As Integer = mPen.Width
    
            '加入这段是因为要判断线条宽度,和线条间距是图形显示完整
            If vcd < 4 And mLineWidth < 4 Then
                Me.mBorderWidth = 4
            ElseIf vcd > mLineWidth Then
            Else
                Me.mBorderWidth = mLineWidth
            End If
    
            '我对此处坐标轴代码做了一些修改,使线条宽度较大时箭头也可以正常显示
            Dim p11 As New Point(10 + Me.mBorderWidth / 2, 10)
            Dim p21 As New Point(10 + Me.mBorderWidth / 2, Me.Height - Me.mBorderWidth * 1.5 - 10)
            Dim p31 As New Point(Me.Width - Me.mBorderWidth * 2.5, Me.Height - Me.mBorderWidth * 1.5 - 10)
            Me.mBorderWidth = mPen.Width
    
    
            '如果是实体的图形,就还是和之前的代码一样了
            If isSolid Then
                ps = {p11, p21, p31}
                e.Graphics.DrawLines(mPen, ps)
                If vcd < 4 Then
                    Dim p111 As New Point(p31.X, p31.Y - 6)
                    Dim p311 As New Point(p31.X, p31.Y + 6)
                    Dim p211 As New Point(p31.X + 10, p31.Y) '
                    Dim ps11 As Point() = {p111, p211, p311}
                    e.Graphics.FillPolygon(mbushs, ps11)
                Else
                    '当宽度大于4,则根据宽度来决定箭头大小,看起来较为美观
                    Dim p111 As New Point(p31.X, p31.Y - 1.5 * vcd)
                    Dim p311 As New Point(p31.X, p31.Y + 1.5 * vcd)
                    Dim p211 As New Point(p31.X + 2.5 * vcd, p31.Y) '
                    Dim ps11 As Point() = {p111, p211, p311}
                    e.Graphics.FillPolygon(mbushs, ps11)
                End If
    
                '如果不是实心的图形,需要多一些的运算,因为连线的点变多了,另外还需要声明一个变量来制定空心线条之间的距离。
            Else
                If vcd < 4 And mLineWidth < 4 Then
                    Me.mBorderWidth = 4
                ElseIf vcd > mLineWidth Then
                Else
                    Me.mBorderWidth = mLineWidth
                End If
                Dim p11s As New Point(10 + Me.mBorderWidth / 2 + LineWidth, 10)
                Dim p21s As New Point(10 + Me.mBorderWidth / 2 + LineWidth, Me.Height - Me.mBorderWidth * 1.5 - LineWidth - 10)
                Dim p31s As New Point(Me.Width - Me.mBorderWidth * 2.5, Me.Height - Me.mBorderWidth * 1.5 - LineWidth - 10)
                Me.mBorderWidth = mPen.Width
                If mLineWidth < 4 Then
                    Dim p111 As New Point(p31.X, p31s.Y - 6)
                    Dim p311 As New Point(p31.X, p31.Y + 6)
                    Dim p211 As New Point(p31.X + 10, p31.Y - 3) '
    
                    ps = {p11, p11s, p21s, p31s, p111, p211, p311, p31, p21, p11}
                    e.Graphics.DrawLines(mPen, ps)
                    'Dim ps11 As Point() = {p111, p211, p311}
                    'e.Graphics.FillPolygon(mbushs, ps11)
                Else
                    Dim p111 As New Point(p31.X, p31s.Y - 1.5 * mLineWidth)
                    Dim p311 As New Point(p31.X, p31.Y + 1.5 * mLineWidth)
                    Dim p211 As New Point(p31.X + 2.3 * mLineWidth, p31.Y - 0.5 * mLineWidth) '
                    ps = {p11, p11s, p21s, p31s, p111, p211, p311, p31, p21, p11}
                    e.Graphics.DrawLines(mPen, ps)
                End If
            End If
    
        End Sub
    End Class
    Regards,


    Shanks Zen
    MSDN Community Support | Feedback to us

    2012年5月11日 5:33
    版主
  • 谢谢您的帮助!!!谢谢!!!
    2012年5月13日 21:27