Drawing rectangle on picture box from another form's button - vb.net

I have a form with a picturebox on it, and another form with a button on it. How would I picturebox1_paint on the first form once I press the button on the other form?
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.DrawRectangle(Pens.Blue, x.text, y.text, width.text, height.text)
End Sub
this is what I have, what would I need to alter to get it to work?

At Form1, add
Sub PaintImage(rectangle As Rectangle)
' create image in size of PictureBox1
Dim image As New Bitmap(PictureBox1.Width, PictureBox1.Height)
' paint on created image
Using gr As Graphics = Graphics.FromImage(image)
gr.DrawRectangle(New Pen(Color.Red), rectangle)
End Using
' display finished image in PictureBox1
PictureBox1.Image = image
End Sub
and call it from the form with button:
Sub Button1_Click(sender as Object, e as EventArgs) Handles Button1.Click
Form1.PaintImage(New Rectangle(x, y, width, height)) ' assume we already have x, y, w, h
End Sub
You can delete your Paint() event handler shown in the question. Its purpose is to repaint PictureBox1.Image if its size or visibility is changed and in most cases you can leave it as it is.

Related

Moving a bitmap to the front

So
I need to put an image on a picturebox
I have a form with a panel which contain a picturebox and an image.
I use image because I need to rotate it.
what I get is that the picture cover the image and I need the opposite.
picturebox.sendToBack doesnt work and i cant find img.bringToTop function.
Imports System.Drawing.Drawing2D
Public Class Form1
Dim g As Graphics
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
g = Panel1.CreateGraphics
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim img As Image
img = Bitmap.FromFile(Application.StartupPath & "/pic/" & "clay.jpg")
g.RotateTransform(330)
g.DrawImage(img, 70, 170, 100, 100)
Pb.SendToBack()
End Sub
End Class
[ pictures][1]
https://i.stack.imgur.com/s9goC.jpg
Here is an example of what I linked to in the comments that applies to your specific scenario. This code will draw the same Image on a Panel and a PictureBox. It will work whether the PictureBox is a child of the Panel or a sibling.
Private ReadOnly img As Image = Image.FromFile("file path here")
Private Sub DrawImage(c As Control, g As Graphics)
'The image will be drawn at (100,100) in form coordinates.
'Translate that location to coordinates for the current control.
Dim imgLocation = c.PointToClient(Me.PointToScreen(New Point(100, 100)))
g.DrawImage(img, imgLocation)
End Sub
Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
DrawImage(Panel1, e.Graphics)
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
DrawImage(PictureBox1, e.Graphics)
End Sub
In that code, there is an individual Paint event handler for each control and they both call a common method that does the drawing. If you want to, you can bundle it all into a single common event handler:
Private ReadOnly img As Image = Image.FromFile("file path here")
Private Sub Controls_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint,
PictureBox1.Paint
'The image will be drawn at (100,100) in form coordinates.
'Translate that location to coordinates for the current control.
Dim imgLocation = DirectCast(sender, Control).PointToClient(Me.PointToScreen(New Point(100, 100)))
e.Graphics.DrawImage(img, imgLocation)
End Sub

Not able to clear drawings in PictureBox using VB.NET

I use the following code to make simple free-hand (brush) drawings over PictureBox1. Drawing is fine, but not able to clear the drawings I made permanently. If I click Button1 the drawings will be cleared, but once I move over PictureBox1 all old drawings (and PictureBox1 image) appear again. Any suggestions?
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = MouseButtons.Left Then
mousePath.StartFigure()
End If
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
'// slide annotations
If e.Button = MouseButtons.Left Then
Try
mousePath.AddLine(e.X, e.Y, e.X, e.Y) 'Add mouse coordiantes to mousePath
Catch
End Try
End If
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
'// slide annotations
Try
'// drwaing options
myUserColor = System.Drawing.Color.Red
myAlpha = 255
myPenWidth = 3
CurrentPen = New Pen(myUserColor, myPenWidth)
e.Graphics.DrawPath(CurrentPen, mousePath)
Catch
End Try
End Sub
Private Sub Button1_Click_2(sender As Object, e As EventArgs) Handles Button1.Click
Dim g As Graphics
g = PictureBox1.CreateGraphics()
g.Clear(PictureBox1.BackColor)
g.Dispose()
End Sub
NEVER call CreateGraphics. ALWAYS do ALL your drawing in the Paint event handler. Your are creating a Graphics object in your Click event handler and clearing that, but what use is that when you do the drawing again in Paint event handler the next time that event is raised?
What you need to do is store all the data that represents your drawing in one or more fields, update that data whenever you want to change the drawing and draw using that data in the Paint event handler. If you want to clear the drawing, you clear that data and then force a repaint by calling Invalidate. In your Paint event handler you are drawing a GraphicsPath stored in the mousePath field. That means that, in your Click event handler, you need to clear that GraphicsPath and then call Invalidate. That will then prompt a Paint event that will first clear the existing drawing and then do the new. As there is no new to do, it will remain clear.

Display an image in picturebox from specific position

I have a picturebox that "works" as button. I have load an image map as background image, to use it for buttons conditions (click, hover etc).
As default, background image shows it's top left position, the first icon. Let's say, how can I move (x) to 32px and (y) to 64? Something like css styles background-position: 32px 64px; for example.
If you need to reposition the image then I wouldn't use a PictureBox, just a Panel or draw the image on the surface of the form.
It is possible though with the following code. Notice that it removes the PictureBox's Image so you are losing the functionality of a PictureBox.
Public Class Form1
Private _moveIt As Boolean = False
Private _coyote As Image
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
_coyote = PictureBox1.Image
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
_moveIt = True
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If _moveIt = True Then
PictureBox1.Image = Nothing
e.Graphics.DrawImage(_coyote, New Rectangle(New Point(32, 64), _
New Size(_coyote.Width, _coyote.Height)))
End If
End Sub
End Class
To keep the PcitureBox's functionality (to use its Image property) you would have to create a new image which is a transformed version of the original image.

Graphics.DrawRectangle not working in control events

First of all thank you for taking the time out of your busy schedule to assist me.
I am developing a project (Win Application) with a Form and 3 textboxes (TextBox1, TextBox2 and TextBox3).
I need draw a rectangle around the textbox when focused this.
The code is:
Private Sub TextBox123_Enter(sender As Object, e As System.EventArgs) Handles TextBox1.Enter, TextBox2.Enter, TextBox3.Enter
Using g As Graphics = Me.CreateGraphics
Dim r As Rectangle = sender.Bounds
r.Inflate(4, 4)
g.DrawRectangle(Pens.Blue, r)
End Using
End Sub
The problem is the following:
The first time the textbox1 gains focus rectangle is not drawn.
The first time the textbox2 gains focus rectangle is not drawn.
Why not the rectangle is drawn when the first two events enter are fired?
Drawing with CreateGraphics is almost always not the correct approach. If you notice also, when you move from one box to another, the old rectangle is not being erased. You need to use the Form_Paint event to get it to work right. Or...perhaps simpler would be to create a UserControls which is 1-2 pixels larger than a child TextBox and set the backcolor of the UserControl canvas, draw your rectangle when the control gets the focus.
For form paint:
Public Class Form1
Private HotControl As Control
If you are only going to do TextBoxes, you can declare it As TextBox. This way it allows you to do the same for other control types. Set/clear the tracker:
Private Sub TextBox3_Enter(sender As Object, e As EventArgs) Handles TextBox3.Enter,
TextBox2.Enter, TextBox1.Enter
HotControl = CType(sender, TextBox)
Me.Invalidate()
End Sub
Private Sub TextBox1_Leave(sender As Object, e As EventArgs) Handles TextBox1.Leave,
TextBox2.Leave, TextBox3.Leave
HotControl = Nothing
Me.Invalidate()
End Sub
The Me.Invalidate tells the form to redraw itself, which happens in Paint:
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
If HotControl IsNot Nothing Then
Dim r As Rectangle = HotControl.Bounds
r.Inflate(4, 4)
e.Graphics.DrawRectangle(Pens.Blue, r)
End If
End Sub
You should also turn on Option Strict.
Try this in the click event handler
Private Sub TextBox1_Click(sender As Object, e As EventArgs) Handles TextBox1.Click
Using g As Graphics = Me.CreateGraphics()
Dim rectangle As New Rectangle(TextBox1.Location.X - 1, _
TextBox1.Location.Y - 1, _
TextBox1.Size.Width + 1, _
TextBox1.Size.Height + 1)
g.DrawRectangle(Pens.Blue, rectangle)
End Using
End Sub

Dynamically change pen color & paint when clicked

The Program
I'm playing around and learning about graphics using visual basic (coming from C++). I've made a program and I want to do two things: paint when the left mouse button is pressed, and stop when released, and also I want to be able to change the pen color using a colordialog. After hours of frustration, I've yet to combat these two problems.
The Code (Snippet)
Private obj As Graphics
Dim rect As Rectangle
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
obj = RichTextBox1.CreateGraphics
End Sub
Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
obj.Dispose()
End Sub
Private Sub RichTextBox1_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles RichTextBox1.MouseMove
With rect
.X = e.X
.Y = e.Y
.Width = TrackBar1.Value
.Height = TrackBar1.Value
End With
If ToolStripButton1.Checked = True Then
obj.DrawEllipse(Pens.Black, rect)
ElseIf ToolStripButton2.Checked = True Then
obj.DrawRectangle(Pens.Black, rect)
End If
ToolStripStatusLabel2.Text = (e.X & ", " & e.Y)
End Sub
Past Attempts (and frustrations)
My idea originally was to do this:
Dim myPen = New Pen(ButtonWithDC1.BackColor)
But doing so gave me an error message. I looked at Microsoft's documentation, but it wasn't useful for what I'm trying to do. I can create a pen just fine, but I'd like for the user to be able to change the color while the app is currently running.
GUI Layout
I don't have an attempt at my other problem (drawing while pressing the mouse down, not just by moving the mouse -- like a normal paint program), I don't even have a starting point for that solution. Thanks to everyone in advance.
Place a button (Button1) and picturebox (PictureBox1) on a form, also add a colordialog (ColorDialog1).
This code will allow you to draw on the picture box and choose the color using a color you select from the colordialog. The MouseDown event writes a flag that the mouse is down, and stores the last location. The MouseUp does similar. The MouseMove actually draws. Use a line and the last location.
Public Class Form1
Private myColor As Color = Color.Black
Private mouseIsDown As Boolean = False
Private previousLocation As System.Nullable(Of System.Drawing.Point) = Nothing
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myColor = If(ColorDialog1.ShowDialog() = Windows.Forms.DialogResult.OK, ColorDialog1.Color, myColor)
End Sub
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
mouseIsDown = True
previousLocation = e.Location
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If mouseIsDown Then
If previousLocation IsNot Nothing Then
Using g As Graphics = Graphics.FromImage(PictureBox1.Image)
g.DrawLine(New Pen(myColor), previousLocation.Value, e.Location)
End Using
PictureBox1.Invalidate()
End If
previousLocation = e.Location
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
mouseIsDown = False
previousLocation = Nothing
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.PictureBox1.Image = New Bitmap(PictureBox1.Width, PictureBox1.Height)
End Sub
End Class
Your question is a bit more involved than you think, and SO is not keen on multiple questions per post (not in your nest interest either - someone might know A and not B so wont bother answering).
To draw on Mousemove when the mouse is down, you need to track when the mouse is down (question A):
Private _mouseDown As Boolean
Private _mouseLoc As Point
Private _mouseNewLoc As Point
sub Ctl_MouseDown(sender...
' ToDo: add logic to check which button....
_mouseDown = True
_mouseLoc = New Point(e.X, e.Y)
End Sub
sub Ctl_MouseUp(sender...
_mouseDown = False
End Sub
Then mousemove can be used to capture the current location
Sub Ctl_MouseMove(sender....
If _mouseDn Then
_mouseNewLoc = New Point(e.X, e.Y)
Ctl.invalidate ' call to paint
End If
End Sub
' selected color from dialog or whereever
Private myColor As Color
Sub Ctl_Paint(sender....
If _mouseDn Then
' Pen ctor is overloaded...(Question B)
Using p As New Pen(myColor)
e.Graphics.DrawLine(p, _mouseLoc, _mouseNewLoc)
' plus more....
End Using
End If
This only addresses the questions posed; the bigger issue you have is tracking what has already been drawn. This will draw a line only while the mouse is down, but for a polygon or shape, you have to add code to redraw those parts. Either a List of the points which make up a polygon, or maybe save what you have to a bitmap and add to it. Thats a bit outside the scope of the question and depends on app factors. You also need a Drawing start/stop or way to signal when to stop adding lines or ovals or whatever (ovals are sort of simple: one at a time, lines as part of a shape will take some work).
Either way all painting has to take place in the Paint event (or OnPaint) if you want to see the shape/drawing/image develop.