积极答复者
版主您好:求教旋转绘图的方法,谢谢!!!

问题
-
求教下面的代码会画的图形为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
答案
-
你好,
请参考以下代码,在这里我定义了一个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
-
您好,
请参考以下代码,我在里面加入了另一个新的参数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
- 已标记为答案 Youen ZenModerator 2012年5月14日 6:06
全部回复
-
你好,
请参考以下代码,在这里我定义了一个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
-
您太厉害了,谢谢!!!我以前自己琢磨写了一个股票分析系统(自己用),但我就是觉得运算速度和专业的无法相比,不知您是否有时间帮助我一下,谢谢!!!
-
谢谢版主,我修改过了,谢谢!!!
还请教:
我想在控件显示时,只显示线条和箭头,其他部位为透明的,我原先用下面方式来实现的,但很麻烦,可用了你的却不知如何做了,还请教您,谢谢!!!
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 -
您好,
请参考以下代码,我在里面加入了另一个新的参数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
- 已标记为答案 Youen ZenModerator 2012年5月14日 6:06