How to create and print a table using Drawing Vb.net - vb.net

I'm trying to recreate a label using Vb.net
I have this label that I want to recreate:
What I did till now:
I tried to change lines but couldn't do to look like that, I don't even know how to arrange or move or add new column or rows.
Code that I found on the internet:
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        Dim ht As Single = 7 ' Table Height
        Dim wt As Single = 5 ' Table Width
        Dim r As Integer = 15, c As Integer = 2 ' Rows and Cols in Table
        Dim Cht As Single ' Cell Height
        Dim lst As Single ' last line drawn
        Dim i As Integer
        Dim p As Pen
        Cht = CSng(Math.Round(ht / r, 2)) * c
        lst = 0.5F + Cht ' 0.5->default margin
        p = New Pen(Color.Black, 0.025F)
        e.Graphics.PageUnit = GraphicsUnit.Inch
        e.Graphics.DrawRectangle(p, 0.5F, 0.5F, wt, ht) ' border of the table
        p.Color = Color.Blue
        For i = 0 To CInt(r / c) - 1 ' lines in the table
            e.Graphics.DrawLine(p, 0.5F, lst, 0.5F + wt, lst)
            lst += Cht
        Next
 
    End Sub
I'm lost, I don't know how to create a similar label. What's the best way to do that?

The following will help you get started in creating the label pictured in your OP.
I'll be using a Windows Forms App (.NET Framework) project with a Form named Form1.
Add the following Imports statements:
Imports System.Drawing.Drawing2D
Imports System.Drawing.Printing
To draw a rounded rectangle, we'll convert code from here to VB.NET.
RoundRect:
Public Function RoundRect(bounds As Rectangle, radius1 As Integer, radius2 As Integer, radius3 As Integer, radius4 As Integer) As GraphicsPath
Dim diameter1 As Integer = radius1 * 2
Dim diameter2 As Integer = radius2 * 2
Dim diameter3 As Integer = radius3 * 2
Dim diameter4 As Integer = radius4 * 2
Dim arc1 As Rectangle = New Rectangle(bounds.Location, New Size(diameter1, diameter1))
Dim arc2 As Rectangle = New Rectangle(bounds.Location, New Size(diameter2, diameter2))
Dim arc3 As Rectangle = New Rectangle(bounds.Location, New Size(diameter3, diameter3))
Dim arc4 As Rectangle = New Rectangle(bounds.Location, New Size(diameter4, diameter4))
Dim path As GraphicsPath = New GraphicsPath()
'arc - top left
If radius1 = 0 Then
path.AddLine(arc1.Location, arc1.Location)
Else
path.AddArc(arc1, 180, 90)
End If
'arc - top right
arc2.X = bounds.Right - diameter2
If radius2 = 0 Then
path.AddLine(arc2.Location, arc2.Location)
Else
path.AddArc(arc2, 270, 90)
End If
'arc - bottom right
arc3.X = bounds.Right - diameter3
arc3.Y = bounds.Bottom - diameter3
If radius3 = 0 Then
path.AddLine(arc3.Location, arc3.Location)
Else
path.AddArc(arc3, 0, 90)
End If
'arc - bottom left
'arc4.X = bounds.Right - diameter4
arc4.Y = bounds.Bottom - diameter4
arc4.X = bounds.Left
If radius4 = 0 Then
path.AddLine(arc4.Location, arc4.Location)
Else
path.AddArc(arc4, 90, 90)
End If
path.CloseFigure()
Return path
End Function
Note: The code below demonstrates how to draw the outer rectangle, as well as, the first row. It also shows how to write text and use MeasureString to assist in calculating positions.
CreateProductLabel:
Private Sub CreateProductLabel(g As Graphics)
'ToDo: add (additional) desired code
Dim widthOuter As Integer = 600 'width of outer rectangle
Dim heightOuter As Integer = 325 'height of outer rectangle
Dim heightRow1 As Single = 80 'height of row 1
Dim xPosRightRow1Col1 As Single = 200 'x-position of row1, column 1
Dim xPosRightRow1Col2 As Single = 400 'x-position of row1, column 2
'specifying '0', indicates to use the smallest width possible
Using penDimGray As Pen = New Pen(Color.DimGray, 0)
'create rectangle for outer border
Dim outerRect As Rectangle = New Rectangle(0, 0, widthOuter, heightOuter)
'draw outer rectangle
Using path As GraphicsPath = RoundRect(outerRect, 10, 10, 10, 10)
g.DrawPath(penDimGray, path)
End Using
'draw horizontal line
g.DrawLine(penDimGray, New PointF(0, heightRow1), New PointF(outerRect.Width, heightRow1))
'draw vertical line - right side of row1, col 1
g.DrawLine(penDimGray, New PointF(xPosRightRow1Col1, 0), New PointF(xPosRightRow1Col1, heightRow1))
'draw vertical line - right side of row1, col 2
g.DrawLine(penDimGray, New PointF(xPosRightRow1Col2, 0), New PointF(xPosRightRow1Col2, heightRow1))
End Using
'size of the string(s); the height/width will be used in calculations
Dim sizeProductionDate As SizeF = New SizeF() 'initialize
Dim sizeShipper As SizeF = New SizeF() 'initialize
Dim sizeCosigner As SizeF = New SizeF() 'initialize
'draw text - headings
Using penBlack As Pen = New Pen(Color.Black, 2)
Using fontArial9Bold As Font = New Font("Arial", 9, FontStyle.Bold)
Using brush As SolidBrush = New SolidBrush(Color.Black)
'draw strings
g.DrawString("Shipper:", fontArial9Bold, brush, 5.0F, 2.0F)
g.DrawString("Cosigner:", fontArial9Bold, brush, xPosRightRow1Col1 + 2.0F, 2.0F)
'determine size of specified string
'the size (height/width) will be used in calculations below
sizeShipper = g.MeasureString("Shipper:", fontArial9Bold)
sizeCosigner = g.MeasureString("Cosigner:", fontArial9Bold)
End Using
End Using
Using fontArial8Bold As Font = New Font("Arial", 8, FontStyle.Bold)
Using brush As SolidBrush = New SolidBrush(Color.Black)
'draw String - Production Date
g.DrawString("Production Date:", fontArial8Bold, brush, xPosRightRow1Col2 + 2.0F, 2.0F)
'determine size of specified string
'the size (height/width) will be used in calculations below
sizeProductionDate = g.MeasureString("Production Date:", fontArial8Bold)
'draw string - Data de Producao
'this string Is positioned at the same Y-position, but for the X-position, add the height of the previous string
g.DrawString("Data de Producao", fontArial8Bold, brush, xPosRightRow1Col2 + 2.0F, 2.0F + sizeProductionDate.Height)
End Using
End Using
End Using
'draw product label information
Using penBlack As Pen = New Pen(Color.Black, 1)
Using fontArial9Regular As Font = New Font("Arial", 9, FontStyle.Regular)
Using brush As SolidBrush = New SolidBrush(Color.Black)
'draw strings
g.DrawString("A 1 VERDE LIMITADA", fontArial9Regular, brush, 5.0F + sizeShipper.Width, 2.0F)
g.DrawString("Plydor Seafood Limited", fontArial9Regular, brush, xPosRightRow1Col1 + 2.0F + sizeCosigner.Width, 2.0F)
End Using
End Using
End Using
End Sub
Note: To generate a QR code, one can use a NuGet package such as QRCoder.
For testing, follow the instructions below to draw to a Panel and/or to print using a PrintDocument.
Open Solution Explorer
In VS menu, click View
Select Solution Explorer
Open Properties Window
In VS menu, click View
Select Properties Window
Add a Panel to Form1 (name: Panel1; Size: 615, 340)
Subscribe to Paint event
Click on panel in form to select it.
In Properties Window, click
Double-click Paint to add the event handler to the form
Add a PrintDocument to Form1 (name: PrintDocument1)
Subscribe to Paint event
In Properties Window, select PrintDocument1 from the drop-down
Click
Double-click PrintPage to add the event handler to the form
Add a Button to the Form (name: btnPrint)
Subscribe to Click event
In Properties Window, select btnPrint from the drop-down
Click
Double-click Click to add the event handler to the form
Usage (Panel):
Private Sub Panel1_Paint(sender As Object, e As PaintEventArgs) Handles Panel1.Paint
CreateProductLabel(e.Graphics)
End Sub
Usage (PrintDocument):
Private Sub btnPrint_Click(sender As Object, e As EventArgs) Handles btnPrint.Click
PrintDocument1.Print()
End Sub
Private Sub PrintDocument1_PrintPage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
CreateProductLabel(e.Graphics)
End Sub
Here's what the Form looks like:
Resources:
How to draw a rounded rectangle in c#
System.Drawing.Namespace
System.Drawing.Drawing2D Namespace
System.Drawing.Printing Namespace
Graphics.MeasureString Method

Related

Load a screenshot into a function as a bitmap without saving it as a file first

Basically my program takes a "sample" image from the user, then takes a screenshot of the entire user's screen, and then if it found that sample on the users screen, it returns the coordinates of it and moves the mouse there.
It works fine if I save the screenshot to a bitmap and compare the sample to a file, but when I try to call the screenshot directly into the function, it fails to find a match.
Any idea why?
First the code for the button click that triggers the comparison:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim clickhere As Point
Dim bounds As Rectangle
Dim screenshot As System.Drawing.Bitmap
Dim graph As Graphics
bounds = Screen.PrimaryScreen.Bounds
screenshot = New System.Drawing.Bitmap(bounds.Width, bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
graph = Graphics.FromImage(screenshot)
graph.CopyFromScreen(bounds.X, bounds.Y, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy)
Dim src As New Bitmap(srcpath.Text)
Dim g = Graphics.FromImage(screenshot)
g.CopyFromScreen(0, 0, 0, 0, screenshot.Size)
g.Dispose()
clickhere = BitmapExtension.Contains(screenshot, src)
MsgBox(clickhere.ToString)
Cursor.Position = clickhere
End Sub
And here is the function:
Imports System.Drawing
Imports System.Runtime.CompilerServices
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Module BitmapExtension
<Extension()>
Public Function Contains(src As Bitmap, ByRef bmp As Bitmap) As Point
'
'-- Some logic pre-checks
'
If src Is Nothing OrElse bmp Is Nothing Then Return New Point(Integer.MinValue, Integer.MinValue)
If src.Width < bmp.Width OrElse src.Height < bmp.Height Then
Return New Point(Integer.MinValue, Integer.MinValue)
End If
'
'-- Prepare optimizations
'
Dim sr As New Rectangle(0, 0, src.Width, src.Height)
Dim br As New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim srcLock As BitmapData = src.LockBits(sr, Imaging.ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb)
Dim bmpLock As BitmapData = bmp.LockBits(br, Imaging.ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb)
Dim sStride As Integer = srcLock.Stride
Dim bStride As Integer = bmpLock.Stride
Dim srcSize As Integer = sStride * src.Height
Dim bmpSize As Integer = bStride * bmp.Height
Dim srcBuff(srcSize) As Byte
Dim bmpBuff(bmpSize) As Byte
Marshal.Copy(srcLock.Scan0, srcBuff, 0, srcSize)
Marshal.Copy(bmpLock.Scan0, bmpBuff, 0, bmpSize)
' we don't need to lock the image anymore as we have a local copy
bmp.UnlockBits(bmpLock)
src.UnlockBits(srcLock)
Return FindMatch(srcBuff, src.Width, src.Height, sStride, bmpBuff, bmp.Width, bmp.Height, bStride)
End Function
Private Function FindMatch(srcBuff() As Byte, srcWidth As Integer, srcHeight As Integer, srcStride As Integer,
bmpBuff() As Byte, bmpWidth As Integer, bmpHeight As Integer, bmpStride As Integer) As Point
For Y As Integer = 0 To srcHeight - bmpHeight - 1
For x As Integer = 0 To srcWidth - bmpWidth - 1
If AllPixelsMatch(x, Y, srcBuff, srcStride, bmpBuff, bmpWidth, bmpHeight, bmpStride) Then
Return New Point(x, Y)
End If
Next
Next
Return New Point(Integer.MinValue, Integer.MinValue)
End Function
Private Function AllPixelsMatch(X As Integer, Y As Integer, srcBuff() As Byte, srcStride As Integer,
bmpBuff() As Byte, bmpWidth As Integer, bmpHeight As Integer, bmpStride As Integer) As Boolean
For by As Integer = 0 To bmpHeight - 1
For bx As Integer = 0 To bmpWidth - 1
Dim bmpIndex As Integer = by * bmpStride + bx * 4
Dim a As Byte = bmpBuff(bmpIndex + 3)
'If bmp pixel is not transparent, check if the colours are identical
If a > 0 T
hen
Dim srcX = X + bx
Dim srcY = Y + by
Dim srcIndex = srcY * srcStride + srcX * 4
For i As Integer = 0 To 2
'check if the r, g and b bytes match
If srcBuff(srcIndex + i) <> bmpBuff(bmpIndex + i) Then Return False
Next
Else
'if bmp pixel is transparent, continue seeking.
Continue For
End If
Next
Next
Return True
End Function
End Module

How to Draw Horizontal Ellipse (AutoCAD 2014)

Goal
To create an Ellipse in AutoCAD 2014 with the possibility of rotating it horizontally (as seen in the red rectangle below).
Attempt
I was able to create the Ellipse but I cannot seem to find how to rotate it horizontally.
CreateEllipse(AcadDoc)
Public Function CreateEllipse(ByRef AcadDoc As Document) As ObjectId
Dim returnId As ObjectId
Dim db As Database = AcadDoc.Database
Dim x As Vector3d = db.Ucsxdir
Dim y As Vector3d = db.Ucsydir
Dim normalVec As Vector3d = x.CrossProduct(y)
Dim axisvec As Vector3d = normalVec.GetNormal()
Dim CenterPoint As New Point3d(Me.StartPoint.X + 50, Me.StartPoint.Y + 40, 0)
Dim aEllipse As New Ellipse(CenterPoint, axisvec, New Vector3d(0, 20, 0), 0.5, 0, Math.PI * 2)
returnId = Utils.CreateAcadObject(AcadDoc, aEllipse)
aEllipse.Dispose()
Utils.regenLayers()
Return returnId
End Function
Utils.CreateAcadObject(AcadDoc, aEllipse)
Public Function CreateAcadObject(ByRef acDoc As Document, ByRef acObj As Object) As ObjectId
Dim objId As ObjectId
Dim acCurDb As Database = acDoc.Database 'Get the current database
Dim acBlkTbl As BlockTable
Dim acBlkTblRec As BlockTableRecord
Using lock As DocumentLock = acDoc.LockDocument
'Start a transaction
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
'Open Model space for write
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
acBlkTblRec = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
acObj.SetDatabaseDefaults()
'Add the object to the drawing
objId = acBlkTblRec.AppendEntity(acObj)
acTrans.AddNewlyCreatedDBObject(acObj, True)
'Commit the changes and dispose of the transaction
acTrans.Commit()
End Using
End Using
Return objId
End Function
This is the result I get:
I'll keep trying to figure it out and I'll post my answer when I end up doing so.
On the line where you create the ellipse:
Dim aEllipse As New Ellipse(CenterPoint, axisvec, New Vector3d(0, 20, 0), 0.5, 0, Math.PI * 2)
You need to change the coordinates of the major axis like this:
Dim aEllipse As New Ellipse(CenterPoint, axisvec, New Vector3d(20, 0, 0), 0.5, 0, Math.PI * 2)

Obtaing the ROI in Visual basic errors in code after conversion from C

I've been working on obtaining the ROI of an image, I'm trying to get a square shaped box that will hoover around the region an be able to click and get the standard deviation. I'm familiar with c so i used the c to VB converter, but im getting errors that the statement is not valid in namespace. Everything seems to compatible to VB code. I will be grateful for any suggestions on this matter. Thanks
Private Function DrawRoi(Image As Bitmap, rect As RectangleF) As oid
Dim roi As New Rectangle()
roi.X = CInt(CSng(Image.Width) * rect.X)
roi.Y = CInt(CSng(Image.Height) * rect.Y)
roi.Width = CInt(CSng(Image.Width) * rect.Width)
roi.Height = CInt(CSng(Image.Height) * rect.Height)
Dim timer As New Stopwatch()
timer.Start()
' graphics manipulation takes about 240ms on 1080p image
Using roiMaskImage As Bitmap = CreateRoiMaskImage(ImageWithRoi.Width, ImageWithRoi.Height, roi)
Using g As Graphics = Graphics.FromImage(ImageWithRoi)
g.DrawImage(Image, 0, 0)
g.DrawImage(roiMaskImage, 0, 0)
Dim borderPen As Pen = CreateRoiBorderPen(ImageWithRoi)
g.DrawRectangle(borderPen, roi)
End Using
End Using
Debug.WriteLine("roi graphics: {0}ms", timer.ElapsedMilliseconds)
Me.imagePictureBox.Image = ImageWithRoi
End Function
Private Function CreateRoiMaskImage(width As Integer, height As Integer, roi As Rectangle) As Bitmap
Dim image As New Bitmap(width, height, PixelFormat.Format32bppArgb)
Using g As Graphics = Graphics.FromImage(image)
Dim dimBrush As New SolidBrush(Color.FromArgb(64, 0, 0, 0))
g.FillRectangle(dimBrush, 0, 0, width, height)
Dim roiBrush As New SolidBrush(Color.Red)
g.FillRectangle(roiBrush, roi)
image.MakeTransparent(Color.Red)
Return image
End Using
End Function

Vb.net changing colors of a picture

I am struggling with the following problem: I have a small picture with is painted in red. This color must be changed to another color (users'choice). I used msdn and some googling did the following:
Private Function GetPicture(Iterator As Integer, tempfile As String) As String
Dim Rstring = ""
If Colors.Count = 0 OrElse Iterator >= Colors.Count Then
Rstring = tempfile
Else
Dim NewPicture = My.Computer.FileSystem.GetTempFileName()
My.Computer.FileSystem.CopyFile(tempfile, NewPicture, True)
Dim mypict = New Bitmap(NewPicture)
Dim ColorList As New List(Of Color)
For x = 0 To mypict.Width - 1
For y = 0 To mypict.Height - 1
Dim mypixel = mypict.GetPixel(x, y)
If ColorList.Contains(mypixel) = False Then
ColorList.Add(mypixel)
End If
Next
Next
Dim NewColor = Color.FromArgb(255, 0, 0, 255)
Dim ListOfColorMaps As New List(Of ColorMap)
For Each elem In ColorList
Dim newcolormap = New ColorMap
newcolormap.OldColor = elem
newcolormap.NewColor = NewColor
ListOfColorMaps.Add(newcolormap)
Next
Dim imageAttributes As New ImageAttributes()
Dim width As Integer = mypict.Width
Dim height As Integer = mypict.Height
Dim colorMap As New ColorMap()
'colorMap.OldColor = Color.FromArgb(255, 0, 0, 0) ' opaque red
'colorMap.NewColor = Color.FromArgb(255, 0, 0, 255) ' opaque blue
Dim remapTable As ColorMap() = ListOfColorMaps.ToArray
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap)
Dim tempBmp = New Bitmap(width, height)
Dim g = Graphics.FromImage(tempBmp)
g.DrawImage(tempBmp, New Rectangle(0, 0, width, height), 0, 0, width, height, GraphicsUnit.Pixel, imageAttributes)
g.Save()
g.Dispose()
mypict.Dispose()
Dim NewFileName = NewPicture.Remove(NewPicture.IndexOf("."c) - 1) & ".png"
tempBmp.Save(NewFileName, Imaging.ImageFormat.Png)
My.Computer.FileSystem.DeleteFile(NewPicture)
tempBmp.Dispose()
Rstring = NewPicture
End If
Return Rstring
The Code runs without exceptions, and it seems to find the desired colors but the saved tempbmp contains no picture. Does this happen because the code runs in a dll without graphic?
You can pretty much ignore the "IF" part - that has something to do with another usecase.
Greetings and sincere thanks
Christian Sauer
You are getting no picture displayed because you are drawing an empty bitmap.
Your problem starts here:
Dim tempBmp = New Bitmap(width, height)
Dim g = Graphics.FromImage(tempBmp)
g.DrawImage(tempBmp, New Rectangle(0, 0, width, height), 0, 0, width, height, _
GraphicsUnit.Pixel, imageAttributes)
You create a new bitmap (probably with a white background).
Then you create a new Graphics object from your empty bitmap.
Then you draw the empty bitmap onto itself.
What you should be doing is drawing the mypict object (which is the bitmap whose colors you want to change). Thus your third line should be as follows:
g.DrawImage(mypict, New Rectangle(0, 0, width, height), 0, 0, width, height, _
GraphicsUnit.Pixel, imageAttributes)
Since the Graphics object g is associated with tempBmp (which is empty prior to the DrawImage operation) drawing mypict will draw to it with your parameters.
One other recommendation is that you remove the g.Save() line. You save a graphics object when you plan to restore it later. Doing a Graphics.Save() does not save a picture. What really saves the changes you have made is the tempBmp.Save() line.

dragging during runtime

the user has the option of dragging several pictureboxes around the form. when he lets go of the mouse, the picturebox will take on a new position on the form. this i have done succesfully thanks to the stackoverflow community.
i would like to implement the following:
on mouseup, if the picturebox position is within some amount maybe 50 or 100 (i dont know what units VB.net) uses, i would like it to be dropped exactly in a defined position. sort of like if you play checkers on yahoo games, you dont have to place the piece exactly on the square only approximately.
please help me with a solution in vb.net
This would work well, I think (cellSize is the "resolution" to which the control will "snap", assuming that each cell is square).
Prerequisites: you will need to have a PictureBox (or some other control) that you want to move around on your Form. Put the sample code below in your form's code and attach the MouseDown, MouseMove and MouseUp events of that control to these event handlers. You can attach the events using the property grid (click the events button, select the event, and use the combo box to select the corresponding event handler).
VB.NET:
Private Sub SetControlPosition(ByVal control As Control, ByVal targetPoint As Point, ByVal cellSize As Integer)
    Dim roundedLocation As New Point(CInt((Math.Round(CSng(targetPoint.X) / cellSize) * cellSize)), CInt((Math.Round(CSng(targetPoint.Y) / cellSize) * cellSize)))
    control.Location = roundedLocation
End Sub
If you want the control location to snap to some specific pre-defined locations, you can do like this instead (_allowedLocations defines two allowed locations; x=50, y=50 and x=500, y=500):
Private _allowedLocations As Point() = {New Point(50, 50), New Point(500, 500), New Point(700, 100)}
Private Sub SetControlPosition(ByVal control As Control, ByVal targetPoint As Point, ByVal cellSize As Integer)
    Dim shortestDistance As Integer = Integer.MaxValue
    Dim nearestLocationIndex As Integer = -1
   
    For i As Integer = 0 To _allowedLocations.Length - 1
        Dim width As Integer = targetPoint.X - _allowedLocations(i).X
        Dim height As Integer = targetPoint.Y - _allowedLocations(i).Y
        Dim distance As Integer = CInt(Math.Sqrt(Math.Pow(width, 2) + Math.Pow(height, 2)))
        If distance < shortestDistance Then
            shortestDistance = distance
            nearestLocationIndex = i
        End If
    Next
    control.Location = _allowedLocations(nearestLocationIndex)
End Sub
Example code calling the method (including moving the control with the mouse):
Private _mouseDownLocation As Point = Point.Empty
Private Sub PictureBox_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
    If (e.Button And MouseButtons.Left) = System.Windows.Forms.MouseButtons.Left Then
        _mouseDownLocation = e.Location
    End If
End Sub
Private Sub PictureBox_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
    If (e.Button And MouseButtons.Left) = System.Windows.Forms.MouseButtons.Left Then
        Dim target As Control = DirectCast(sender, Control)
        target.Location = New Point(target.Location.X + e.Location.X - _mouseDownLocation.X, target.Location.Y + e.Location.Y - _mouseDownLocation.Y)
    End If
End Sub
Private Sub PictureBox_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs)
    If (e.Button And MouseButtons.Left) = System.Windows.Forms.MouseButtons.Left Then
        Dim target As Control = DirectCast(sender, Control)
' Snap the control in place, to nearest 100x100 corner '
        SetControlPosition(target, target.Location, 100)
    End If
End Sub
The SetControlPosition method in C# (as an extra bonus):
private void SetControlPosition(Control control, Point targetPoint, int cellSize)
{
Point roundedLocation = new Point(
(int)(Math.Round((float)targetPoint.X / cellSize) * cellSize),
(int)(Math.Round((float)targetPoint.Y / cellSize) * cellSize)
);
control.Location = roundedLocation;
}