Position a textbox on a control in a tablelayoutpanel - vb.net

I have a table layout panel on my form.
I have put a usercontrol in one if its cells.
Now I would like to position a textbox above this usercontrol, but I am not sure how to do the positioning.
The textbox is located on the form, not in the tablelayoutpanel.
I have tried a lot with .PointToScreen, but somehow I could not get it right.
The closest I could get was
Dim pt As Point
Me._ucGrid1.PointToScreen(Me._ucGrid1.Location)
Dim iGridOffsetTop As Integer = Me._ucGrid1.Top + pt.Y
Dim iGridOffsetLeft As Integer = Me._ucGrid1.Left + pt.X
But I guess that did not take the position of the table layout panel into account.
Could somebody please tell me where I went wrong?
Thank you!

Got it:
Dim iGridOffsetTop As Integer = Me._ucGrid1.Top
Dim iGridOffsetLeft As Integer = Me._ucGrid1.Left
Dim pt As Point
pt = Me.TableLayoutPanel1.Location
iGridOffsetLeft += pt.X
iGridOffsetTop += pt.Y

Related

Make a list of all Textbox values in a form

I asked a question before, related to this topic. I wanted to know how to make a loop that adds together all of the textbox.text values in a form. This is the response I got, and it works perfectly.
sum = 0
For Each ctrl In Me.Controls.OfType(Of TextBox)()
Dim txt As TextBox = DirectCast(ctrl, TextBox)
Dim i As Integer = 0
If Integer.TryParse(txt.Text, i) Then
sum = sum + i
End If
Next
What I want to know is how can I, using the same button, get the values of each text box in a form, and put them all together in one list/array?
It's quite a simple problem, but I just can't find the exact syntax for this anywhere.
Also, if a use a similar loop, but do list.Add(text), it just breaks the first loop.
Thanks in advance!
You just need to add the parsed integers to a List(Of Int32):
Dim list As New List(Of Int32)
For Each txt In Me.Controls.OfType(Of TextBox)()
Dim num As Int32 = 0
If Integer.TryParse(txt.Text, num) Then
list.Add(num)
End If
Next
Dim sum = list.Sum() ' easier ;-)
The cast to TextBox is not needed because ctrl is already a TextBox thanks to OfType.
Dim listOfTextBox = Me.Controls.OfType(Of TextBox).ToList()
Dim listOfValue = listOfTextBox.Select(Function(e) Integer.Parse(e.Text))
Dim sum = listOfValue.Sum()

Set postition of New Form related to Control

I'm stuck with basic's.
Here I need to place New Form "myForm2" in place of DataGridView's "myDgv" location.
Here is my approach:
Dim fl As New myForm2
fl.StartPosition = FormStartPosition.Manual
Dim p As Point = Me.PointToScreen(myDgv.Location)
fl.Location = p
fl.Show(Me)
Showed code places myForm2 at top-left position of the screen.
How to get it to place myForm2 at the top-left position of myDgv?
First, get the screen-coordinates of the grid:
Dim pt As Point = myDgv.PointToScreen(Point.Empty)
Then set the location of the form:
fl.Location = pt

Positioning UserControl relative to Form or Screen

Is there any way to get and set the .Location of an UserControl, which is positioned on a Container (e.g. a Panel) relative to the "most-parental" Form?
I know that there is the possibility of calculating the offset of the Panel itself and adding it to the .Location of the UserControl.
But in my case the number of parent-levels is unknown and can differ from case to case.
So once the UserControl could be placed on a Panel which is directly on the Form. But there is also the possibility that the UserControl is placed on a 2nd Panel which is on the 1st Panel which is on the Form.
What if you take your idea of calculating the offset of the Panel and calculate the offset recursively back to the Form? i.e. I have a Textbox1 within a Panel2 within a Panel1. Panel1 is located at .Left 266, Panel2 is at .Left 77 within Panel1.
Private Function GetLeftOffset(ByVal UserControl As Control) As Int32
Dim intLeftOffset As Int32 = 0
If Not TypeOf UserControl.Parent Is Form Then
intLeftOffset = UserControl.Parent.Left
intLeftOffset += GetLeftOffset(UserControl.Parent)
End If
Return intLeftOffset
End Function
Now if I GetLeftOffset(Me.TextBox1), it returns an Offset of 343 (266 + 77).
I use this function to place a context menu near a control like a textbox or button. You can set x and y to zero to return the location of a control itself.
'--- Return the screen location of a control with an offset
Private Function Offset(ByRef controlObj As Control, ByVal x As Integer, ByVal y As Integer) As Point
Dim pt As Point
Dim parentObj As Control = controlObj.Parent
Do While parentObj IsNot controlObj.FindForm
x += parentObj.Location.X
y += parentObj.Location.Y
parentObj = parentObj.Parent
Loop
pt = PointToScreen(controlObj.Location)
pt.Offset(x, y)
Return pt
End Function
Try:
Dim pnt As Point
pnt = UserControl.PointToScreen(New Point(0, 0))
pnt = Me.PointToClient(pnt)
This calculates the location relative to your Form. Change Me to any control, if you like
Now, if you want to set the location eg (100, 100), relative to your Form
pnt = Me.PointToScreen(New Point(100, 100))
pnt = UserControl.Parent.PointToClient(pnt)
UserControl.Location = pnt
Remember that, if the new location is outside the parent area the control will not be visible.

Add LineShape programatically in VB.NET WinForms

How do you add a LineShape programmatically in VB.NET WinForms?
I'm looking to write something like you would for a Label , CheckBox or whatever else:
Dim somelabel as New Label
somelabel.Text = "Whatever"
somelabel.Location = New Point(200, 200)
Me.Controls.Add(somelabel)
Etc.
My purpose is to create thin dividing lines between the rows and columns of 16 Labels that form a 4x4 grid.
I appreciate that, since LineShape is a part of VB PowerPacks, this may present some difficulties, such as having to use Imports ... or, if really necessary, import a .dll. But I'd like to see all your ideas/solutions!
First, import the powerpacks namespace to give you access to the control:
Imports Microsoft.VisualBasic.PowerPacks
Then you could do it like this:
Dim startx As Integer
Dim starty As Integer
Dim endx As Integer
Dim endy As Integer
Dim yourline As New LineShape(startx, starty, endx, endy)
Where startx = the x starting position, starty = the y starting position, endx = the ending x position and endy = the ending y position.
If you want to put it into a canvas, simply:
Dim yourcanvas As ShapeContainer
canvas.Parent = formName
yourline.Parent = canvas
For more information and an API reference, go to:
http://msdn.microsoft.com/en-us/library/bb918067.aspx

What is the starting position of cell in DataGridView

I have 10 columns in DataGridView.
If i click first cell,popup window's starting position should be near first cell.
If i click 2nd cell,popup window's starting position should be near 2nd cell.
If i click 3rd cell,popup window's starting position should be near 3rd cell.
how to change RowIndex and ColumnIndex accordingly?
Used following code in Datagridview_CellClick
sub
mPopup.Show(datagridview.PointToScreen(New Point(e.RowIndex , e.ColumnIndex )))
end sub
Since this is .NET all indexes start at 0.
The value range for both e.RowIndex and e.ColumnIndex would only be 0-2.
I would imagine that your results are that your selected point ends up being in the upper left hand corner.
You'll need to calculate where the actual cell is first, then apply that value to the New Point method.
This post has a good example
Current Selected Cell Position
According to that post, you only need to call
Dim rect as Rectangle = DataGridView.GetCellDisplayRectangle(e.RowIndex, e.ColumnIndex)
Dim left as int = rect.Left
Dim top as int = rect.Top
to get the correct Point values.
then pass that back to
datagridview.PointToScreen(New Point(top,left))
Be sure to check my syntax, its been a while since I wrote VB.
You need to add up all the position offsets to get the correct point.
This code shows a contextmenu at the bottom right corner of a cell that is clicked on:
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
Dim rect As Rectangle = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
Dim formBorderWidth As Integer = CInt((Me.Width - Me.ClientSize.Width) / 2)
Dim formTitlebarHeight As Integer = Me.Height - Me.ClientSize.Height - 2 * formBorderWidth
Dim left As Integer = Me.Left + formBorderWidth + DataGridView1.Left + rect.Left + rect.Width
Dim top As Integer = Me.Top + formTitlebarHeight + formBorderWidth + DataGridView1.Top + rect.Top + rect.Height
Dim pt As New Point(left, top)
ContextMenuStrip1.Show(pt)
End Sub
I feel there is probably an easier way to do this but this works for now.