parse value from datagrid to button name - vb.net

I'm building a form that has many buttons, all buttons do the same thing: add 1 every time they are clicked. Every pressed button is sent to a datagridview along with the time they are pressed. Datagrid values look like this:
a_1_serv (button name), 18:05:00(time).
Sometimes I want to delete the last row. Everything works fine so far.
When I delete the last row, I want to change the text of the button (a_1_serv).
I can parse the dgv value (a_1_serv) to a variable but I can't bind it to the appropriate button name so I can control it.
Is there a way to do it?

Don't store your program state in your UI
Create a data structure to hold the information, and let the DataGridView be a "view", not treating it as a variable. You will save yourself headaches vs using the UI as a variable.
That said, create a class to represent your information
Public Class Data
Public Sub New(button As Button, time As DateTime)
Me.Button = button
Me.Time = time
End Sub
<System.ComponentModel.Browsable(False)>
Public Property Button As Button
Public ReadOnly Property Text As String
Get
Return Button.Name
End Get
End Property
Public Property Time As DateTime
End Class
And your code can manipulate the data in a variable off the UI. Bind the data to the DataGridView for display.
Private datas As New List(Of Data)()
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click
addButton(DirectCast(sender, Button))
End Sub
Private Sub RemoveLastButton_Click(sender As Object, e As EventArgs) Handles RemoveLastButton.Click
removeLast()
End Sub
Private Sub addButton(b As Button)
datas.Add(New Data(b, DateTime.Now))
bindData()
End Sub
Private Sub removeLast()
Dim b = datas.Last.Button
b.Text = "new text" ' change to whatever
datas.RemoveAt(datas.Count - 1)
bindData()
End Sub
Private Sub bindData()
DataGridView1.DataSource = Nothing
DataGridView1.DataSource = datas
End Sub
This does exactly what you stated but there may be inconsistency in these two bits of information you provided: a_1_serv (button name) and I want to change the text of the button .... This changes the button text but not the name. The name is displayed in the grid. You can change the data class to display the text or whatever. But the point is this approach will keep your data off the UI and you won't need to look up the control by name anymore.

Related

How to save the last Position/Value of a trackbar when closing a form?

I have a Form1 that sends a line of text to another open application using AppActivate.
This line of text is created from dropdowns and textboxes, and is sent to the other app using sendkeys and System.Threading.Thread.Sleep(label1.text).
I have a trackbar on a second form hooked to label1 to control the time amount for sleep value. I have the trackbar value set at 100 so that the user has a default value. When the timer is not long enough, the user can go to the second form and increase the slider value.
My problem is that because I have the trackbar value set at 100 everytime the second form opens it resets to the default 100 setting. How can I have a default 100 setting on the trackbar, but once the value is changed it will be there next time the second form is opened?
Also I want it to go back to 100 when the application is close completely (form 1 closed).
I don't understand exactly what controls each form has or what it's job is, but it sounds like you can just pass the current trackbar value from one form to another via the constructor:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Set the default value
TrackBar.Value = 100
End Sub
Private Sub Button1_Clicked(sender As Object, e As EventArgs) Handles Button1.Click
'Pass the current value of trackbar into Form2 constructor
Dim form2 As New Form2(TrackBar.Value)
form2.Show()
End Sub
End Class
Public Class Form2
'You can this wherever you need it now
Dim _TrackBarValue As Integer
Public Sub New(ByVal TrackBarValue As Integer)
_TrackBarValue = TrackBarValue
End Sub
End Class
Obviously, you need to use the right forms for how your controls are layed out.

passing data from textbox in form1 to textbox in opened form2 in visual basic

i have form1 to enter movies details
in this form1 i have a textbox called NVideosGenres
through this textbox i can open the form2 with a space
the form2 contains 5 combobox to let the users choose the genres if there is more then one
when user choose the genres they will be applied to a textbox in the same form like this way
for example i choose from three combobox
action - war - western
so now i have a problem because i know that to pass value i should do this
Videos.NVideosGenres.text = me.FinalGenres.text
me.close()
when i click on the button the form2 will close but the data don't pass to NVideosGenres in the form1
any help??
There are many, many ways to do this. One of the easiest ways would be to create a property on Form2 that holds a reference to your main calling form. Then you can set the values of the textboxes (or whatever) directly from Form2. This is definitely not the best way to do it, but it certainly is quick and easy.
Private Sub btnShowForm2_Click(sender As System.Object, e As System.EventArgs) Handles btnShowForm2.Click
'Create a new instance of Form2 (called frmDetail in this example).
Dim frm2 As New frmDetail()
'Set the MyParentForm property of Form2 to this form.
frm2.MyParentForm = Me
'Show the form.
frm2.ShowDialog()
End Sub
Now in Form2, when you click the "OK" button to close the form, you can use the property that references your parent form to set the values directly.
' Property to hold a reference to the calling form.
Private mParentForm As frmMain
Public Property MyParentForm() As frmMain
Get
Return mParentForm
End Get
Set(ByVal value As frmMain)
mParentForm = value
End Set
End Property
' When I click the OK button, I will store the value of my various textboxes to properties.
Private Sub btnOK_Click(sender As System.Object, e As System.EventArgs) Handles btnOK.Click
'Set the value of the Genre textbox on the parent form to the value
'of the textbox on my current form.
MyParentForm.txtGenre.Text = txtGenre.Text
Me.Hide()
End Sub

How do I use the Tag property with forms and code in VB 2012?

I am writing a program using a database for customers and technicians. The main form (CustomerIncidents) has a toolstripbutton that opens a different form to (SearchByState) where the user inputs a state code and looks for any incidents.
If the user clicks into one of the datagrid cells I want that customers information to be stored in the TAG so that when the form is closed using the OK button that it will show back up in the main form (CustomerIncidents).
Edited 03/11/14 12:21pm
The problem is in the Main Form. When I click the OK button in the Second Form it tries to convert the DialogResult Button to a String. I can't figure out how to fix it.
Customer Form (Main Form) Opens to Secondary Form
Private Sub btnOpenState_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnOpenState.Click
Dim frmSearchState As New FindCustomer
----->>Dim selectedButton As DialogResult = frmSearchState.ShowDialog()
If selectedButton = Windows.Forms.DialogResult.OK Then
CustomerIDToolStripTextBox.Text = frmSearchState.Tag.ToString
End If'
Search By State Form (Secondary Form) Or "Child Form"
Private Sub btnOk_Click(message As String, ByVal e As DataGridViewCellEventArgs) Handles btnOk.Click
message = CustomersDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value.ToString
Me.Tag = message
Me.DialogResult = DialogResult.OK
End Sub
The click event for a button does not have a DataGridViewCellEventArgs parameter, and will throw an exception when you try to use it.
You don't need to use the Tag property since you can just create your own property.
In your child form, create a property called GridValue:
Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
If dgv.CurrentCell Is Nothing OrElse dgv.CurrentCell.Value Is Nothing Then
MessageBox.Show("A cell needs to be selected.")
Else
Me.DialogResult = DialogResult.OK
End If
End Sub
Public ReadOnly Property GridValue As String
Get
Return dgv.CurrentCell.Value.ToString
End Get
End Property
In your parent form, you can now access your information:
Using frmSearchState As New FindCustomer
If frmSearchState.ShowDialog(Me) = DialogResult.Ok Then
CustomerIDToolStripTextBox.Text = frmSearchState.GridValue
End If
End Using
My personal approach for doing this kind of stuff is to create a public property in the child form, having the same type as the DATA you want to take back to your main form. So instead of storing DataGridView's reference in Tag property, you should really be storing the actual value that was there in the cell that the user clicked on.
For example, if your DGV cell has a string value in it, you could do something like:
Public Readonly Property StateName As String
Get
If YourDGV.SelectedCell IsNot Nothing Then
Return YourDGV.SelectedCell.Value
Else
Return ""
End If
End Get
End Property
(I have written that code by hand, so there may be some syntax problems, but you should be able to get the idea.)
You can now use ShowDialog() in the main form to bring up this child form and upon OK or Cancel, you could check the value of StateName property of your child form to get this value. The thing to remember here is that closing a form doesn't dispose off all its constituent controls and properties and therefore you can access them even after the form has finished ShowDialog() call.

Edit Update DatagridView VB.Net (No Database)

Good day everyone.
I need your help in this project I am into (a Visual Basic program with no database.) It just contains a Datagridview, a Textbox, and three buttons (an "Add" Button, a "Edit" and an "Update" Button).
1 . Is there any way (like using "for loop") to automatically assign DataGridView1.Item("item location") to the one edited and be updated?
2 . Or is it possible to just click an item in the Datagridview then it will be edited at that without passing it to a Textbox, and to be updated at that.
The DataGridViewCellEventArgs variable (e in the method stub the designer will generate for you) of the double click event of the cell has RowIndex and ColumnIndex properties which refer to the position of the cell you clicked.
Save those (in a class variable possibly or a local one if that's all you need) and then refer to them when you update the cell in your DataGridView, possibly like this MyDataGridView.Item(e.ColumnIndex, e.RowIndex) or MyDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) where e is the variable from the double click event handler.
For you cell double click event you could have something like this:
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
Using myEditor As New frmCellEditor(Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value)
If myEditor.ShowDialog() = DialogResult.OK Then
Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = myEditor.NewCellValue
End If
End Using
End Sub
This will call a new instance of your editor and get a value from you. For the purpose of this demo I have made a form like this:
Public Class frmCellEditor
Public NewCellValue As Integer
Public Sub New(ByVal CurrentCellValue As Object)
InitializeComponent()
Me.TextBox1.Text = CStr(CurrentCellValue)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.NewCellValue = CInt(Me.TextBox1.Text)
Me.DialogResult = DialogResult.OK
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Call Me.Close()
End Sub
End Class
Which just has two buttons (Button1 = OK, Button2 = Cancel). When you click OK, it just returns the value 1 which then gets set as the value of the cell.
This is a VERY simplistic example, but it should provide you the basics of what you are trying to do.
UPDATE:
I updated the code for the editor interface so it will include handling for passing the value back and forth from the form with your datagridview.
In your project, make a new form called frmCellEditor. This forms has to have two buttons and a textbox (Make sure that the programmatic names match!). Replace the code with the code listed above. You will have to add Imports System.Windows.Forms above the class as well.
Amend the event handler for the cell double click event of your datagrid to pass the cell value when frmCellEditor is constructed (the line going ... New frmCellEditor(...).
How many columns does your DataGridView has?
Based on how you populate your DataGridView, I'll assume only 1.
Declare this on top of your form
Dim i as Integer
On your btnUpdate_Click Event (Just combine your Edit and Update button into One)
SELECT CASE btnUpdate.Text
Case "Update"
With DataGridView1
'Check if there is a selected row
If .SelectedRows.Count = 0 Then
Msgbox "No Row Selected for Update"
Exit Sub
End If
i = .CurrentRow.Index 'Remember the Row Position
Textbox1.Text = .item(0 ,i).value 'Pass the Value to the textbox
.Enabled = False 'Disable DataGridView to prevent users from clicking other row while updating.
btnUpdate.Text = "Save"
End With
Case Else 'Save
DatagridView1.Item(0,i).Value = Textbox1.Text
btnUpdate.Text = "Update"
END SELECT
Thanks for those who contributed to finding answers for this thread. I have not used your solutions for now (maybe some other time). After some research, I've found an answer for problem 2 (more user friendly at that):
2 . Or is it possible to just click an item in the Datagridview then
it will be edited at that without passing it to a Textbox, and to be
updated at that.
Here's what i did:
in Private Sub Form1_Load, just add:
yourDataGridView.EditMode = DataGridViewEditMode.EditOnEnter
in Private Sub yourDataGridView_(whatever event here: DoubleCellClick, CellContentClick, etc.) add:
DataGridView1(e.ColumnIndex, e.RowIndex).[ReadOnly] = False
DataGridView1.BeginEdit(False)

How to change programmatically cell values of bound DataGridView without receiving exceptions?

I have problems trying to change programmatically the content of a cell of a bound DataGridView.
I implemented a minimal piece of code to show the problem.
Do the following steps to replicate the problem:
Launch example
Write the title content to create a new row
CTRL+C on inserted title
Move to grid's empty row to force the creation of a new row
CTRL+V on title cell
Click on previous row (new row creation is cancelled)
Click again to the empty row to force the creation of a new row
Exception: Operation is not valid due to the current state of the object.
Here it is the code:
Public Class Form1
Private _dgv As New DataGridView
Private _Movies As New System.ComponentModel.BindingList(Of Movie)
Public Sub New()
InitializeComponent()
Me.Controls.Add(_dgv)
_dgv.Dock = DockStyle.Fill
_dgv.DataSource = _Movies
AddHandler _dgv.KeyDown, AddressOf DataGridView_KeyDown
End Sub
Private Sub DataGridView_KeyDown(sender As Object, e As KeyEventArgs)
If e.Control AndAlso e.KeyCode = Keys.V Then
_dgv.CurrentCell.Value = Clipboard.GetText
End If
End Sub
Public Class Movie
Public Property Title As String
End Class
End Class
For sure there is something wrong in my implementation but I spent many hours searching a workaround without success. Thank you in advance for any help you can give me.
When setting up the form in the constructor, make sure the EditMode of the DataGridView is DataGridViewEditMode.EditOnEnter. This makes the cell we are pasting to enter edit mode as soon as it receives focus and makes the new row stick instead of being cancelled if we move away from it.
Public Sub New()
InitializeComponent()
Me.Controls.Add(_dgv)
_dgv.Dock = DockStyle.Fill
_dgv.DataSource = _Movies
AddHandler _dgv.KeyDown, AddressOf DataGridView_KeyDown
_dgv.EditMode = DataGridViewEditMode.EditOnEnter
End Sub
Then, instead of setting the cell value, set the Title property of the underlying Movie:
Private Sub DataGridView_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.Control AndAlso e.KeyCode = Keys.V Then
Dim Mov As Movie = _Movies.Last
Mov.Title = Clipboard.GetText
_dgv.Refresh()
End If
End Sub
When you add a new row in the DataGridView, the BindingList is automagically adding a new Movie object to the list. _Movies.Last should gets you the newly added Movie.
Why not use the DataGridView event UserAddedRow?
system.windows.forms.datagridview.useraddedrow