Is there a way to shorten these PictureBox Subs? - vb.net

I have 9 PictureBoxes on my form. Every single PictureBox got its own DoubleClick event handler. I haven't yet found a way to combine these 9 subs into one; especially because the bitmap list (List(Of System.Drawing.Bitmap)) must have a different number of .count.
If you click on a PictureBox, only code for this should be executed.
Private Sub PictureBox1_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox1.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 0 Then
BitmapList.RemoveAt(0)
Path_List.RemoveAt(0)
PictureBox1.Image = Nothing
End If
End Sub
Private Sub PictureBox2_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox2.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 1 Then
BitmapList.RemoveAt(1)
Path_List.RemoveAt(1)
PictureBox2.Image = Nothing
End If
End Sub
Private Sub PictureBox3_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox3.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 2 Then
BitmapList.RemoveAt(2)
Path_List.RemoveAt(2)
PictureBox3.Image = Nothing
End If
End Sub
Private Sub PictureBox4_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox4.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 3 Then
BitmapList.RemoveAt(3)
Path_List.RemoveAt(3)
PictureBox4.Image = Nothing
End If
End Sub
Private Sub PictureBox5_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox5.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 4 Then
BitmapList.RemoveAt(4)
Path_List.RemoveAt(4)
PictureBox5.Image = Nothing
End If
End Sub
Private Sub PictureBox6_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox6.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 5 Then
BitmapList.RemoveAt(5)
Path_List.RemoveAt(5)
PictureBox6.Image = Nothing
End If
End Sub
Private Sub PictureBox7_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox7.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 6 Then
BitmapList.RemoveAt(6)
Path_List.RemoveAt(6)
PictureBox7.Image = Nothing
End If
End Sub
Private Sub PictureBox8_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox8.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 7 Then
BitmapList.RemoveAt(7)
Path_List.RemoveAt(7)
PictureBox8.Image = Nothing
End If
End Sub
Private Sub PictureBox9_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox9.DoubleClick
If BitmapList IsNot Nothing AndAlso BitmapList.Count > 8 Then
BitmapList.RemoveAt(8)
Path_List.RemoveAt(8)
PictureBox9.Image = Nothing
End If
End Sub

Start by setting the Tag property of each PictureBox to the corresponding number in the designer, i.e. PictureBox1.Tag to 0, etc. You can then combine all those event handlers into one:
Private Sub PictureBoxes_DoubleClick(sender As Object, e As EventArgs) Handles PictureBox1.DoubleClick,
PictureBox2.DoubleClick,
PictureBox3.DoubleClick,
PictureBox4.DoubleClick,
PictureBox5.DoubleClick,
PictureBox6.DoubleClick,
PictureBox7.DoubleClick,
PictureBox8.DoubleClick,
PictureBox9.DoubleClick
Dim pb = DirectCast(sender, PictureBox)
Dim n = CInt(pb.Tag)
If BitmapList?.Count > n Then
BitmapList.RemoveAt(n)
Path_List.RemoveAt(n)
pb.Image.Dispose()
pb.Image = Nothing
End If
End Sub
Note that I added a line to dispose the Image you're removing. Don't do that if you're still using the Image object elsewhere but definitely do it if you're not still using it.
Note that I also threw a null propagation operator in there, negating the need for a separate null check.

Related

Get selected value from DateTimePicker

I would like to get selected value from DateTimePicker in VB (If I select only day value then I would like to get only selected day value.)
In this image I have selected (blue marked) year value from this DateTimePicker. So I need only this year value.
In the case of TextBox I can get selected value using
TextEndTime.SelectedText
Is there any syntax or approach to get selected value from DateTimePicker?
As the DateTimePicker-control can be manipulated by using the arrow keys, you can use SendKeys to change the current selected value.
The following example gets the current DateTime-value of the DateTimePicker and, after sending the ↑ key, compares the value to the new value. At last it resets the DateTimePicker to the original value.
So the variable currSelected will contain the last Selection.
Dim currVal As DateTime
Dim newVal As DateTime
Dim valCheck As Boolean
Dim currSelected As Selection = Selection.None
Public Enum Selection
None = 0
Year = 1
Month = 2
Day = 3
End Enum
Private Sub CheckDTPSelection(dtp As DateTimePicker)
valCheck = True
currVal = dtp.Value
SendKeys.Send("{UP}")
End Sub
Sub RefreshSelection(dtp As DateTimePicker)
If valCheck Then
newVal = dtp.Value
If currVal.Year <> newVal.Year Then
currSelected = Selection.Year
ElseIf currVal.Month <> newVal.Month Then
currSelected = Selection.Month
ElseIf currVal.Day <> newVal.Day Then
currSelected = Selection.Day
End If
dtp.Value = currVal
valCheck = False
End If
End Sub
Private Sub MyDateTimePicker_DropDown(sender As Object, e As EventArgs) Handles MyDateTimePicker.DropDown
RemoveHandler MyDateTimePicker.MouseUp, AddressOf MyDateTimePicker_MouseUp
End Sub
Private Sub MyDateTimePicker_CloseUp(sender As Object, e As EventArgs) Handles MyDateTimePicker.CloseUp
AddHandler MyDateTimePicker.MouseUp, AddressOf MyDateTimePicker_MouseUp
CheckDTPSelection(MyDateTimePicker)
End Sub
Private Sub MyDateTimePicker_KeyUp(sender As Object, e As KeyEventArgs) Handles MyDateTimePicker.KeyUp
If e.KeyValue = Keys.Left OrElse e.KeyValue = Keys.Right Then
CheckDTPSelection(MyDateTimePicker)
End If
End Sub
Private Sub MyDateTimePicker_MouseUp(sender As Object, e As MouseEventArgs) Handles MyDateTimePicker.MouseUp
CheckDTPSelection(MyDateTimePicker)
End Sub
Private Sub MyDateTimePicker_ValueChanged(sender As Object, e As EventArgs) Handles MyDateTimePicker.ValueChanged
Dim dtp As DateTimePicker = DirectCast(sender, DateTimePicker)
RefreshSelection(dtp)
End Sub
Private Sub Btn_WhatsSelected_Click(sender As Object, e As EventArgs) Handles Btn_WhatsSelected.Click
'Show the current selected value in a MessageBox
MessageBox.Show(currSelected.ToString())
End Sub
Hi Everyone and thanks for your tips that the DateTimePicker-control can be manipulated.
I had the selection problem with DateTimePicker , the currently selected item value could not send to a text box, as DTP works only valuechanged event. I spend 4 hours time to find the solution and wrote the following code:
Public MyEventCounter As Integer = 0
Private Sub DTPAcquDt_DropDown(sender As Object, e As EventArgs) Handles DTPAcquDt.DropDown
RemoveHandler DTPAcquDt.MouseUp, AddressOf dtpacqudt_closeup
End Sub
Private Sub dtpacqudt_closeup(sender As Object, e As EventArgs) Handles DTPAcquDt.CloseUp
AddHandler DTPAcquDt.MouseUp, AddressOf dtpacqudt_closeup
'Check the Mouse/Keys event counter
If MyEventCounter > 0 Then
TxtDtAcqu.Text = DTPAcquDt.Value
'RESET The Counter
MyEventCounter = 0
End If
End Sub
Private Sub DTPAcquDt_KeyUp(sender As Object, e As KeyEventArgs) Handles DTPAcquDt.KeyUp
If e.KeyValue = Keys.Left OrElse e.KeyValue = Keys.Right Then
MyEventCounter = MyEventCounter + 1
End If
End Sub
Private Sub DTPAcquDt_MouseUp(sender As Object, e As MouseEventArgs) Handles DTPAcquDt.MouseUp
MyEventCounter = MyEventCounter + 1
End Sub
Private Sub DTPAcquDt_ValueChanged(sender As Object, e As EventArgs) Handles DTPAcquDt.ValueChanged
TxtDtAcqu.Text = DTPAcquDt.Value
'RESET The Counter
MyEventCounter = 0
End Sub

Change the color of a button(s) for a duration of time

I have a small VB.net app that has a LOT of buttons. I need to change the back color of the buttons when they are clicked and then set it back to its original color after a duration of 10 seconds. I am struggling with either using a timer or the time process both of which have their own issues.
Any ideas to make this work and work efficiently?
Code:
Private Sub MyButtons_Click(sender As Object, e As EventArgs) _
Handles Button1.Click,
Button2.Click
Dim myButton = DirectCast(sender, Button)
MakeCall()
myButton.BackColor = Color.Green
'TurnOnActiveCallCOLOR.Enabled = True
For i As Integer = 0 To 10000 - 1
Threading.Thread.Sleep(10000)
Next
myButton.BackColor = Color.FromArgb(64, 64, 64)
End Sub
Here is an example of using a Windows Forms Timer to accomplish what you need:
Private MyButton As Button
Private Sub MyButtons_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
MyButton = DirectCast(sender, Button)
MyButton.BackColor = Color.Green
Timer1.Enabled = True
MakeCall()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
MyButton.BackColor = Color.FromArgb(64, 64, 64)
Timer1.Enabled = False
End Sub
To handle an arbitrary number of buttons, you could have something like this:
Public Class Form1
Dim buttonTimers As New Dictionary(Of Control, ButtonTimer)
Class ButtonTimer
Property Timeout As Integer = 2000
Property Target As Control
Property ActiveColor As Color = Color.Green
Property DefaultColor As Color = Color.FromArgb(64, 64, 64)
Private tim As Timer
Sub TimTick(sender As Object, e As EventArgs)
tim.Stop()
Target.BackColor = DefaultColor
End Sub
Sub New()
' empty constructor
End Sub
Sub New(target As Control)
Me.Target = target
Me.Target.BackColor = Me.ActiveColor
tim = New Timer With {.Interval = Timeout}
AddHandler tim.Tick, AddressOf TimTick
tim.Start()
End Sub
Sub Restart()
Target.BackColor = Me.ActiveColor
If tim IsNot Nothing Then
tim.Stop()
tim.Start()
End If
End Sub
Public Sub DisposeOfTimer()
If tim IsNot Nothing Then
tim.Stop()
RemoveHandler tim.Tick, AddressOf TimTick
tim.Dispose()
End If
End Sub
End Class
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
Dim myButton = DirectCast(sender, Button)
'MakeCall()
If buttonTimers.ContainsKey(myButton) Then
buttonTimers(myButton).Restart()
Else
buttonTimers.Add(myButton, New ButtonTimer(myButton))
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
For Each x In buttonTimers
x.Value.DisposeOfTimer()
Next
End Sub
End Class
If a button is clicked again before the timeout, the time is restarted.
You can add other constructors if you want to have a different timeout/colours for different buttons.
The MyBase.FormClosing code should be included in your form closing handler (if there is one) so that the timers are cleaned up properly.
I expect it would be tidier overall to make your own custom button class which inherits from Button, so you might want to investigate doing that. (How to: Inherit from Existing Windows Forms Controls.)
asynh and await if you don't want use timer. Simple method using task.delay
Private Async Sub ButtonClick(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click
DirectCast(sender, Button).BackColor = Color.Red 'after click setcolor to red
Await setColorAfterDelay(sender) 'Add this comand on button click and don't forget add asynh before sub in this method
End Sub
Public Async Function setColorAfterDelay(sender As Object) As Task
Await Task.Delay(1000) ''Milisecound how long you wana dealey
DirectCast(sender, Button).BackColor = Color.White 'and set colorto white
End Function
With the use of lambda expressions (and a lookup table if you want to interact with it further) you can do this pretty easily:
'Lookup table for if you want to be able to interact with the timers even more.
Dim ButtonTimers As New Dictionary(Of Button, Timer)
Private Sub MyButtons_Click(sender As Object, e As EventArgs) _
Handles Button1.Click, Button2.Click
MakeCall()
Dim myButton = DirectCast(sender, Button)
myButton.BackColor = Color.Green
'If a timer already exists for the button, restart it.
Dim existingTimer As Timer = Nothing
If ButtonTimers.TryGetValue(myButton, existingTimer) Then
existingTimer.Stop()
existingTimer.Start()
Return 'Do not execute the rest of the code.
End If
'Create the timer and set its Interval to 10000 ms (10 seconds).
Dim buttonTimer As New Timer() With {.Interval = 10000}
'Add a handler to its Tick event.
AddHandler buttonTimer.Tick, _
Sub(tsender As Object, te As EventArgs)
myButton.BackColor = Color.FromArgb(64, 64, 64)
'Dispose timer and remove from lookup table.
ButtonTimers.Remove(myButton)
buttonTimer.Stop()
buttonTimer.Dispose()
End Sub
ButtonTimers.Add(myButton, buttonTimer)
buttonTimer.Start()
End Sub
If you want to interact with a button's timer (if one exists) you can do:
Dim buttonTimer As Timer = Nothing
If ButtonTimers.TryGetValue(yourButtonHere) Then
'Do something with buttonTimer...
End If
This could probably be done better by dynamically creating timer controls so each button has it's own timer but here is what I came up with.
Oh, an set your timer to 1000 interval and enabled to 'False'.
Public Class Form1
Dim T1 As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
T1 = T1 + 1
If T1 = 10 Then
For Each button In Controls
button.backcolor = Color.FromArgb(225, 225, 225)
Next
Timer1.Stop()
T1 = 0
End If
Me.Text = T1
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Button1.BackColor = Color.Red
Timer1.Start()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Button2.BackColor = Color.Orange
Timer1.Start()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button3.BackColor = Color.Yellow
Timer1.Start()
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Button4.BackColor = Color.Green
Timer1.Start()
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
Button5.BackColor = Color.Blue
Timer1.Start()
End Sub
End Class

keypress on datagridview only character "abcde" and convert to uppercase

How to limit keypress on datagridview only character abcde and convert to uppercase at vb.net?
Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
If DataGridView1.CurrentCell.ColumnIndex = 3 Then
AddHandler CType(e.Control, TextBox).KeyPress, AddressOf TextBoxabcde_keyPress
End If
End Sub
Private Sub TextBoxabcde_keyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)
If Not Char.IsControl(e.KeyChar) And Not Char.IsLetter(e.KeyChar) And e.KeyChar <> "." Then
e.Handled = True
End If
End Sub
Updated:
Private Sub DataGridView1_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles DataGridView1.KeyPress
Dim allLetters As String = "abcde"
If Not allLetters.Contains(e.KeyChar.ToString.ToLower) Then
e.KeyChar = ChrW(0)
e.Handled = True
End If
End Sub
Private Sub dataGridView1_CellFormatting(sender As Object, e As
DataGridViewCellFormattingEventArgs)
If e.Value IsNot Nothing Then
e.Value = e.Value.ToString().ToUpper()
e.FormattingApplied = True
End If
End Sub
another solution,im try with this, its work
Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
If DataGridView1.CurrentCell.ColumnIndex = 3 Then
DirectCast(e.Control, TextBox).CharacterCasing = CharacterCasing.Upper
AddHandler CType(e.Control, TextBox).KeyPress, AddressOf TextBoxabcde_keyPress
End If
End Sub
Private Sub TextBoxabcde_keyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)
If Not (Asc(e.KeyChar) = 8) Then
Dim allowedChars As String = "ABCDE"
If Not allowedChars.Contains(e.KeyChar.ToString.ToUpper) Then
e.Handled = True
End If
End If
End Sub
thanks for your help Claudius
Try this
Dim txtEC As DataGridViewTextBoxEditingControl = Nothing
Private Sub DGV_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DGV.EditingControlShowing
If TypeOf e.Control Is DataGridViewTextBoxEditingControl Then
If DGV.CurrentCell.ColumnIndex =1 Then
txtEC = DirectCast(e.Control, DataGridViewTextBoxEditingControl)
txtEC.CharacterCasing = CharacterCasing.Upper
End If
End If
End Sub
Private Sub DGV_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DGV.CellEndEdit
If txtEC IsNot Nothing Then
txtEC.CharacterCasing = CharacterCasing.Normal
txtEC = Nothing
End If
End Sub

Adding 150,000 records to a listview without freezing UI

I have a listview loop that is adding 150,000 items to my listview. For testing purposes I moved this code to a background worker with delegates, but it still freezes up the UI. I am trying to find a solution so that it can add these items in the background while I do other stuff in the app. What solutions do you guys recommend?
this is what I am using
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.Clear()
ListView1.BeginUpdate()
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If bw.IsBusy Then bw.CancelAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
For x = 1 To 125000
Dim lvi As New ListViewItem("Item " & x)
If bw.CancellationPending Then
e.Cancel = True
Exit For
Else
bw.ReportProgress(0, lvi)
End If
Next
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bw.ProgressChanged
Try
Dim lvi As ListViewItem = DirectCast(e.UserState, ListViewItem)
Me.ListView1.Items.Add(lvi)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
ListView1.EndUpdate()
If Not e.Cancelled Then
Debug.Print("Done")
Else
Debug.Print("Cancelled")
End If
End Sub
End Class
Give this a try, it's a great example for what you would need... I also had a progress bar that shows the progress and such, see example image that is attached. Also I wasn't seeing any delegate that you need to perform such operation, mine has one that will be required. The reason is you are adding items to a control on the UI thread, in order to add items we need to know if an Invoke is required, if so we invoke otherwise we add the item to the control... Also I made the thread sleep, so it can take a break; this also prevents the UI from wanting to lock up here and there, now it's responsive with NO FREEZING.
Option Strict On
Option Explicit On
Public Class Form1
Delegate Sub SetListItem(ByVal lstItem As ListViewItem) 'Your delegate..
'Start the process...
Private Sub btnStartProcess_Click(sender As Object, e As EventArgs) Handles btnStartProcess.Click
lvItems.Clear()
bwList.RunWorkerAsync()
End Sub
Private Sub AddListItem(ByVal lstItem As ListViewItem)
If Me.lvItems.InvokeRequired Then 'Invoke if required...
Dim d As New SetListItem(AddressOf AddListItem) 'Your delegate...
Me.Invoke(d, New Object() {lstItem})
Else 'Otherwise, no invoke required...
Me.lvItems.Items.Add(lstItem)
End If
End Sub
Private Sub bwList_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwList.DoWork
Dim intCount As Integer = CInt(txtCount.Text)
Dim dblPercent As Integer = 100
Dim intComplete As Integer = 0
Dim li As ListViewItem = Nothing
For i As Integer = 1 To CInt(txtCount.Text)
If Not (bwList.CancellationPending) Then
li = New ListViewItem
li.Text = "Item " & i.ToString
AddListItem(li)
Threading.Thread.Sleep(1) 'Give the thread a very..very short break...
ElseIf (bwList.CancellationPending) Then
e.Cancel = True
Exit For
End If
intComplete = CInt(CSng(i) / CSng(intCount) * 100)
If intComplete < dblPercent Then
bwList.ReportProgress(intComplete)
End If
If li IsNot Nothing Then
li = Nothing
End If
Next
End Sub
Private Sub bwList_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bwList.ProgressChanged
pbList.Value = e.ProgressPercentage
End Sub
Private Sub bwList_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwList.RunWorkerCompleted
If pbList.Value < 100 Then pbList.Value = 100
MessageBox.Show(lvItems.Items.Count.ToString & " items were added!")
End Sub
Private Sub btnStopWork_Click(sender As Object, e As EventArgs) Handles btnStopWork.Click
bwList.CancelAsync()
End Sub
Private Sub btnRestart_Click(sender As Object, e As EventArgs) Handles btnRestart.Click
pbList.Value = 0
lvItems.Items.Clear()
txtCount.Text = String.Empty
End Sub
End Class
Screenshot in action...

open selected row in datagridview to edit in Another form

I am using vb.net designer to connect to access database .
On my Form1 I have a DataGridView And Two Button For Add And Edit
I Make Form2 To Add Data Into Database And Worked OK ..
Imake Form3 Wiht Same form2 Content
Now I need When i selcet row in DataGridView And Clic Edit Button The data of selected row show on form3 for Edit it
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SalesTableAdapter.Fill(Me.OrdersDataSet.sales)
Me.DateTimePicker1.Value = Date.Today
End Sub
Private Sub DateTimePicker1_ValueChanged(sender As Object, e As EventArgs) Handles DateTimePicker1.ValueChanged
SalesBindingSource.Filter = String.Format("date = '{0}'", DateTimePicker1.Value.ToShortDateString())
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.Show()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Form3.Show()
End Sub
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
End Sub
Private Sub SalesDataGridView_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles SalesDataGridView.CellContentClick
End Sub
End Class
You need to approach this in a modal/dialog way. You only need one form for both add and edit.
Add/Edit form
Add a parameterized constructor to the form.
Public Sub New(row As DataRowView)
Me.InitializeComponent()
'Me.ctlAge: NumericUpDown control.
'Me.ctlBirthday: DateTimePicker control.
'Me.ctlName: TextBox control.
If (row Is Nothing) Then
'Add mode, set default values:
Me.ctlAge.Value = 0
Me.ctlBirthday.Value = Date.Now
Me.ctlName.Text = String.Empty
Else
'Edit mode, set current values:
Me.ctlAge.Value = CDec(row.Item("AGE"))
Me.ctlBirthday.Value = CDate(row.Item("BIRTHDAY"))
Me.ctlName.Text = CStr(row.Item("NAME"))
End If
End Sub
You also need an accept button and a cancel button.
Friend Sub btnAcceptClicked(sender As Object, e As EventArgs) Handles btnAccept.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
Me.Close()
End Sub
Friend Sub btnCancelClicked(sender As Object, e As EventArgs) Handles btnCancel.Click
Me.DialogResult = Windows.Forms.DialogResult.Cancel
Me.Close()
End Sub
Main form
Add method:
Private Sub btnAddClicked(sender As Object, e As EventArgs) Handles btnAdd.Click
Try
Using f As New AddOrEditForm(CType(Nothing, DataRowView))
If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
Dim view As DataView = TryCast(Me.SalesDataGridView.DataSource, DataView)
If (view Is Nothing) Then
Throw New InvalidCastException()
End If
Dim viewRow As DataRowView = view.AddNew()
viewRow.EndEdit()
viewRow.Item("AGE") = f.ctlAge.Value
viewRow.Item("BIRTHDAY") = f.ctlBirthday.Value
viewRow.Item("NAME") = f.ctlName.Text
viewRow.EndEdit()
End If
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Edit method:
Private Sub btnEditClicked(sender As Object, e As EventArgs) Handles btnEdit.Click
Try
Me.SalesDataGridView.EndEdit()
If (Me.SalesDataGridView.SelectedRows.Count > 0) Then
Dim gridRow As DataGridViewRow = Me.SalesDataGridView.SelectedRows(0)
Dim viewRow As DataRowView = TryCast(gridRow.DataBoundItem, DataRowView)
If (viewRow Is Nothing) Then
Throw New InvalidCastException()
End If
Using f As New AddOrEditForm(viewRow)
If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
viewRow.BeginEdit()
Try
viewRow.Item("AGE") = f.ctlAge.Value
viewRow.Item("BIRTHDAY") = f.ctlBirthday.Value
viewRow.Item("NAME") = f.ctlName.Text
viewRow.EndEdit()
Catch ex As Exception
viewRow.CancelEdit()
Throw ex
End Try
End If
End Using
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub