VB DataGridView CellMouseClick event Prevents CellMouseDoubleClick - vb.net

I'm using Visual Basic to write a WinForm Application. In my DataGridView I have the Selection Mode property set to CellSelect. I am trying to set my DataGrid up so that on a single click, a few textboxes are populated with some data, and on a double click, it will open up a new form and display all kinds of other info.
I have tried both the CellClick + CellDoubleClick events as well as the CellMouseClick + CellMouseDoubleClick however, everytime I double click, the single click event fires first and prevents the doubleclick event from ever firing.
Maybe this is just a lack of understanding on my part and I need to do something different, I thought about just adding a button column and firing the buttonclick event but that will require a lot of re-coding since I hard-coded existing data columns properties such as Column(1...15).visible = false and a lot more. Anyone have any thoughts on how to get both events to fire?
Double Click event
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
CallLookup.ShowDialog()
Dim PatientID As String = SelectGrid.Rows(SelectGrid.CurrentRow.Index).Cells("PatientID").Value.ToString
PatientID = CallLookup.patientID2
End Sub
Single Click
Private Sub DataGridView1_CellMouseClick1(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseClick
Dim reader As SqlClient.SqlDataReader = mycommand.ExecuteReader
While reader.Read
Dispatchtxt2.Text = (reader("PickupDispatchedTime").ToString)
Enroute2Txt.Text = (reader("PickupEnRouteTime").ToString)
OnScene2Txt.Text = (reader("PickupOnSceneTime").ToString)
Transport2Txt.Text = (reader("PickupTransportTime").ToString)
Arrival2Txt.Text = (reader("PickupArrivalTime").ToString)
clear2txt.Text = (reader("PickupClearTime").ToString)
End While
DataGridView1.Refresh()
DataGridView1.InvalidateRow(DataGridView1.CurrentRow.Index)
Else
End If
End Sub
I left a few lines out that were just a data connection

Related

frm.showDialog dispose when openFileDialog close [vb.net]

I have two forms. First form is used to display a set of record and second form is used to edit the particular record. I called the second form using frm.ShowDialog(). Inside that form I got a button to call the OpenFileDialog. When I press OK or Cancel, then the second form dispose together with the OpenFileDialog. I'm pretty should that my code is correct, but it was the ShowDialog() problem. Anyone have idea on this issue?
This is how i called the second form from the first form to display the Information.
Private Sub btnViewOrganizationEdit_Click(sender As Object, e As EventArgs) Handles btnViewOrganizationEdit.Click, dgvOrganization.DoubleClick
Dim selectedOrganization As New Organization
'check permission because double click
If dgvOrganization.RowCount > 0 Then
strOrganizationID = dgvOrganization.SelectedRows.Item(0).Cells(0).Value
selectedOrganization = helperOrganizationCKJ.getOrganizationByID(strOrganizationID)
frmEditOrganizationCKJ.objOrganization = selectedOrganization
frmEditOrganizationCKJ.ShowDialog()
iniGridView()
End If
End Sub
This is how i called the OpenFileDialog.
Private Sub btnEditOrganizationImage_Click(sender As Object, e As EventArgs) Handles btnEditOrganizationImage.Click
dlgImage.Filter = ""
Dim codecs() As ImageCodecInfo = ImageCodecInfo.GetImageEncoders()
Dim sep As String = String.Empty
For Each c As ImageCodecInfo In codecs
Dim codecName As String = c.CodecName.Substring(8).Replace("Codec", "Files").Trim()
dlgImage.Filter = String.Format("{0}{1}{2} ({3})|{3}", dlgImage.Filter, sep, codecName, c.FilenameExtension)
sep = "|"
Next
dlgImage.FilterIndex = 5
If dlgImage.ShowDialog(Me) = DialogResult.OK Then
'Get the image name
Dim img = dlgImage.FileName
picEditOrganizationImage.Image = System.Drawing.Bitmap.FromFile(img)
End If
End Sub
The frmEditOrganizationCKJ just dispose together with the dispose of OpenFileDialog.
Probably you have copy/pasted your btnEditOrganizationImage from a button that has the DialogResult property set to something different than DialogResult.None.
This triggers the closing action for your modal form and the fix is really simple.
Set the property DialogResult for the btnEditOrganizationImage to DialogResult.None
From MSDN on Button.DialogResult
If the DialogResult for this property is set to anything other than
None, and if the parent form was displayed through the ShowDialog
method, clicking the button closes the parent form without your having
to hook up any events. The form's DialogResult property is then set to
the DialogResult of the button when the button is clicked

RichEditControl event handler, prompting to save upon form close with nothing has changed

Having an issue when closing the form and nothing has changed, it still prompts to save the form. We have a form that has multiple controls. There are a few lookup combo boxes with data. They select their data and then click a button called "view". View then brings up a few textboxes and combo boxes etc and populates with data. There is also a RichEditControl that also gets loaded. After all the data is loaded in the load event. The last line is to call the following method to set event handlers for all controls. If something has changed after that then prompt to save upon form closing.
customFunc.AddDirtyEvent(Me)
The issue is and we have test if there is no richtextbox, it works. If the only control on a form is a RichEditControl, it always prompts to save no matter what, even if nothing has changed upon load. I noticed if you have a form that has a RichEditControl, and it gets populated upon form load. Even if you call the eventhandler after that, it still prompts you to save BUT if you add the eventhandler call in the form shown event, it seems to work as it doesn't set the dirty bit again. Its almost like the events are queue at the end of the form load event. But then it goes to the shown event, the call is made there and the dirty bit doesn't get reset back to true.
Issue is in our case, we can't use a shown event, because we have a button "view" that loads all the data and populates a RichEditControl. So even if we add the event handlers after the data gets loaded in the same method, it always goes back to set the dirty bit to true. We need to somehow keep the dirty bit to false after this, so if there is no changes and they just want to view data don't prompt to save upon form closing. Below is my code.
If customFunc.IsDirty = True Then
Dim dr As DialogResult = MessageBox.Show("Do you want save changes before leaving?", "Closing Mud Report", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2)
If dr = Windows.Forms.DialogResult.Yes Then
SimpleButtonSave.PerformClick()
ElseIf dr = Windows.Forms.DialogResult.Cancel Then
e.Cancel = True
End If
End If
Private Sub SetIsDirty(ByVal sender As System.Object, ByVal e As System.EventArgs)
is_Dirty = True
End Sub
Public Sub AddDirtyEvent(ByVal ctrl As Control)
For Each c As Control In ctrl.Controls
If TypeOf c Is RichEditControl Then
Dim rtb As RichEditControl = CType(c, RichEditControl)
AddHandler rtb.RtfTextChanged, AddressOf SetIsDirty
End If
If c.Controls.Count > 0 Then
AddDirtyEvent(c)
End If
Next
End Sub
In your SetIsDirty method check for RichEditControl.Modified property.
Here is example:
Private Sub SetIsDirty(ByVal sender As System.Object, ByVal e As System.EventArgs)
If TypeOf sender Is RichEditControl Then
Dim rtb As RichEditControl = CType(sender, RichEditControl)
is_Dirty = is_Dirty OrElse rtb.Modified
Else
is_Dirty = True
End If
End Sub

Find Timers by Name

Okay I'm working with visual studio and I've hit a bit of a snag. The basic situation is I have a bunch of buttons and timers that correspond to each other. For example when button1 is clicked Timer1 should start.
Currently I'm using one method to handle all of the button clicks. Which identifies the CR (1, 2, 3, etc...) and constructs a string for the name of the correct Timer that goes along with it, dim timername as string = "timer" & cr.ToString. Then when I use Me.Controls(cr).Enabled = True it returns an a null pointer error.
I know the issue has to do with the identification of the timer, suggestions?
You can't identify a control using a string (well, not easily). Try this.
Private Sub ButtonX_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click ' etc.
Dim vButton = DirectCast(sender, Button)
Select Case vButton.Name
Case "Button1"
Timer1.Start ' Or stop, or whatever
Case "Button2"
Timer2.Start
End Select
End Sub
You can also compare the button object itself using If vButton Is Button1, but that gets messy in VB (I remember having to use GetType and stuff like that).
However, if your code is as simple as my example, why not just use separate handlers for each button?!!
A Timer is a Component not a Control so it will not be located in the Control Collection. This is a case where it is probably better to not use a common button click handler since it is not simplifying anything.
However, everything which inherits from Object, such as a Button, has a Tag property which you can use to associate things with that object. In form load:
Button1.Tag = Timer1
Button2.Tag = Timer2
Button3.Tag = Timer3
Then the click event:
Private Sub ButtonX_Click(... etc ) Handles Button1.Click, Button2.Click ...
Dim thisBtn As Button = CType(sender, Button)
Dim thisTmr As Timer = Ctype(thisBtn.Tag, Timer)
thisTmr.Start
End Sub

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)

DataGridView - ReadOnly Cell KeyDown Event

i have a datagridview with a readonly cell, i would like to show a formdialog window when the user press the space key. but is not possible since the cell is readonly=true.
i'v been using the following code with the EditingControlShowing event. and when the cell is readonly=false it works sometimes.
Private Sub sub_fecha_keydown(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.KeyCode = Keys.Space Then
Dim frm As New frmFecha
frm.fecha_inicial = Me.m_dtp_id_fecha.Fecha
Dim res As DialogResult = frm.ShowDialog()
If res = Windows.Forms.DialogResult.OK Then
Me.m_dgv_detalle.Rows(Me.m_dgv_detalle.CurrentRow.Index).Cells("m_dgv_dtm_documento").Value = frm.fecha_format
Else
Me.m_dgv_detalle.Rows(Me.m_dgv_detalle.CurrentRow.Index).Cells("m_dgv_dtm_documento").Value = ""
End If
End If
End Sub
i would like to keep the cell readonly=true.
is there any other way to do it?
thanks very much for your time and help.
Rather than trying to intercept a keystroke for a readonly cell, which may not be possible, why not add a button column next to the field and when it is pressed, perform your actions.
This way you don't have to worry about whether the cell is readonly or not and it will be easier for your users to understand how the form is to be accessed.
Here is a link to the MSDN documentation on the DataGridViewButtonColumn.