创建动态重新调整大小的line \形状winforms [英] Create dyamically re-sizable line\shape winforms
问题描述
我是编程新手。任何人都可以帮助我在图片框中创建线条/形状与线/形状上的夹点。就像我们在CAD软件中一样。
我想知道如何在鼠标点击时创建一条线,直到发生另一次鼠标点击事件。
当我使用createGraphics()绘制一条线时,它会从选定的点连续创建线条。而我想创建一条线仅用于向用户显示线路的路径。我已经实现了选择矩形右键单击按钮
工作程序:工具栏将包含行和区域
-
打开文件(图像文件) -
在工具栏的行按钮上单击
-
*来到picturebox -
*点击屏幕的一个点 -
*动态线开始在屏幕上绘图(行将从第一个点击的点到鼠标鼠标所在的位置) -
*。
-
点击
工具栏区域
-
*回到图片框
-
*操作与行相同,但当用户点击图片框上的第三个点时,应出现阴影矩形。
< pre class ="prettyprint lang-vb"> Public Class Form1
Dim isDrag As Boolean = False
Dim theRectangle As New Rectangle(New Point(0,0),New Size(0, 0))
Dim startPoint As Point
Dim IsDimension As Boolean = False
Dim LineLocationStPoint As Point = Nothing
Dim LineLocationEndPoint As Point = Nothing
Dim cnt As Integer = 0
Dim LineArray As New ArrayList
Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As System.EventArgs)Handles MyBase.Load
Dim fd As OpenFileDialog = New OpenFileDialog()
Dim strFileName As String
fd.Title =" Open File Dialog"
fd.Filter ="(* .PDF; * .DWG; * .TIFF; *。 TIF)| * .PDF; * .DWG; * .TIFF; * .TIF |所有文件(*。*)| *。*"
fd.FilterIndex = 2
fd.RestoreDirectory = True
如果是fd.ShowDialo g()= DialogResult.OK然后
strFileName = fd.FileName
'ShowFileInWebBrowser(WebBrowser1,strFileName)
PictureBox1.Load(strFileName)
End if
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object,ByVal e As _
System.Windows.Forms.MouseEventArgs)Handles PictureBox1.MouseDown
If(e.Button = MouseButtons.Right)Then
isDrag = True
End if
Dim control As Control = CType(sender,Control)
startPoint = control.PointToScreen(New Point (eX,eY))
If(e.Button = MouseButtons.Left)然后
IsDimension = True
LineLocationStPoint = e.Location
LineArray.Add(e .Location)
End if
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object,ByVal e As _
System.Windows.Forms.MouseEventArgs)处理PictureBox1 .MouseMove
If(isDrag)Then
ControlPaint。 DrawReversibleFrame(theRectangle,Me.BackColor,_
FrameStyle.Dashed)
Dim endPoint As Point = CType(sender,Control).PointToScreen(New Point(eX,eY) )
Dim width As Integer = endPoint.X - startPoint.X
Dim height As Integer = endPoint.Y - startPoint.Y
theRectangle = New Rectangle(startPoint.X,startPoint.Y, _
宽度,高度)
ControlPaint.DrawReversibleFrame(theRectangle,Me.BackColor,_
FrameStyle.Dashed)
End if
If IsDimension Then
LineLocationEndPoint = e.Location
Dim g As Graphics = PictureBox1.CreateGraphics()
g.DrawLine(Pens.Red,LineLocationStPoint,e.Location)
g.Dispose()
End if
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object,ByVal e As _
System.Windows.Forms.MouseEventArgs)处理PictureBox1.MouseUp
如果IsDimension那么
PictureBox1.Refresh()
ElseIf isDrag然后
'如果发生MouseUp事件,则用户不会拖动。
isDrag = False
'绘制要评估的矩形。使用FrameStyle枚举设置虚线框样式
'。
ControlPaint.DrawReversibleFrame(theRectangle,Me.BackColor,_
FrameStyle.Dashed)
'找出哪些控件与矩形相交并改变它们的颜色。
'该方法使用RectangleToScreen方法将
'Control的客户端坐标转换为屏幕坐标。
Dim i As Integer
Dim controlRectangle As Rectangle
For i = 0 To Controls.Count - 1
controlRectangle = Controls(i).RectangleToScreen _
(Controls( i).ClientRectangle)
如果controlRectangle.IntersectsWith(theRectangle)那么
Controls(i).BackColor = Color.BurlyWood
结束如果
下一个
'重置矩形。
theRectangle = New Rectangle(0,0,0,0)
End if
End Sub
是的,需要一年或两年。
与此同时,您需要学习如何保留图形。
Windows工作的方式是每次需要更新时系统会重新绘制每个窗口。系统通过调用控件的paint事件告诉我们何时需要这些更新。系统在绘图事件参数
中的绘图事件中将绘图表面传递给我们。参数e.graphics是我们在paint事件中绘制的临时绘图表面。因此,当paint事件触发时,我们绘制所有图形。然后,下次窗口需要更新时,我们需要再次绘制所有图形
。
此示例使用paint事件绘制一条线。因此,如果窗口被另一个应用程序或其他原因覆盖并覆盖,则绘制事件将触发并绘制我们的行。
每次绘制事件触发窗口时,探测器都是完全擦除并需要完全重绘。
如果我们只在鼠标移动事件中绘制我们的线条,使用创建图形,我们得到一条线,然后它立即被系统擦除。除非鼠标移动,否则我们不知道何时再画画。因此,在鼠标移动事件中使用创建图形确实
不能很好地工作。最好在绘制事件中绘制,然后在鼠标移动事件中调用绘制事件。通过这种方式,我们获得了重绘窗口的所有调用,而不仅仅是鼠标移动事件。然后当我们想要重绘窗口时,我们只需
通过使用control.refresh / invalidate来调用paint事件。
你可以在这个例子中看到,paint通过使用invalidate触发窗体控件的绘制事件,在mousemove事件中触发事件。然后在paint事件中,我们在e.graphics绘图表面上绘制我们的行,系统在paint
事件参数e中传递给我们。
这是一个详细的例子,需要数年才能掌握。
https:// msdn。 microsoft.com/en-us/library/ms973830.aspx?f=255&MSPPError=-2147217396
所以你需要一步一步。先画一条线。然后是一个矩形。然后添加一个工具栏并打开......
Public Class Form2
Private MouseDownPt,MouseMovePt As PointF
Private PenColor As Color = Color.Yellow
Private Sub Form3_Load(sender As Object,e As EventArgs)Handles Me.Load
DoubleBuffered = True
End Sub
Private Sub Form3_MouseDown(sender As Object,e As MouseEventArgs)Handles Me.MouseDown
MouseDownPt = e.Location
MouseMovePt = e.Location
End Sub
Private Sub Form3_MouseMove(sender As Object,e As MouseEventArgs)处理Me.MouseMove
如果e.Button = MouseButtons.Left则
MouseMovePt = e.Location
Invalidate()
End If
End Sub
Private Sub Form3_Paint(sender As Object,e As PaintEventArgs)处理Me.Paint
使用e.Graphics
.Clear(Color.Black)
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
使用p作为新笔(PenColor,3)
p.DashStyle = Drawing2D.DashStyle.Dash
.DrawLine(p,MouseDownPt,MouseMovePt)
结束使用
结束使用
End Sub
私有子Form3_Resize(发件人为对象,e为EventArgs)处理Me.Resize
Invalidate()
结束子
结束类
I am new to programming. Can anybody help me with creating line/shape in picturebox with grips on the line/shape. Like we do it in CAD software's.
And i want to know how to create a line on mouse click until another mouse click event occurs.
When I draw a line using createGraphics() it creates the line continuously from selected point. Whereas I want to create a line only for showing user the path of line. And i have implemented selection rectangle an right click button
Procedure for working: Toolbar will contain line and Area
- Open a file(image file)
- click on line button of toolbar
- *Come to picturebox
- *click on one point of screen
- *dynamic line starts drawing on screen (line will be from the 1st clicked point to where ever mouse mouse)
-
*when user clicks the next time the line is created.
-
click area of toolbar
-
*come back to picturebox
-
*operation same like line but when user clicks third point on picture box a shaded rectangle should appear.
Public Class Form1 Dim isDrag As Boolean = False Dim theRectangle As New Rectangle(New Point(0, 0), New Size(0, 0)) Dim startPoint As Point Dim IsDimension As Boolean = False Dim LineLocationStPoint As Point = Nothing Dim LineLocationEndPoint As Point = Nothing Dim cnt As Integer = 0 Dim LineArray As New ArrayList Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim fd As OpenFileDialog = New OpenFileDialog() Dim strFileName As String fd.Title = "Open File Dialog" fd.Filter = "(*.PDF;*.DWG;*.TIFF;*.TIF)|*.PDF;*.DWG;*.TIFF;*.TIF|All files (*.*)|*.*" fd.FilterIndex = 2 fd.RestoreDirectory = True If fd.ShowDialog() = DialogResult.OK Then strFileName = fd.FileName 'ShowFileInWebBrowser(WebBrowser1, strFileName) PictureBox1.Load(strFileName) End If End Sub Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _ System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown If (e.Button = MouseButtons.Right) Then isDrag = True End If Dim control As Control = CType(sender, Control) startPoint = control.PointToScreen(New Point(e.X, e.Y)) If (e.Button = MouseButtons.Left) Then IsDimension = True LineLocationStPoint = e.Location LineArray.Add(e.Location) End If End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _ System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove If (isDrag) Then ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _ FrameStyle.Dashed) Dim endPoint As Point = CType(sender, Control).PointToScreen(New Point(e.X, e.Y)) Dim width As Integer = endPoint.X - startPoint.X Dim height As Integer = endPoint.Y - startPoint.Y theRectangle = New Rectangle(startPoint.X, startPoint.Y, _ width, height) ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _ FrameStyle.Dashed) End If If IsDimension Then LineLocationEndPoint = e.Location Dim g As Graphics = PictureBox1.CreateGraphics() g.DrawLine(Pens.Red, LineLocationStPoint, e.Location) g.Dispose() End If End Sub Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As _ System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp If IsDimension Then PictureBox1.Refresh() ElseIf isDrag Then ' If the MouseUp event occurs, the user is not dragging. isDrag = False ' Draw the rectangle to be evaluated. Set a dashed frame style ' using the FrameStyle enumeration. ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _ FrameStyle.Dashed) ' Find out which controls intersect the rectangle and change their color. ' The method uses the RectangleToScreen method to convert the ' Control's client coordinates to screen coordinates. Dim i As Integer Dim controlRectangle As Rectangle For i = 0 To Controls.Count - 1 controlRectangle = Controls(i).RectangleToScreen _ (Controls(i).ClientRectangle) If controlRectangle.IntersectsWith(theRectangle) Then Controls(i).BackColor = Color.BurlyWood End If Next ' Reset the rectangle. theRectangle = New Rectangle(0, 0, 0, 0) End If End Sub
Yes well that will take a year or two.
In the mean time, you need to learn how to persist your graphics.
The way windows works is each window is redrawn by the system each time it needs updating. The system tells us when these updates are required by calling the paint event for the control. And the system passes a drawing surface to us in the paint event in the paint event arguments. The argument e.graphics is the temporary drawing surface we are given to draw on in the paint event. So when the paint event fires, we draw all our graphics. Then, next time the window needs updating, we need to draw all our graphics again.
This example uses the paint event to draw a line. So if the window is covered and uncovered by another application or some other reason, the paint event fires and we draw our line.
The probem is that each time the paint event fires the window is completely erased and need to be completly redrawn.
If we only draw our line in the mouse move event, using create graphics, we get a line, and then it is immediately erased by the system. And we dont know when to draw again unless the mouse is moving. So using create graphics in the mouse move event does not work very well. It is better to draw in the paint event, then call the paint event in the mouse move event. In this way, we get all the calls to redraw the window, not just mouse move event. Then when we want to cause the window to be redrawn, we just call the paint event by using control.refresh/invalidate.
You can see in this example, the paint event is fired in the mousemove event by using invalidate to fire the paint event for the form control. Then in the paint event we draw our line on the e.graphics drawing surface passed to us by the system in the paint event arguments e.
Here is a detailed example that takes years to master.
https://msdn.microsoft.com/en-us/library/ms973830.aspx?f=255&MSPPError=-2147217396
So you need to take it one step at a time. Just draw a line first. Then a rectangle. Then add a toolbar and on and on...
Public Class Form2 Private MouseDownPt, MouseMovePt As PointF Private PenColor As Color = Color.Yellow Private Sub Form3_Load(sender As Object, e As EventArgs) Handles Me.Load DoubleBuffered = True End Sub Private Sub Form3_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown MouseDownPt = e.Location MouseMovePt = e.Location End Sub Private Sub Form3_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove If e.Button = MouseButtons.Left Then MouseMovePt = e.Location Invalidate() End If End Sub Private Sub Form3_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint With e.Graphics .Clear(Color.Black) .SmoothingMode = Drawing2D.SmoothingMode.AntiAlias Using p As New Pen(PenColor, 3) p.DashStyle = Drawing2D.DashStyle.Dash .DrawLine(p, MouseDownPt, MouseMovePt) End Using End With End Sub Private Sub Form3_Resize(sender As Object, e As EventArgs) Handles Me.Resize Invalidate() End Sub End Class
这篇关于创建动态重新调整大小的line \形状winforms的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!