Access a Label object from a Panel, all within a ToolStripMenuItem - vb.net

I am trying to move a Label object from a Panel object, in this case I have a parent panel that has Panel and Label objects as child, these are dynamically created. The objective is that when executing from the ToolStripMenuItem, when the Panel object is moved, the Label object is also moved.
I made the following code, but I think I could not move the Label object. From what I understand, what I am doing is generating the variable that is called the same as the Label that I need, but what I need is to refer to the existing object, not the new one. (this is correct?)
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
Dim clickedPanel = DirectCast(DirectCast(DirectCast(sender, ToolStripMenuItem).Owner, ContextMenuStrip).SourceControl, Panel)
clickedPanel.Location = New Point((clickedPanel.Location.X + 120), clickedPanel.Location.Y)
Dim posX = clickedPanel.Location.X + 120
Dim posY = clickedPanel.Location.Y
Dim namelabel As New Label With {
.Name = "Label" & clickedPanel.Name.Last
}
namelabel.Location = New Point((posX), posY)
End Sub
Could you please guide me?
Note: I Forgot something, in this case, If I move the Panel1, Label1 will move too, if I move Panel2, Label2 will move too, etc, etc.

This is the code, where the label is created inside the panel dynamically, and move together.
Private Sub NavButton15_ElementClick(sender As Object, e As NavElementEventArgs) Handles NavButton15.ElementClick
Dim pos As Int32 = 50
Dim poslabel As Int16 = 26
Dim posY As Int16 = 330
Dim posX As Int16 = 3
Dim counter as Int16 = 1
Panel1.AutoScrollPosition = New Point(0, 0)
Dim pb As New Panel With
{
.Width = 120,
.Height = 460,
.Top = 10,
.Left = 10,
.BorderStyle = BorderStyle.FixedSingle,
.BackgroundImage = Image.FromFile("C:\Example.bmp"),
.BackgroundImageLayout = ImageLayout.Stretch,
.ContextMenuStrip = CntxtMnuStrpSection,
.Name = "Panel" & counter
}
Dim labela As New Label With {
.AutoSize = True,
.Location = New Point((poslabel), 12),
.Text = "Panel " & counter,
.ForeColor = Color.White,
.BackColor = Color.Transparent,
.Font = New Font(Me.Font, FontStyle.Bold),
.Name = "Label" & counter
}
pb.Location = New Point(pos, 20)
Panel1.Controls.Add(pb)
pb.Controls.Add(labela)
End Sub
This is the ToolStripMenuItem where move the panel whit the label.
Private Sub ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem.Click
Dim clickedPanel = DirectCast(DirectCast(DirectCast(sender, ToolStripMenuItem).Owner, ContextMenuStrip).SourceControl, Panel)
clickedPanel.Location = New Point((clickedPanel.Location.X + 120), clickedPanel.Location.Y)
End Sub

Related

Create controls dinamically in a form got by a string value

In my current project I intend to do something like a file explorer. When I click with the right mouse button over the form it opens another form that simulates a MsgBox with 2 buttons, one to create a folder and another to create a text file. The program stores the name of the form that was open when clicked with the mouse and should create the desired option. The problem is that it does not create and does not give errors.
prevForm is a string which contains the previous form name.
Sorry for bad English
Private Sub pasta_Click(sender As Object, e As EventArgs) Handles pasta.Click
Dim nomePasta = InputBox("Nome da Pasta: ", "Nova Pasta", "Nova pasta")
Dim novoForm As New Form With {
.Name = nomePasta,
.Text = nomePasta,
.Size = New Point(816, 489),
.BackColor = Color.FromName("ActiveCaption")
}
Dim novaPicBox As PictureBox
novaPicBox = New PictureBox With {
.Size = New Point(60, 60),
.Location = New Point(720, 21)
}
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & prevForm).Controls.Add(novaPicBox)
Dim novaLbl As Label
novaLbl = New Label With {
.Text = nomePasta,
.Location = New Point(720, 85)
}
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & prevForm).Controls.Add(novaLbl)
Me.Close()
End Sub
Private Sub fichtexto_Click(sender As Object, e As EventArgs) Handles fichtexto.Click
Dim nomeFichTexto = InputBox("Nome do Ficheiro de Texto: ", "Novo Ficheiro de Texto", "Novo Ficheiro de Texto")
Dim novaPicBox As PictureBox
novaPicBox = New PictureBox With {
.Size = New Point(60, 60),
.Location = New Point(720, 111),
.Image = Image.FromFile(".\txt.png"),
.SizeMode = PictureBoxSizeMode.StretchImage
}
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & prevForm).Controls.Add(novaPicBox)
Dim novaLbl As Label
novaLbl = New Label With {
.Text = nomeFichTexto,
.Location = New Point(720, 174)
}
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & prevForm).Controls.Add(novaLbl)
Me.Close()
End Sub
You keep calling
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(ProductName & "." & prevForm)
which keeps creating instances. You don't want to create an instance since there is surely already one. You need to find it, or, better yet, just set it when the message is shown.
Add a property to your class which can be set before it's shown, which is the actual previous Form.
Public Class MsgForm
Public Property PreviousForm As Form
Private Sub pasta_Click(sender As Object, e As EventArgs) Handles pasta.Click
Dim nomePasta = InputBox("Nome da Pasta: ", "Nova Pasta", "Nova pasta")
Dim novoForm As New Form With {
.Name = nomePasta,
.Text = nomePasta,
.Size = New Point(816, 489),
.BackColor = Color.FromName("ActiveCaption")
}
Dim novaPicBox = New PictureBox With {
.Size = New Point(60, 60),
.Location = New Point(720, 21)
}
PreviousForm.Controls.Add(novaPicBox)
Dim novaLbl = New Label With {
.Text = nomePasta,
.Location = New Point(720, 85)
}
PreviousForm.Controls.Add(novaLbl)
Me.Close()
End Sub
Private Sub fichtexto_Click(sender As Object, e As EventArgs) Handles fichtexto.Click
Dim nomeFichTexto = InputBox("Nome do Ficheiro de Texto: ", "Novo Ficheiro de Texto", "Novo Ficheiro de Texto")
Dim novaPicBox = New PictureBox With {
.Size = New Point(60, 60),
.Location = New Point(720, 111),
.Image = Image.FromFile(".\txt.png"),
.SizeMode = PictureBoxSizeMode.StretchImage
}
PreviousForm.Controls.Add(novaPicBox)
Dim novaLbl = New Label With {
.Text = nomeFichTexto,
.Location = New Point(720, 174)
}
PreviousForm.Controls.Add(novaLbl)
Me.Close()
End Sub
End Class
And when you call the message box form, set the property
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim m = New MsgForm With {.PreviousForm = Me}
m.Show()
End Sub
End Class

How to get specific line and value in line seperate with coma from text file

I want get value 1 in all line for get path string, and programmatically add cover to flowlayoutpanel.
in Resource/Game List.ini (from drag n drop)
Apex Legends,Resource/Cover/Apex Legends.jpg,Resource/Game Info/Apex Legends.txt
Fortnite,Resource/Cover/Fortnite.jpg,Resource/Game Info/Fortnite.txt
PUBG,Resource/Cover/PUBG.jpg,Resource/Game Info/PUBG.txt
here my code :
Private Sub LabelSetting_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LabelSetting.Click
FlpAddItem.Controls.Clear()
'I am confused in this part to get value 1 in all line for get path string
'Directory.GetFiles(Path) will be replace with streamreader from lines(i) value 1
Dim Path = '???
Dim ImageX As Image = Nothing
Dim x As Int32 = Directory.GetFiles(Path).Count - 1
Dim Img(x) As PictureBox
Dim ImgText(x) As Label
Dim ImgPanel As Panel
For i = 0 To Directory.GetFiles(Path).Count - 1
ImgPanel = New Panel
With ImgPanel
.Width = 96
.Height = 136
.BackColor = Color.Transparent
End With
FlpAddItem.Controls.Add(ImgPanel) 'Add panel to the flowlayoutpanel
ImgText(i) = New Label
With ImgText(i)
.Name = Directory.GetFiles(Path)(i).Replace(Path, "").Replace(".jpg", "").Replace(".png", "")
.FlatStyle = FlatStyle.Popup
.Width = 116
.Height = 40
.Padding = New Padding(0, 3, 0, 0)
.TextAlign = ContentAlignment.TopCenter
.Dock = DockStyle.Bottom
.BackColor = Color.Transparent
.ForeColor = Color.Black
End With
Img(i) = New PictureBox
With Img(i)
.Width = 96
.Height = 96
.Padding = New Padding(20, 20, 20, 20)
.BackColor = Color.Transparent
.BorderStyle = BorderStyle.FixedSingle
.SizeMode = PictureBoxSizeMode.StretchImage
End With
ImgPanel.Controls.Add(Img(i)) 'Add the picturebox to the panel
ImageX = Image.FromFile(Directory.GetFiles(Path)(i), True)
Img(i).Image = Image.FromFile(Directory.GetFiles(Path)(i))
ImgText(i).Text = Directory.GetFiles(Path)(i)
ImgPanel.Controls.Add(ImgText(i))
Next
End Sub
I suggest creating a class for the game name and path information
Public Class GamePath
Public Property GameName As String
Property Path As String
Public Overrides Function ToString() As String
Return GameName
End Function
End Class
I have overridden ToString, so that the game name will automatically be displayed in a ListBox.
When loading the form, I read this information from the INI-file and set it as data source of a listbox, where you will be able to select a game.
Private Sub Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim games =
From line In File.ReadLines(IniFilePath)
Let parts = line.Split(","c)
Select New GamePath With {.GameName = parts(0), .Path = parts(1)}
GameListBox.DataSource = games.ToList()
GameListBox.SelectedIndex = 0 'Select first game
End Sub
Note that it is easier to use File.ReadLines than a StreamReader. You will have to add Imports System.IO to the top of the code. Then we use the LINQ syntax to split each line at the comma and to create the game path information.
The user selects a game in the ListBox and then clicks a button. You can get the file path information from the ListBox like this:
Dim gamePath As GamePath = DirectCast(GameListBox.SelectedItem, GamePath)
Then read the files only once and assign the result to a variable
Dim files As String() = Directory.GetFiles(gamePath.Path)
Get the file count
Dim fileCount As Integer = files.Count
The whole Click method:
Private Sub StartGameButton_Click(sender As Object, e As EventArgs) Handles StartGameButton.Click
FlpAddItem.Controls.Clear()
Dim gamePath As GamePath = DirectCast(GameListBox.SelectedItem, GamePath)
Dim files As String() = Directory.GetFiles(gamePath.Path)
Dim fileCount As Integer = files.Count
Dim ImageX As Image = Nothing
Dim Img(fileCount) As PictureBox
Dim ImgText(fileCount) As Label
Dim ImgPanel As Panel
For i = 0 To fileCount - 1
Dim filePath = files(i)
ImgPanel = New Panel
With ImgPanel
.Width = 96
.Height = 136
.BackColor = Color.Transparent
End With
FlpAddItem.Controls.Add(ImgPanel) 'Add panel to the flowlayoutpanel
ImgText(i) = New Label
With ImgText(i)
.Name = System.IO.Path.GetFileNameWithoutExtension(filePath)
.FlatStyle = FlatStyle.Popup
.Width = 116
.Height = 40
.Padding = New Padding(0, 3, 0, 0)
.TextAlign = ContentAlignment.TopCenter
.Dock = DockStyle.Bottom
.BackColor = Color.Transparent
.ForeColor = Color.Black
End With
Img(i) = New PictureBox
With Img(i)
.Width = 96
.Height = 96
.Padding = New Padding(20, 20, 20, 20)
.BackColor = Color.Transparent
.BorderStyle = BorderStyle.FixedSingle
.SizeMode = PictureBoxSizeMode.StretchImage
End With
ImgPanel.Controls.Add(Img(i)) 'Add the picturebox to the panel
ImageX = Image.FromFile(filePath, True)
Img(i).Image = Image.FromFile(filePath)
ImgText(i).Text = filePath
ImgPanel.Controls.Add(ImgText(i))
Next
End Sub
Some details:
In the For-loop you can get the path of an image file with
Dim filePath = files(i)
You can get the name of the image with
.Name = System.IO.Path.GetFileNameWithoutExtension(filePath)
This automatically removes the directory name and the extension.
Later on, you don't call Directory.GetFiles again:
ImageX = Image.FromFile(filePath, True)
Img(i).Image = Image.FromFile(filePath)
ImgText(i).Text = filePath
If you only want to read the file paths into a list, you could write
Dim games =
(From line In File.ReadLines(IniFilePath)
Select line.Split(","c)(1)).ToList()

Color at mouse location is incorrect

Public Class Form1
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer) As Integer
Dim BMP As New Bitmap(1, 1)
Dim G As Graphics = Graphics.FromImage(BMP)
Dim XCoorLabel As New Label
Dim YCoorLabel As New Label
Dim ColorLabel As New Label
Dim ColorExam As New Panel
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Preparing the Form
Me.Width = 500
Me.Height = 150
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
'Setting up all the labels and 1 panel
With XCoorLabel
.Location = New Point(12, 9)
.Name = "xCoorlabel"
.Size = New Drawing.Size(50, 25)
.Visible = True
.ForeColor = Color.DarkGray
End With
With YCoorLabel
.Location = New Point(69, 9)
.Name = "YCoorLabel"
.Size = New Drawing.Size(50, 25)
.Visible = True
.ForeColor = Color.DarkGray
End With
With ColorLabel
.Location = New Point(12, 36)
.Name = "ColorLabel"
.Size = New Drawing.Size(200, 25)
.Visible = True
.ForeColor = Color.DarkGray
End With
With ColorExam
.Location = New Point(12, 66)
.Name = "ColorLabel"
.Size = New Drawing.Size(20, 10)
.Visible = True
End With
'Adding everything to the form
Me.Controls.Add(XCoorLabel)
Me.Controls.Add(YCoorLabel)
Me.Controls.Add(ColorLabel)
Me.Controls.Add(ColorExam)
'Starting the timer
Timer1.Enabled = True
End Sub
Private Sub keyPressed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
'Stopping the timer when 'W' is pressed
If e.KeyValue = Keys.W Then
Timer1.Enabled = False
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'Getting the cursor position and place it in the text label
Dim mousepos As Point = Cursor.Position
XCoorLabel.Text = "X" & mousepos.X
YCoorLabel.Text = "Y" & mousepos.Y
'Getting the screenimage and checking what color is on the location
G.CopyFromScreen(mousepos, Point.Empty, BMP.Size)
'placing the RGB color values in text in the label
ColorLabel.Text = BMP.GetPixel(0, 0).ToString
'Change the panels color according to the color that was found on the position
Dim Icolor As Integer = GetPixel(GetDC(0), mousepos.X, mousepos.Y)
ColorExam.BackColor = System.Drawing.ColorTranslator.FromOle(Icolor)
End Sub
End Class
THE CODE CAN BE PASTED INTO VISUAL STUDIO 2013, AND WILL FUNCTION IMMEDIATLY (No need to add any labels or stuff yourself to see it function, altering the code is allowed obviously)
Above here is my code. I wanted to try some stuff with finding the current mouse location, and which color is at that location (Not just from the background, from the screen itself).
The thing is, that this code actually works (might not be the best code, but it does function).
Sadly I have the problem that when I hover the mouse over a certain place, the color it shows does not match, when I checked this, I noticed that it is off.
In X it seems to be about 400-500 pixels off
In Y it seems to be about 90 pixels off
Does anybody have any idea where this comes from, and how I could fix this?

How to change image in picture box when clicked

I have used the following code in a program that I am designing to book seats. Each picturebox is a seat, and when each picturebox is clicked, the image should change from Seating_No_Person to Seating_With_Person to show that the seat has been selected. I am currently getting a problem with the changing image, as when clicked, none of the pictureboxes swap images. Anyone got any suggestions?
Thanks
Public Class Form1
Public Class Seating
Public SeatRow As Integer = 0
Public SeatColumn As Integer = 0
Public PB As PictureBox = Nothing
Public Occupied As Boolean = False
End Class
Private seatingList As New List(Of Seating)
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim xPosition As Integer = -50
Dim yPosition As Integer = -25
For i As Integer = 1 To 5
'Number of rows
For j As Integer = 1 To 10
Dim pb As New PictureBox
With pb
.Name = "PictureBox" & i.ToString & j.ToString
'Name of Picture box i.e. if i = 1 (row 1), j = 3 (column 3), name is PictureBox13
.SizeMode = PictureBoxSizeMode.Zoom
.Size = New Size(60, 60)
'Size of seat is 60 by 60
.Location = New Point(xPosition + (j * 70), yPosition + (i * 70))
'Location of picture box is: -50 + (columnnumber * 70), -25 + (rownumber * 70)
.Image = My.Resources.Seating_No_Person
Me.Controls.Add(pb)
AddHandler pb.Click, AddressOf PictureBox_Click
Dim thisSeating As New Seating
With thisSeating
.SeatRow = i
.SeatColumn = j
.PB = pb
.Occupied = True
End With
seatingList.Add(thisSeating)
End With
Next
Next
End Sub
Private Sub PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim pb As PictureBox = DirectCast(sender, PictureBox)
Dim seatRowNum As Integer = CInt(pb.Name.Replace("PictureBox", ""))
Dim seatColumnNum As Integer = CInt(pb.Name.Replace("PictureBox", ""))
Dim qry = From seat As Seating In seatingList Where seat.SeatRow = seatRowNum And seat.SeatColumn = SeatColumnNum
If qry.Count = 1 Then
If qry.First.Occupied = True Then
pb.Image = My.Resources.Seating_No_Person
qry.First.Occupied = False
Else
pb.Image = My.Resources.Seating_With_Person
qry.First.Occupied = True
End If
End If
End Sub
End Class
I would suggest setting a breakpoint and debugging to see where you're going wrong. If you just call DirectCast(sender, PictureBox).Image = My.Resources.Seating_With_Person inside Private Sub PictureBox_Click it works, which suggests that there is problem with the logic inside your If block.

VB Tab control in draw.mode

I am trying to make the tabs show horizontally on the right side of my form. I can't use tabcontrol from tool box because of how the text displays.
I am using a code that I found to help me. But after exhausting all of my resources I can't seem to get the code to point to the tabPages collection. I have entries in there but the tabs show up blank.
Public Sub New()
tabControl1 = New TabControl()
Dim tabPage1 As New TabPage()
' Sets the tabs to be drawn by the parent window Form1.
' OwnerDrawFixed allows access to DrawItem.
tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed
tabControl1.Controls.Add(tabPage1)
tabControl1.Location = New Point(25, 25)
tabControl1.Size = New Size(250, 250)
tabPage1.TabIndex = 0
myTabRect = tabControl1.GetTabRect(0)
ClientSize = New Size(300, 300)
Controls.Add(tabControl1)
AddHandler tabControl1.DrawItem, AddressOf OnDrawItem
End Sub!
tab Example
You can set the .Alignment property of the TabControl to Left to use horizontal tabs.
If you don't like that, try a FlowLayoutPanel with a separate TabControl for each tab, e.g.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Dim flp As New FlowLayoutPanel
flp.Dock = DockStyle.Left
flp.AutoSize = True
flp.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowOnly
Me.Controls.Add(flp)
For i As Integer = 0 To 5
Dim tbc As New TabControl
Dim tbp As New TabPage("Tab" & i.ToString)
tbc.TabPages.Add(tbp)
flp.Controls.Add(tbc)
Next i
End Sub
End Class
I ended up compiling this code from different sources to get this working,
Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
Dim g As Graphics
Dim sText As String
Dim iX As Integer
Dim iY As Integer
Dim sizeText As SizeF
Dim ctlTab As TabControl
Dim r As New RectangleF(e.Bounds.X, e.Bounds.Y + 2, e.Bounds.Width, e.Bounds.Height - 2)
ctlTab = CType(sender, TabControl)
g = e.Graphics
sText = ctlTab.TabPages(e.Index).Text
sizeText = g.MeasureString(sText, ctlTab.Font)
iX = e.Bounds.Left + 6
iY = e.Bounds.Top + (e.Bounds.Height - sizeText.Height) / 2
g.DrawString(sText, ctlTab.Font, Brushes.Black, iX, iY)
End Sub
The text doesn't show up in the RAD but it does when I debug/run it.
Many thanks to LUC001 # http://www.dreamincode.net/forums/topic/125792-how-to-make-vertical-tabs/