Create controls dinamically in a form got by a string value - vb.net

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

Related

How to display image in pictureedit and picturebox when clicked in gridview devexpress in vb.net

I want to display images in picturedit and picturebox when I click on gridview devexpress.
I want to display the image when the cell value clicked in the path1 column and path2 column in one pictureedit and one picturebox.
Public Class Form1
Private WithEvents dt As New DataTable
Dim Path As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\PRODUCT.mdb"
Dim cn = "provider=Microsoft.Jet.OLEDB.4.0; data source=" & Path
Private Images As Hashtable = New Hashtable()
Private Sub LoadDataGridView()
Try
dt = New DataTable
Dim query = "select Code,Path1,Path2 FROM ITEM"
Using adapter As New OleDbDataAdapter(query, cn.ToString)
adapter.Fill(dt)
End Using
Me.GridControl1.DataSource = dt
Catch myerror As OleDbException
MessageBox.Show("Error: " & myerror.Message)
Finally
End Try
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadDataGridView()
End Sub
Private Sub GridView1_RowCellClick(sender As Object, e As RowCellClickEventArgs) Handles GridView1.RowCellClick
Dim view As GridView = TryCast(sender, GridView)
Dim path1 As String = view.GetFocusedRowCellValue("Path1").ToString
Dim path2 As String = view.GetFocusedRowCellValue("Path2").ToString
PictureEdit1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(path1)), True, False)
PictureEdit1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(path2)), True, False)
End Sub
End Class
Capturegridview18022022
Captureerror18022022
Visit https://docs.devexpress.com/WindowsForms/DevExpress.XtraGrid.Views.Grid.GridView.RowCellClick
Private Sub GridView1_RowCellClick(sender As Object, e As RowCellClickEventArgs) Handles GridView1.RowCellClick
Dim view As GridView = TryCast(sender, GridView)
If e.Column.FieldName = "Path1" Then
Dim path1 As String = view.GetRowCellValue(e.RowHandle, e.Column).ToString
PictureEdit1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(path1)), True, False)
Else
If e.Column.FieldName = "Path2" Then
Dim path2 As String = view.GetRowCellValue(e.RowHandle, e.Column).ToString
PictureEdit1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(path2)), True, False)
End If
End If
End Sub
Use Click event instead of RowCellClick
Private Sub GridView1_Click(sender As Object, e As RowCellClickEventArgs) Handles GridView1.Click
Dim path1 As String = (GridView1.GetRowCellValue(GridView1.FocusedRowHandle,"Path1"))
Dim path2 As String = (GridView1.GetRowCellValue(GridView1.FocusedRowHandle,"Path2"))
PictureEdit1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(path1)), True, False)
PictureEdit1.Image = Image.FromStream(New MemoryStream(File.ReadAllBytes(path2)), True, False)
End Sub

Access a Label object from a Panel, all within a ToolStripMenuItem

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

Insert data from auto generated textbox to SQL Server database

I have created a code for generating a text box in vb.net using button click and function
Public Function AddNewTextBox() As System.Windows.Forms.TextBox
Dim txt As New System.Windows.Forms.TextBox()
Me.Controls.Add(txt)
txt.Top = cLeft * 30
txt.Left = 100
'txt.Text = "TextBox " & Me.cLeft.ToString
cLeft = cLeft + 1
txt.ForeColor = Color.DarkGreen
txt.BackColor = Color.Gray
txt.Font = New Font("Arial", 14.0, FontStyle.Regular)
txt.Size = New Size(237, 31)
txt.Location = New Point(156, 130 + top1)
Return txt
End Function
In the button
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'call the function
AddNewTextBox()
End Sub
I have tried this
cmd.CommandText = "INSERT INTO userlog ([username],[userlastname]) Values ( #username) "
cmd.Parameters.AddWithValue("#username", txt.Text(i).Text)
cmd.Parameters.AddWithValue("#userlastname", txt.Text(i).Text)
but getting an error in
txt.Text(i)
since txt is declared only in AddNewTextBox function.
I have made 3 auto generated text boxs
How do I save this data inside the text box to the database?
Add a FlowlayoutPanel to your form and set the FlowDirection to TopDown. (as commented by #jmcilhinney) This saves calculating the position of the text boxes.
It doesn't make sense to have a function returning a text box when you never use the return value.
The data access code uses the .Add method suggested by #SMor. See
http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
I had to guess at the datatypes. Check your database for correct types.
The values come from the controls collection of the FlowLayoutPanel where the controls were added.
Using blocks ensure that you database objects are closed and disposed even if there is an error. Pass the connection string directly to the constructor of the connection and the command text and connection directly to the constructor of the command.
Public Sub AddNewTextBox()
Dim txt As New System.Windows.Forms.TextBox()
txt.Name = "user" & nameTextBox.ToString
txt.ForeColor = Color.DarkGreen
txt.BackColor = Color.Gray
txt.Font = New Font("Arial", 14.0, FontStyle.Regular)
txt.Size = New Size(120, 30)
FlowLayoutPanel1.Controls.Add(txt)
End Sub
Private Sub UpdateUsers()
Using cn As New SqlConnection("Your connection string")
Using cmd As New SqlCommand("INSERT INTO userlog ([username],[userlastname]) Values ( #username, #userlastname);", cn)
cmd.Parameters.Add("#username", SqlDbType.VarChar).Value = FlowLayoutPanel1.Controls(0).Text
cmd.Parameters.AddWithValue("#userlastname", SqlDbType.VarChar).Value = FlowLayoutPanel1.Controls(1).Text
cn.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AddNewTextBox()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
UpdateUsers()
End Sub
EDIT
For Each tb As TextBox In FlowLayoutPanel1.Controls
If tb.Text = "" Then
MessageBox.Show("Please fill all text boxes before Updating")
Return
End If
Next
Since the TextBox is being added to the control collection of the Form, you can use the OfType enumerable method to get all TextBox controls. What's more I would probably assign the Tag of the generated TextBox to the desired field name so that you can query the control collection for the first instance of the TextBox who's tag equals the desired field.
Also its worth mentioning that you can use the With keyword to get rid of some unnecessary code.
With all that being said, your AddNewTextBox method would look like this:
Public Function AddNewTextBox(ByVal fieldName As String) As System.Windows.Forms.TextBox
Dim txt As New System.Windows.Forms.TextBox()
Me.Controls.Add(txt)
With
.Top = cLeft * 30
.Left = 100
'.Text = "TextBox " & Me.cLeft.ToString
cLeft = cLeft + 1
.ForeColor = Color.DarkGreen
.BackColor = Color.Gray
.Font = New Font("Arial", 14.0, FontStyle.Regular)
.Size = New Size(237, 31)
.Location = New Point(156, 130 + top1)
.Tag = fieldName
End With
Return txt
End Function
Your Button's click event would look like this:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'call the function
Dim txt As TextBox = AddNewTextBox("username")
End Sub
And your parameterized query would look like this:
Dim usernameTextBox As TextBox = Me.Controls.OfType(Of TextBox).FirstOrDefault(Function(txt) txt.Tag IsNot Nothing AndAlso txt.Tag = "username")
If usernameTextBox IsNot Nothing Then
cmd.Parameters.AddWithValue("#username", usernameTextBox.Text)
End If

How to update a Chart

I've just finished developing a piece of code where I am able to create a Chart and query from my database. Here I insert values from the database and it will show to the user.
I will post here the code that I've done to create a chart:
Public Sub BuildChart()
Try
SQLCon = New SqlConnection
SQLCon.ConnectionString = "........."
Dim sqlStatis As String = "SELECT Top 5 Filename, Filesize FROM infofile"
Dim Chart1 As New Chart()
Dim da As New SqlDataAdapter(sqlStatis, SQLCon)
Dim ds As New DataSet()
da.Fill(ds, "infofile")
Dim ChartArea1 As ChartArea = New ChartArea()
Dim Legend1 As Legend = New Legend()
Dim Series1 As Series = New Series()
Me.Controls.Add(Chart1)
ChartArea1.Name = "ChartArea1"
Chart1.ChartAreas.Add(ChartArea1)
Legend1.Name = "Legend1"
Chart1.Legends.Add(Legend1)
Chart1.Location = New System.Drawing.Point(12, 12)
Chart1.Name = "Chart1"
Series1.ChartArea = "ChartArea1"
Series1.Legend = "Legend1"
Series1.Name = "Tamanho do ficheiro"
Chart1.Series.Add(Series1)
Chart1.Size = New System.Drawing.Size(600, 300)
Chart1.TabIndex = 0
Chart1.Text = "Chart1"
Chart1.Series("Tamanho do ficheiro").XValueMember = "Filename"
Chart1.Series("Tamanho do ficheiro").YValueMembers = "Filesize"
Chart1.DataSource = ds.Tables("infofile")
Catch ex As Exception
MessageBox.Show(ex.ToString())
Finally
SQLCon.Dispose()
End Try
End Sub
As you can see I've created a method which will be called in the form and the info will be shown there. Outside of everything I declared a variable Dim Chart1 As New Chart(). Now I want to create a method which allows me with a timer to update automatically the chart. So I should create another method called UpdateChart where I could insert there this:
Timer1.Interval = 3000
Timer1.Start()
But now I have no idea what should I use to update it every 3 secs or 3000 milliseconds.
On Load you want to call the BuildChart method and start the timer:
Private Sub frmTest_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
BuildChart()
With Timer1
.Enabled = True
.Interval = 3000
.Start()
End With
End Sub
For BuildChart you only need to create the chart itself and not bind the data.
Public Sub BuildChart()
Try
Dim Chart1 As New Chart()
Dim ChartArea1 As ChartArea = New ChartArea()
Dim Legend1 As Legend = New Legend()
Dim Series1 As Series = New Series()
Me.Controls.Add(Chart1)
ChartArea1.Name = "ChartArea1"
Chart1.ChartAreas.Add(ChartArea1)
Legend1.Name = "Legend1"
Chart1.Legends.Add(Legend1)
Chart1.Location = New System.Drawing.Point(12, 12)
Chart1.Name = "Chart1"
Series1.ChartArea = "ChartArea1"
Series1.Legend = "Legend1"
Series1.Name = "Tamanho do ficheiro"
Chart1.Series.Add(Series1)
Chart1.Size = New System.Drawing.Size(600, 300)
Chart1.TabIndex = 0
Chart1.Text = "Chart1"
Chart1.Series("Tamanho do ficheiro").XValueMember = "Filename"
Chart1.Series("Tamanho do ficheiro").YValueMembers = "Filesize"
Catch ex As Exception
MessageBox.Show(ex.ToString())
Finally
SQLCon.Dispose()
End Try
End Sub
We then want UpdateChart to be called from the Timer.Tick event.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
UpdateChart()
End Sub
Private Sub UpdateChart()
Chart1.Series(0).Points.Clear()
Chart1.DataSource = ""
SQLCon = New SqlConnection
SQLCon.ConnectionString = "............."
Dim sqlStatis As String = "SELECT Top 5 Filename, Filesize FROM infofile"
Dim da As New SqlDataAdapter(sqlStatis, SQLCon)
Dim ds As New DataSet()
da.Fill(ds, "infofile")
Chart1.DataSource = ds.Tables("infofile")
End Sub
Be aware though that this will create a lot of hits to your database.

Design-time Coding

I'm a newbie in visual basic dot net. I tried to create a design in run-time. Here's my simple code.
Dim frmLogin As New Form
Dim lblUserName, lblPassword As New Label
Dim txtUserName, txtPassword As New TextBox
Dim btnContinue, btnCancel As New Button
'set frmLogin properties
frmLogin.StartPosition = FormStartPosition.CenterScreen
frmLogin.FormBorderStyle = Windows.Forms.FormBorderStyle.None
frmLogin.BackColor = Color.LightGray
frmLogin.Size = New Size(400, 200)
'set lblUserName properties
lblUserName.Text = "User Name: "
lblUserName.Font = New Font("Calibri", 12, FontStyle.Regular)
lblUserName.Location = New Point(20, 30)
'set lblPassword properties
lblPassword.Text = "Password: "
lblPassword.Font = New Font("Calibri", 12, FontStyle.Regular)
lblPassword.Location = New Point(20, 70)
'set txtUserName properties
txtUserName.Font = New Font("Calibri", 12, FontStyle.Regular)
txtUserName.Location = New Point(120, 20)
txtUserName.Size = New Size(250, 20)
txtPassword.Font = New Font("Calibri", 12, FontStyle.Regular)
txtPassword.Location = New Point(120, 60)
txtPassword.Size = New Size(250, 20)
txtPassword.PasswordChar = "*"
btnCancel.Text = "Cancel"
btnCancel.Location = New Point(270, 120)
btnCancel.Size = New Size(100, 28)
btnCancel.BackColor = Color.White
btnCancel.Font = New Font("Calibri", 12, FontStyle.Regular)
frmLogin.Controls.Add(lblPassword)
frmLogin.Controls.Add(lblUserName)
frmLogin.Controls.Add(txtUserName)
frmLogin.Controls.Add(txtPassword)
frmLogin.Controls.Add(btnCancel)
frmLogin.ShowDialog()
How could I start creating a code here? I'd like to start in btnCancel, how could I insert this code in btnCancel
dim myAns as string = msgbox("This will exit the program. Are you sure?")
if ans = vbyes then application.exit
you have to add an event handler to the controls:
'register the event handler after initializing of the control
AddHandler btnCancel.Click, AddressOf CancelClick
'create a method with same signature as the delegate of the event
Private Sub CancelClick(ByVal sender As Object, ByVal e As EventArgs)
'do your stuff here
End Sub