Creating handle in a Windows Form with a declared object as an array - vb.net

Im trying to make a Connect 4 game just to practice some windows forms which im new to. What my code does is creates a grid of 7 x 6 regularly spaces blank PictureBox's. But since im creating them in the script and not using the form1 design windows i dont know how i would add Handles to them, especially since the PictureBox's are in an array. Any ideas?
Public Class Form1
Dim Grid(6, 5) As PictureBox
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Button1.Visible = False
Me.FormBorderStyle = FormBorderStyle.FixedSingle
For i As Integer = 0 To 6
For j As Integer = 0 To 5
Grid(i, j) = New PictureBox
Grid(i, j).BackColor = Color.LightGray
Grid(i, j).Size = New Size(90, 90)
Grid(i, j).Location = New Point((i * 100) + 10, (j * 100) + 10)
Grid(i, j).Visible = True
Controls.Add(Grid(i, j))
Next
Next
End Sub
Private Sub Grid_MouseHover(sender As Object, e As EventArgs) Handles Grid(x, y).MouseHover 'Doesnt work
'Run depending on which picturebox in array
End Sub
End Class
I can get an error which is "Handles clause requires a WithEvents variable defined in the containing type or one of its base types."

One possible way would be to set the .Tag property using the coordinates -
add something like into your For..Next loop
Grid(i, j).Tag = i.ToString & j.ToString
and use
AddHandler Grid(i, j).MouseHover, AddressOf Grid_MouseHover
and add this after the one above.
Then, change the first line of your MouseHover Sub to
Private Sub Grid_MouseHover(sender As Object, e As EventArgs)
with no handler on the end.
Finally, change the type of the sender to a PictureBox
Private Sub Grid_MouseHover(sender As Object, e As EventArgs)
Dim Pbox As PictureBox = CType(sender, PictureBox)
Dim i As Integer = Integer.Parse(Pbox.Tag.ToString(0))
Dim j As Integer = Integer.Parse(Pbox.Tag.ToString(1))
End Sub
To access the Picturebox and its properties, just use PBox and if you need the coordinates, use i and j

Related

Animated sliding form VB.Net

EDIT:
So now my form location is established as per ZackRyan's answer but I still can't get it to move back to original location after it slides left.
This is the code I expect to move the form to original location
Private Sub Label7_Click(sender As Object, e As EventArgs) Handles Label7.Click
Me.Close()
'Testing.StartPosition.CenterScreen
For MoveLeft = Form2.Location.X To 30 Step 1
Form2.Left = MoveLeft
Form2.Refresh()
Threading.Thread.Sleep(0)
Next
End Sub
This is the original location:
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim xLoc = Me.Location.X
Dim yLoc = Me.Location.Y
Me.Location = New Point(xLoc, yLoc)
End Sub
------------------------------------------//--------------------------------------------------
I'm creating a windows app where a form moves to the left smoothly, all ok with this. My problem is bringing it back to it's initial position.
The form is loaded with default position set to CenterScreen I then use the following to move it to the left:
Private Sub Label3_Click(sender As Object, e As EventArgs) Handles Label3.Click
For MoveLeft = FormStartPosition.CenterScreen To 18 Step 1
Me.Left -= MoveLeft
Me.Refresh()
Threading.Thread.Sleep(1)
Next
To make it go back I'm trying the inverse:
Private Sub Label9_Click(sender As Object, e As EventArgs) Handles Label9.Click
For MoveLeft = FormStartPosition.CenterScreen To 18 Step 1
Me.Left = MoveLeft
Me.Refresh()
Threading.Thread.Sleep(1)
Next
This only works partially. The form moves to the right which is what is required, but instead of moving from the current position to CenterScreen, if moves completely at the bottom of the page.
I basically need it to return to its original center screen position smoothly.
Simply store the form's position(on form load) in some variables...
E.g.
Dim xLoc = MyForm.Location.X
Dim yLoc = MyForm.Location.Y
'Or
Dim xLoc = MyForm.Bounds.Left
Dim yLoc = MyForm.Bounds.Top
'or
Dim loc As Point = MyForm.Location
then use it as follows :
MyForm.Location = New Point(xLoc,yLoc)
'or
MyForm.Location = New Point(loc)
And one last thing , i really don't find your code fascinating enough to slide in a form .. You can easily use a Timer for that :
Dim Withevents tmr As New Forms.Timer
Dim myXLocation as integr
Private sub Btn_Click()
Tmr.start()
Private sub tmr_Tick()
myXloc= myXloc+ 1
MyForm.Location=New Point(myXloc,yloc)
If myXloc>= 190 Then 'change 190 to whatever u want :)
Tmr.Stop()
End if

Labels don't redraw on Form.Refresh()

I have a form on which in the Paint event some labels with some information are drawn inside a panel - this works fine. However I would like to have the text on the labels being changed depending on the value of a Trackbar that is placed on the same form. This is the Trackbar-Scroll Event which should refresh the whole form:
Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
Me.Refresh()
End Sub
And this is the code that draws the labels on the form:
Public Sub Form_Paint(sender As Object, e As PaintEventArgs)
For i = 0 To 10
Dim tb As New Label
tb.Name = "tb" & CStr(i)
If Me.TrackBar1.Value = 1 Then tb.Text = "sometext"
If Me.TrackBar1.Value = 0 Then tb.Text = "anothertext"
tb.Location = New Point(i, i * 2)
Me.Panel1.Controls.Add(tb)
Next
End Sub
However no matter in what state the trackbar is the text displayed in the labels is alaways "anothertext". The Paint event is triggered as far as I can tell when I change the value of the trackbar but how can I also force the labels to update?
Just add the labels once. Separate the creating and changing logic into two methods
Private prefix As String = "tb"
Private factor As Integer = 10
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
addLabels()
changeLabels()
End Sub
Private Sub addLabels()
For i = 0 To 10
Dim tb As New Label()
tb.Name = prefix & CStr(i)
tb.Location = New Point(factor * i, factor * i * 2)
Me.Panel1.Controls.Add(tb)
Next
End Sub
Private Sub changeLabels()
For i = 0 To 10
Dim tb As Label = CType(Panel1.Controls(prefix & CStr(i)), Label)
If Me.TrackBar1.Value = 1 Then tb.Text = "sometext"
If Me.TrackBar1.Value = 0 Then tb.Text = "anothertext"
Next
End Sub
Now, in TrackBar1_Scroll, you can just change them (instead of recreating them)
Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
changeLabels()
End Sub
Since the label value depends on the TrackBar value, there is no reason to update them in Paint, which happens more frequently than the TrackBar is updated.
Adding new Labels and removing old Labels in Paint seems like a lot of extra processing.
I believe you need to set the LargeChange property of the TrackBar as a Scroll Event is considered a large change, but LargeChange defaults to 0, thus when you scroll the Value is only increasing/decreasing by 0, Leaving it at 0

Get value of multiple created controls at runtime VB.NET

I can get the value of a single control that has been created at run time, that control is a DateTimePicker, but i can't get the values of multiple controls. how do i do it?
code:
This is where i add the DateTimePicker with every click at run time.
Private Sub btnAddTime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddTime.Click
Dim Time As New DateTimePicker()
Dim count As Integer = GroupBox1.Controls.OfType(Of DateTimePicker)().ToList().Count
Time.Location = New Point(9, (23 * count) + 22)
Time.Size = New Size(150, 20)
Time.Format = DateTimePickerFormat.Time
Time.ShowUpDown = True
Time.Name = "DateTimePicker" & (count + 1)
GroupBox1.Controls.Add(Time)
End Sub
And this is where i get the values of the controls.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim i As Integer = 0
For Each cntrl In Form3.GroupBox1.Controls
Dim dt As DateTimePicker = Form3.GroupBox1.Controls.Item("DateTimePicker" & (i + 1))
If DateTime.Now.ToString = dt.Value Then
MsgBox("P")
End If
Next
End Sub
I can only get the the value of a created control if only i specified it in the code, i think i can't get the right Name of the control. I'm trying to make the program to read every value of the control in another form while the Timer ticks. help?
Try this:
For Each cntrl In Form3.GroupBox1.Controls
If TypeOf cntrl Is DateTimePicker Then
If DateTime.Now.ToString = cntrl.Value Then
MsgBox("P")
End If
End If
Next

access to new dynamically controls in vb.net

First of all excuse me for my poor grammar and vocabulary :)
please see this source and run it:
Public Class Form1
Public pointX As Integer
Public pointY As Integer = 32
Public dynamicText As TextBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
pointX = 330
For i = 1 To 4
dynamicText = New Windows.Forms.TextBox
dynamicText.Name = "T" + Trim(Str(i))
dynamicText.Text = ""
dynamicText.Location = New Point(pointX, pointY)
dynamicText.Size = New Size(100, 20)
Me.Controls.Add(dynamicText)
pointX = pointX - 106
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pointX = 330
pointY = pointY + 26
For i = 1 To 4
dynamicText = New Windows.Forms.TextBox
dynamicText.Name = "T" + Trim(Str(i))
dynamicText.Text = ""
dynamicText.Location = New Point(pointX, pointY)
dynamicText.Size = New Size(100, 20)
Me.Controls.Add(dynamicText)
pointX = pointX - 106
AddHandler dynamicText.Click, AddressOf printHello1
Next
End Sub
Private Sub printHello1(ByVal sender As System.Object, ByVal e As System.EventArgs)
MsgBox(dynamicText.Name)
If dynamicText.Name = "T1" Then MsgBox("Oh! this is T1")
End Sub
End Class
why If never is not true?!
why MsgBox(dynamicText.Name) always return T4?!
i want all controlls to be access by name or array of names.
please help me thank you. :)
The global variable dynamicText takes the value of the last TextBox added in the loop inside the Button1_Click event. This happens to be the control named T4. You don't really need a global variable in this case. You can cast the sender parameter to a TextBox instance because the sender parameter is the control that has raised the event.
Private Sub printHello1(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim txt = CType(sender, "TextBox")
if txt IsNot Nothing then
MsgBox(txt.Name)
If txt.Name = "T1" Then MsgBox("Oh! this is T1")
End If
End Sub
You also don't need to recreate the controls again in the button click event. The action executed in the form load event is enough (You could add the AddHandler there). Global variables are dangerous, avoid them when possible.
See if this is acceptable. Place a panel at the bottom of your form, set Dock to Bottom, add a single button to the panel and a TextBox. Place a FlowLayoutPanel onto the form, Dock = Fill, AutoScroll = True.
The code below creates the amount of TextBox controls as inputted into TextBox. Each newly created TextBox a click event is added with simple logic.
Form code
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim count As Integer = 0
If Integer.TryParse(TextBox1.Text, count) Then
Dim demo = New TextBoxCreate(FlowLayoutPanel1, "Demos", count)
demo.CreateTextBoxes()
End If
End Sub
End Class
Class code (add a new class to the project, name it TextBoxCreate.vb)
Public Class TextBoxCreate
Public Property TextBoxes As TextBox()
Public Property TextBoxBaseName As String
Public Property TextBoxCount As Integer
Public Property ParentControl As Control
Public Sub New(
ByVal ParentControl As Control,
ByVal BaseName As String,
ByVal Count As Integer)
Me.ParentControl = ParentControl
Me.TextBoxBaseName = BaseName
Me.TextBoxCount = Count
End Sub
Public Sub CreateTextBoxes()
Dim Base As Integer = 10
TextBoxes = Enumerable.Range(0, TextBoxCount).Select(
Function(Indexer)
Dim b As New TextBox With
{
.Name = String.Concat(TextBoxBaseName, Indexer + 1),
.Text = (Indexer + 1).ToString,
.Width = 150,
.Location = New Point(25, Base),
.Parent = Me.ParentControl,
.Visible = True
}
AddHandler b.Click, Sub(sender As Object, e As EventArgs)
Dim tb As TextBox = CType(sender, TextBox)
If tb.Name = TextBoxBaseName & "1" Then
tb.Text = "Got it"
Else
MessageBox.Show(tb.Name)
End If
End Sub
Me.ParentControl.Controls.Add(b)
Base += 30
Return b
End Function).ToArray
End Sub
End Class

vb.net deleting lots of dynamically created buttons

I'm a new programmer to vb.net, so apologise for what is likely to be ignorance.
I’m building a simple gui for a database interface, with many parent and child items within it. Upon a form I create buttons depending on how many items (parents/children). I've got the creation of the buttons thus:
For RowNumber As Integer = 0 To NoOfRows
Dim Buttoni As New Button
Buttoni.Location = New Point(LocationX, LocationY)
Buttoni.Width = 100
Buttoni.Height = 40
Buttoni.Visible = True
Buttoni.Text = DatasetA.Tables(0).Rows(RowNumber).Item("Name")
ButtonName = "Button" + RowNumber.ToString
If LocationX < FormWidth - (SpacePerButtonX * 2) Then
LocationX = LocationX + SpacePerButtonX
Else
LocationX = 50
LocationY = LocationY + SpacePerButtonY
End If
AddHandler Buttoni.Click, AddressOf DynamicButtonClick
Me.Controls.Add(Buttoni)
Buttoni.BringToFront() 'brings newest buttons to front!
Next
But I’m struggling with a way to delete the buttons to make way for a new set to replace them... I can delete a single one upon its click, but I’d like to delete all of the buttons that have been created in this way before re-creating them.
I hope that makes sense and there is a fairly simple way to accomplish this..?
I will add, in your creation loop, some value to the Tag property.
This will help to differentiate the buttons created dinamically from the buttons created statically in your form.
Buttoni.Tag = 1
Then, to delete a button, loop in reverse order on the Me.Controls collection,
check if you get a button and if the Tag property IsNot Nothing
For x as Integer = Me.Controls.Count - 1 to 0 step -1)
Dim b as Button = TryCast(Me.Controls(x), Button)
If b IsNot Nothing AndAlso b.Tag IsNot Nothing then
b.Dispose() '' NOTE: disposing the button also removes it
End If
Next
It's hard to know exactly what you want to do. I guess you could just use the same technique in reverse, something like
For i As Integer = Me.Controls.Count - 1 To 0 Step -1
Dim ctrl = Me.Controls(i)
If TypeOf (ctrl) Is Button Then
ctrl.Dispose() '' NOTE: disposing the control also removes it
End If
Next
Create a button and delete it with double click!
Easy Code :
Dim b As New Button
Private btn As Button ' this is a reference object
Private ptX, ptY As Integer
Private drag As Boolean
Private Sub nodebtn_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Clicks = 2 Then
b.Dispose()
End If
If e.Button = MouseButtons.Left Then
drag = True
btn = CType(sender, Button)
ptX = e.X : ptY = e.Y
End If
End Sub
Private Sub nodebtn_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If drag Then
btn.Location = New Point(btn.Location.X + e.X - ptX, btn.Location.Y + e.Y - ptY)
Me.Refresh()
End If
End Sub
Private Sub nodebtn_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
drag = False
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
b.Location = New Point(10, 10)
b.Size = New Size(110, 29)
b.BringToFront()
b.Text = "Button"
AddHandler b.MouseDown, AddressOf nodebtn_MouseDown
AddHandler b.MouseMove, AddressOf nodebtn_MouseMove
AddHandler b.MouseUp, AddressOf nodebtn_MouseUp
Me.Controls.Add(b)
End Sub