draw a dot in a form on click event - vb.net

Any help would be appreciated. How do I create a colored dot on a panel on where a user clicks his mouse? I can get the coordinates of the mouse click and output it through a message box but I can't draw the dot on the panel where the user clicked. I have these codes tried.
Private Sub createDot(x, y)
MsgBox(x & " " & y)
Dim myGraphics As Graphics = Me.CreateGraphics
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Maroon, 20)
myGraphics.DrawRectangle(myPen, x, y, 1, 1)
End Sub
Private Sub Panel1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseClick
missed += 1
lblMissed.Text = missed
Dim x, y As Integer
x = e.X.ToString
y = e.Y.ToString
createDot(x, y)
End Sub
Thanks!

Three things:
1.If you draw on panel you should use Panel1.CreateGraphics not Me.CreateGraphics
2.The width of the pen is to large for a dot. Use 1 instead
3.Do not convert x, y to strings and pass it to createDot
Caution:
As soon as the panel is invalidated (for example you move another window over it) the dot will disappear. The drawing code should be in the Panel1_Paint event` (Scott Chamberlain)
Private Sub createDot(ByVal x As Integer, ByVal y As Integer)
MsgBox(x.ToString & " " & y.ToString)
Dim myGraphics As Graphics = Panel.CreateGraphics
Dim myPen As Pen
myPen = New Pen(Drawing.Color.Maroon, 1)
myGraphics.DrawRectangle(myPen, x, y, 1, 1)
End Sub
Private Sub Panel1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseClick
missed += 1
lblMissed.Text = missed
createDot(e.x, e.y)
End Sub

If you want to create dot on panel you should change Me.CreateGraphics to Panel1.CreateGraphics
Remove ToString from
x=e.X
y=e.Y

Related

Random picturebox arrangement

I am new to visual basics and was wondering how to do the following program: I have 9 picture boxes and a button "arrange". For my program, I would like that all picture boxes come together like a puzzle randomly to make a square that has a width and height of three picture boxes. The square made would have all nine picture boxes in one and every time you click the button "arrange" the picture boxes would change to a random location within the square. So far, I have written so that all the picture boxes become the same size but i don't know how to make them come together in a square. Thanks in advance.
Public Class frm1
Dim Placement As Integer
Private Sub btnArrange_Click(sender As Object, e As EventArgs) Handles btnArrange.Click
picDeux.Size = picgris.Size
picTrois.Size = picgris.Size
picQuatre.Size = picgris.Size
picCinq.Size = picgris.Size
picSix.Size = picgris.Size
picSept.Size = picgris.Size
picHuit.Size = picgris.Size
picNeuf.Size = picgris.Size
lstNum.Items.Clear()
For i = 1 To 3
For j = 1 To 3
Dim L As New Point(picgris.Width * j + 100, picgris.Height * i)
lstNum.Items.Add(L)
Next
Next
For i = 1 To 3
For j = 1 To 3
Placement = Int(Rnd() * (lstNum.Items.Count))
Next
Next
End Sub
End Class
I created nine pictures boxes at design time. You would assign a different image to each picture box. They are all square and the same size. Mine are 100 x 100 to make the arithmetic easy.
I made an array of points as a form level variable. These point will form a 300 x 300 square with the picture boxes. I also declared an array of PictureBox. In the Form.Load I added the pictures boxes to the array.
To reposition the picture boxes assigned the array to a list. Items in this list will be removed because we don't want to assign the same location to more the one picture box. This will not effect the original array.
Looping through the picture boxes we assign a random position to the box then remove that point from the list.
Public Class PictureSort
Private Rand As New Random()
Private PointArray As Point() = {New Point(100, 100), New Point(200, 100), New Point(300, 100), New Point(100, 200), New Point(200, 200), New Point(300, 200), New Point(100, 300), New Point(200, 300), New Point(300, 300)}
Private PictureBoxArray(8) As PictureBox
Private Sub PictureSort_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PictureBoxArray = {PictureBox1, PictureBox2, PictureBox3, PictureBox4, PictureBox5, PictureBox6, PictureBox7, PictureBox8, PictureBox9}
End Sub
Private Sub RepositionPictureBoxes()
Dim lst = PointArray.ToList
For Each pb In PictureBoxArray
Dim index = Rand.Next(0, lst.Count)
pb.Location = lst(index)
lst.RemoveAt(index)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
RepositionPictureBoxes()
End Sub
End Class
My advice is to use a control array - you have an example here that should help: VB.NET Control Array- Declaration and Application.
You just need to initiate that array of controls once, this can be done at form load.
The next step is to sort that array in a random manner. Finally, loop on the array and every time your current loop index modulo 3 = 0, then you increase the Y coordinates and reset the X position.
Here is an example. You can see that each time you click on the button, the picture boxes are rearranged on the form in random order using an ad hoc function. For each picture box, a bitmap is generated on the fly to show the index of the control.. this is for demonstration purposes.
Public Class frmPics
Private pics As New List(Of PictureBox)
Private Const picture_width As Integer = 100, picture_height As Integer = 50
Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
' instantiate controls
Dim font As New Font("Arial", 20, FontStyle.Regular, GraphicsUnit.Pixel)
For i As Integer = 1 To 9
Dim pic As New PictureBox
pic.Visible = False
pic.Name = "pic" & i
pic.Text = i.ToString
Console.WriteLine("Create control: name: " & pic.Name)
' generate an ad-hoc bitmap image showing the index of the control
Dim bitmap As New Bitmap(picture_width, picture_height)
Using g As Graphics = Graphics.FromImage(bitmap)
Dim width As Integer = CInt(g.MeasureString(Text, font).Width)
Dim height As Integer = CInt(g.MeasureString(Text, font).Height)
End Using
Using g As Graphics = Graphics.FromImage(bitmap)
g.Clear(Color.Blue)
g.DrawString(i.ToString, font, New SolidBrush(Color.White), 0, 0)
End Using
pic.Image = bitmap
pics.Add(pic)
Me.Controls.Add(pic)
Next
End Sub
Private Sub btnShuffle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnShuffle.Click
Dim x As Integer = 10, y As Integer = picture_height
Dim counter As Integer = 1
Dim rnd As New Random()
' show controls on form
Console.WriteLine("Show controls on form")
Me.SuspendLayout()
For Each item In pics.OrderBy(Function() rnd.Next)
item.Width = picture_width
item.Height = picture_height
item.Location = New Point(x, y)
item.BorderStyle = BorderStyle.FixedSingle
item.Visible = True
Console.WriteLine("counter: " & counter & " - control name" & item.Name & " - position: " & item.Location.X & "/" & item.Location.Y & " text: " & item.Text)
' reset X position every 3 iterations
If counter Mod 3 = 0 Then
x = 10
y += item.Height
Else
x += item.Width
End If
counter += 1
Next
Me.ResumeLayout()
End Sub
End Class

draw coordinate Two dimensions graph of (x-y) visual basic

hey every one I want to make a program that able to draw coordinate graph of Two dimensions of (x-y).when I enter a value in (x) text box and (y) text box and hit draw button it well draw the graph in the blue picture box . I searched in web sit but I found only one method that draw using the mouse and this not what I want .This is the image of the program and and it supposed to draw in white line like this image
Private Sub PictureBox2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseMove
Static last As Point
If e.Button = Windows.Forms.MouseButtons.Left Then
PictureBox2.CreateGraphics.DrawLine(Pens.White, last.X, last.Y, e.X, e.Y)
End If
last = e.Location
End Sub
this is the code that I found that draw using the mouse
You should use the Graphic class inside the panel's Paint event
Private Sub Panel1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
' Create pen.
Using blackPen As New Pen(Color.Black, 3)
' Create points that define line.
Dim point1 As New Point(100, 100)
Dim point2 As New Point(500, 100)
' Draw line to screen.
e.Graphics.DrawLine(blackPen, point1, point2)
End Using
End Sub
Then call Panle1.Invalidate() to fire the Paint event
It would be good to have a bit more details of your code, especially how and in what class you store the X and Y coordinate. By the way you draw a line between 2 points so you would need two sets of X and Y coordinate boxes on your form.
After that it is as easy as what you found on the internet using the DrawLine method (https://msdn.microsoft.com/en-us/library/system.drawing.graphics.drawline(v=vs.110).aspx), you just needs to fire it from the Click event of your "draw" button.
Hi again Ahmed
Here is a simple sample of a form that would draw a line when button is clicked. Of course it would need more bootstrapping to make sure user only enter integer value for the number of pixels and in its basic form, (0,0) is the top left of the panel but it can easily be converted for a bottom left approach...
and
Class Form1
Private Sub cmdDraw_Click(sender As Object, e As EventArgs) Handles cmdDraw.Click
Dim x1 As Integer = Integer.Parse(txtX1.Text)
Dim y1 As Integer = Integer.Parse(txtY1.Text)
Dim x2 As Integer = Integer.Parse(txtX2.Text)
Dim y2 As Integer = Integer.Parse(txtY2.Text)
pnlMap.CreateGraphics.DrawLine(New Pen(Color.Black), x1, y1, x2, y2)
End Sub
End Class

Padding/ Size / Margin, when using ToolstripControlHost for a popup control

I'm using VB2008 Express. And I've been working on a "popup" to select a date range. The DateTimePicker isn't ideal because the purpose is to pick a date range, which will always be one full week, from Sunday through Saturday. The control works just fine and I'm pretty proud of it. My problem has to do with the border added when using ToolstripControlHost for this. I've included a screenshot and my code.
In the code below, assume there exists a button named "btnTimePeriod", below which I desire to show a panel, which contains a few custom items, and the panel's name is "pnlDateRangePicker".
IT WORKS... but it doesn't look right. The panel itself is 147 x 326 pixels, but notice in the attached graphic that it's adding a border around the panel which I don't want. There's a border on the top, bottom, and left... but for some reason the border on the right one is especially large. Although my code doesn't expressly set it, AutoSize = true so I would have expected it to shrink around the panel.
As required, my code already does set ShowCheckMargin and ShowImageMargin false. I haven't included the code for the DrawDateCalander Sub because it's not relevant. I believe even a blank panel would yield the same result. I have no idea where this margin is coming from. Any guidance?
Private Sub btnTimePeriod_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTimePeriod.Click
Call DrawDateCalendar(DatePart(DateInterval.Month, FirstDisplayedSunday), DatePart(DateInterval.Year, FirstDisplayedSunday))
Call ShowControlBelow(btnTimePeriod, pnlDateRangePicker)
End Sub
Sub ShowControlBelow(ByVal Showbutton As Control, ByVal ShownControl As Control)
Dim PopupContainer As New ToolStripControlHost(ShownControl)
PopupContainer.Margin = New Padding(0)
Dim mnuDropDown As New ContextMenuStrip
mnuDropDown.Padding = New Padding(0)
mnuDropDown.ShowCheckMargin = False
mnuDropDown.ShowImageMargin = False
mnuDropDown.Items.Add(PopupContainer)
ShowMenuBelow(Showbutton, mnuDropDown)
End Sub
Sub ShowMenuBelow(ByVal Showbutton As Control, ByVal WhichMenu As ContextMenuStrip, Optional ByVal AlignRight As Boolean = False)
Dim x As Integer = 0
Dim y As Integer = 0
Dim itscontainer As Control = Showbutton.Parent
x = Showbutton.Location.X
y = Showbutton.Location.Y
If Not itscontainer Is Nothing Then
Do Until TypeOf itscontainer Is Form
x = x + itscontainer.Location.X
y = y + itscontainer.Location.Y
itscontainer = itscontainer.Parent
If itscontainer Is Nothing Then Exit Do
Loop
End If
y = y + Showbutton.Height
If AlignRight = True Then
x = x - WhichMenu.Width + Showbutton.Width
End If
Dim xy As New Point(x, y)
WhichMenu.Show(Showbutton.FindForm, xy)
End Sub
I've never used a ContextMenuStrip for that, and maybe that's the problem.
You can try using a ToolStripDropDown instead:
Private Sub ShowControl(ByVal fromControl As Control, ByVal whichControl As Control)
'\\ whichControl needs MinimumSize set:
whichControl.MinimumSize = whichControl.Size
Dim toolDrop As New ToolStripDropDown()
Dim toolHost As New ToolStripControlHost(whichControl)
toolHost.Margin = New Padding(0)
toolDrop.Padding = New Padding(0)
toolDrop.Items.Add(toolHost)
toolDrop.Show(Me, New Point(fromControl.Left, fromControl.Bottom))
End Sub
Private Sub btnTimePeriod_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnTimePeriod.Click
Call DrawDateCalendar(DatePart(DateInterval.Month, FirstDisplayedSunday), DatePart(DateInterval.Year, FirstDisplayedSunday))
'\\Call ShowControlBelow(btnTimePeriod, pnlDateRangePicker)
Call ShowControl(btnTimePeriod, pnlDateRangePicker)
End Sub

How to dynamically create an overlay over a VB.Net PictureBox

I have a VB.Net PictureBox floorPlanImage on a form form1.
I load a picture into the picturebox:
floorPlanImage.image = my.resources.ResourceManager.GetObject("level8") 'this is actually dynamic, and this part works
I am trying to create an overlay to highlight a region of the image:
Public Sub highlightPrintArea(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer)
'**** DOES NOT WORK
Dim g As Graphics = Me.CreateGraphics
Dim r As Rectangle = New Rectangle(x1, y1, x2 - x1, y2 - y1) 'these are args passed in to the function
Dim pen As Pen = New Pen(Color.FromArgb(128, 32, 100, 200), 1) 'semi-transparent
Dim b As Brush = New SolidBrush(pen.Color)
g.FillRectangle(b, r)
end sub
I need to do this dynamically at runtime, say, on button click. The above function does not seem to draw the rectangle.
However, if I have a function that Handles floorPlanImage.Paint like follows, then the rectangle is drawn as I expect it to:
Private Sub floorPlanImage_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles floorPlanImage.Paint
'**** Works, but does not suit my workflow
Dim g As Graphics = e.Graphics
Dim r As Rectangle = New Rectangle(100, 100, 100, 100)
Dim pen As Pen = New Pen(Color.FromArgb(128, 32, 100, 200), 1)
Dim b As Brush = New SolidBrush(pen.Color)
g.FillRectangle(b, r)
End Sub
The Question (finally)
How can I modify my onclick function to correctly overlay the rectangle over my PictureBox?
In the onclick event you need to save the location/point to a member variable and set a flag so app knows you have a location saved. To update the picture box call Invalidate and Update.
floorPlanImage.Invalidate()
floorPlanImage.Update()
In the onpaint event test the flag that you have a point then use the saved point to draw the overlay.
Private Sub floorPlanImage_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles floorPlanImage.Paint
If hasPoint
'Draw with saved point
End If
End Sub

Determining what objects fall within a selection rectangle (marquee)

I'm writing a program that (amongst other things) provides an IDE-like environment for the user where they can select one or more objects with a rectangualr selection tool.
All selections will be a simple rectangle, and all selectable objects will be simple rectangles as well.
I already have the code (VB.Net) to create the rubber-banding effect visually - what I need is an efficient algorithm that will tell me what objects have at least a portion of their area within the final selection rectangle.
If it helps to visualize, what I want to do would be identical to dragging a selection box over icons on the Windows desktop... whichever icons have even a portion of their areas located within that selection marquee are highlighted (selected).
Any help would be appreciated... thank you in advance
Dim Rect1 As New Rectangle(10, 10, 20, 20)
Dim Rect2 As New Rectangle(5, 5, 20, 20)
Debug.Print(Rect1.IntersectsWith(Rect2))
IntersectsWith works as BigFunger already has mentioned. But aditionally you should check if a rectangle contains another rectangle(intersectsWith only checks for intersection).
A small sample-form that demonstrates it:
Public Class SelectionRectangle
Private first As Point
Private allRectangles As New List(Of RectangleF)
Private Sub form_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseDown
first = New Point(e.X, e.Y)
End Sub
Private Sub form_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseUp
Dim p As New Pen(Brushes.Black, 2)
Dim g As Graphics
Dim second As New Point(e.X, e.Y)
Dim x, y, w, h As Int32
x = DirectCast(IIf(first.X > second.X, second.X, first.X), Int32)
y = DirectCast(IIf(first.Y > second.Y, second.Y, first.Y), Int32)
w = Math.Abs(second.X - first.X)
h = Math.Abs(second.Y - first.Y)
Dim nextRec As New RectangleF(x, y, w, h)
Dim intersects As Boolean = False
For Each rec As RectangleF In allRectangles
If rec.Contains(nextRec) OrElse rec.IntersectsWith(nextRec) Then
intersects = True
Exit For
End If
Next
If Not intersects Then
p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot
g = Me.CreateGraphics()
g.DrawLine(p, first.X, first.Y, second.X, first.Y)
g.DrawLine(p, second.X, second.Y, first.X, second.Y)
g.DrawLine(p, first.X, first.Y, first.X, second.Y)
g.DrawLine(p, second.X, second.Y, second.X, first.Y)
allRectangles.Add(nextRec)
Else
Beep()
End If
End Sub
End Class
UPDATE: changed this code to 1.first check in both directions and 2. and more important for you: checks also if one rectangle not only intersects another but additionally if it contains another.