IndexOutOfRangeException error when DataGridView header is clicked - vb.net

Iam trying to get DataGridView rowIndex and set it to textbox and all is well with this code
Private Sub dgv_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellContentClick
isitxt(e.RowIndex)
btnInsert.Enabled = False
btnUpdate.Enabled = True
btnDelete.Enabled = True
End Sub
and
Sub isitxt(ByVal x As Integer)
txtIDBarang.Text = dgv.Rows(x).Cells(0).Value
txtNamaBarang.Text = dgv.Rows(x).Cells(1).Value
cbJenisBarang.Text = dgv.Rows(x).Cells(2).Value
numHargaBeli.Value = dgv.Rows(x).Cells(3).Value
numHargaJual.Value = dgv.Rows(x).Cells(4).Value
End Sub
But i got IndexOutOfRangeException when i clicked on Column Header. how can i handle it ?

Note, that if you use CellContentClick, the code will be executed only if the user actually aims at text content of a cell. Usually a CellClick is makes more sense.
As for your code, you can debug and see, what's in "x", when you get an error - I guess "-1"... You can handle it then. However, the reason for this should not be in your code above.
You can also set SelectionMode = FullRowSelect and do it following way:
Private Sub dgv_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgv.CellClick
isitxt(Me.dgv.selectedRows(0).index)
btnInsert.Enabled = False
btnUpdate.Enabled = True
btnDelete.Enabled = True
End Sub
Unless you want to handle the cells separately, users usually prefer the FullRowSelect mode.

Related

How to prevent Checkbox Checkchanged event from firing in VB.Net

I have this code in my one function
If DataServices.IsGroupByMe(test) = True Then
chkGroup.Visible = True
chkGroup.Checked = True
Else
chkGroup.Checked = False
chkGroup.Visible = False
End If
Upon going through this line
chkGroup.Checked = True
It automatically calls my checkchanged event for that checkbox
Private Sub chkGroupByMe_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkGroupOper.CheckedChanged
LoadFilteredData()
End Sub
Which then distrupts the usual sequence of action to perform. Are there ways to prevent triggering the checkchanged event?
Please note that the first function in the base form. and the checkchanged event in a different child form inheriting the base.
You can simply use a variable to block the update:
private bool PreventUpdate;
// your function
If DataServices.IsGroupByMe(test) = True Then
PreventUpdate = true;
// ... all tasks
PreventUpdate = false;
// handler
Private Sub chkGroupByMe_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkGroupOper.CheckedChanged
if not PreventUpdate Then
LoadFilteredData()
End Sub
A simple method would be to remove the Event Handler before settings its value and then re-assigning it.
Before setting the checked value (or at the start of the function):
RemoveHandler chkGroup.CheckedChanged, AddressOf chkGroupByMe_CheckedChanged
And after setting the checked value (or at the end of the function):
AddHandler chkGroup.CheckedChanged, AddressOf chkGroupByMe_CheckedChanged
Note: Anytime you add an EventHandler using the method above, always make sure there is a corresponding RemoveHandler called before it. Calling RemoveHandler too many times won't be a problem, but having your events handled too many times will cause you a few headaches wondering what is going on.
This is tough to answer since we don't really know the structure of your forms, in which form each piece of code reside nor how you interact with them.
However, one option is that you create a Shared property in the base form that indicates when LoadFilterData() should be bypassed.
Put this in your base form:
Protected Shared Property BypassDataLoad As Boolean = False
Then in your function do:
If DataServices.IsGroupByMe(test) = True Then
BaseForm.BypassDataLoad = True
chkGroup.Visible = True
chkGroup.Checked = True
BaseForm.BypassDataLoad = False
Else
BaseForm.BypassDataLoad = True
chkGroup.Checked = False
chkGroup.Visible = False
BaseForm.BypassDataLoad = False
End If
...and in your event handler:
Private Sub chkGroupByMe_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkGroupOper.CheckedChanged
If Not BaseForm.BypassDataLoad Then
LoadFilteredData()
End If
End Sub
Replace BaseForm with the actual name of your base form class.
you can remove the event handler using RemoveHandler before setting the Checked property to true. Then in the else case where you set the Checked property to false you can add the eventhandler back using the AddHandler. so that whenever it is checked the actual event will fire.
You can use the "Tag" property of the checkbox in order to control the "CheckChanged" event instead of removing and re-adding the handler again.
Please try the following code:
If DataServices.IsGroupByMe(test) Then
chkGroup.Tag = "0"
chkGroup.Visible = True
chkGroup.Checked = True
Else
chkGroup.Tag = "0"
chkGroup.Checked = False
chkGroup.Visible = False
End If
Private Sub chkGroupByMe_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkGroupOper.CheckedChanged
If chkGroup.Tag <> "0" Then
LoadFilteredData()
End If
chkGroup.Tag = ""
End Sub

VB 2010 .NET ComboBox How To Controll Object Whit This?

I want to ask how to control objects with a combobox in VB.
So I have a combobox with two choices On and Off.
How can I enable and disable a textbox with an combobox?
you can try something like this
private Sub OrainsComboBox3_SelectedIndexChanged(sender As Object, e As EventArgs) Handles OrainsComboBox3.SelectedIndexChanged
If OrainsComboBox3.SelectedText = "On" Then
OrainsTextBox7.Enabled = True
OrainsTextBox8.Enabled = True
End If
If OrainsComboBox3.SelectedText = "Off" Then
OrainsTextBox7.Enabled = False
OrainsTextBox8.Enabled = False
End If
End Sub

Checkbox does does not work in VB.Net form

I have two checkboxes for two groupboxes to enable visibility or invisibility of each one at a time but somehow one is working(chboNew) the other one(chboIssue) doesn't!
here is the code I have written for it, any help would be appreciated:
Private Sub chboIssue_CheckStateChanged(sender As Object, e As EventArgs) Handles chboIssue.CheckStateChanged
If chboIssue.Checked = True Then
gbIssueSearch.Visible = True
gbNewSearch.Visible = False
chboNew.Checked = False
ElseIf chboIssue.Checked = False Then
gbIssueSearch.Visible = False
End If
End Sub
Private Sub chboNew_CheckStateChanged(sender As Object, e As EventArgs) Handles chboNew.CheckStateChanged
If chboNew.Checked = True Then
gbNewSearch.Visible = True
gbIssueSearch.Visible = False
chboIssue.Checked = False
ElseIf chboIssue.Checked = False Then
gbNewSearch.Visible = False
End If
End Sub
If user has to choose between new issue and issue search,one at a time.
Then you should use radio buttons, instead of checkbox.
Checkbox gives idea that user can choose both checkboxes at same time.
Which in your case is not true.
Changing the name of the checkboxes is not going to solve your issue. I noticed that for your chboNew.CheckStateChanged event handler in your elseif clause you are checking if chboIssue is checked, whereas in your other handler for chboIssue both your if/else clauses look at chboIssue. I'm thinking that may be part of your issue. Also, if only one of these boxes is supposed to be checked at a time, you may want to add logic to automatically uncheck the other whenever one is checked. For instance, in your chboNew handler, "If chboNew.Checked = True Then chboIssue = False", and the inverse in your chboIssue handler. Hope this helps.

Managing `CheckBox_Checked` Event without an infinite loop

I know this seems like an easy fix, but I am having trouble. I have a CheckBox, when checked, I remove the data source of a DataGridView on my Windows Form and remove the ReadOnly properties of a few Textbox.
I know the CheckedChanged event will send my code into an infinite loop, but I cannot figure out which event would handle this change without changing the CheckedState each time. I have tried using Click, MouseClick, and CheckStateChanged events with no luck.
This is my current code:
Private Sub chkManual_MouseClick(sender As Object, e As EventArgs) Handles chkManual.MouseClick
If Not Me.chkManual.Checked Then
Me.chkManual.Checked = False
Me.cbRegion.SelectedIndex = -1
Me.txtIssueDate.ReadOnly = True
Me.txtCasenum.ReadOnly = True
Me.txtCommnum.ReadOnly = True
Exit Sub
Else
Me.dgDataEntry.DataSource = Nothing
Me.cbRegion.SelectedIndex = -1
Me.txtIssueDate.ReadOnly = False
Me.txtCasenum.ReadOnly = False
Me.txtCommnum.ReadOnly = False
ClearForm()
frmPDF.Hide()
Exit Sub
End If
End Sub
Properties of CheckBox: AutoCheck = True, Checked = False, and CheckState = Unchecked
I have looked into these already:
CheckBox_Checked event
Is there a simpler way to process check boxes?
CheckBox reverts to checked after being unchecked
How to check if a checkboxes state has changed
How can I prevent an assignment statement to CheckBox.Checked from raising the CheckChanged event?
http://www.vbforums.com/showthread.php?758455-CheckBox-code-got-stuck-in-an-infinite-loop-can-not-unchecked-it
EDIT
It helps if your ClearForm() sub doesn't change the CheckedState of your CheckBox back to False every time. Thank you #Visual Vincent for pointing out the obvious. Nothing is wrong with the code, changed the EventHandler to CheckedChanged
Final code (so simple):
Private Sub chkManual_CheckedChanged(sender As Object, e As EventArgs) Handles chkManual.CheckedChanged
If Me.chkManual.Checked Then
Me.dgDataEntry.DataSource = Nothing
Me.cbRegion.SelectedIndex = -1
Me.txtIssueDate.ReadOnly = False
Me.txtCasenum.ReadOnly = False
Me.txtCommnum.ReadOnly = False
ClearForm()
frmPDF.Hide()
Else
Me.cbRegion.SelectedIndex = -1
Me.txtIssueDate.ReadOnly = True
Me.txtCasenum.ReadOnly = True
Me.txtCommnum.ReadOnly = True
End If
End Sub
I'm not sure if you want the CheckBox, when Checked, to Uncheck again automatically or not!?...seems like a weird interface.
At any rate, if you want something to occur when the Check state changes:
Private Sub chkManual_CheckedChanged(sender As Object, e As EventArgs) Handles chkManual.CheckedChanged
If chkManual.Checked Then
Debug.Print("Checked")
Me.dgDataEntry.DataSource = Nothing
Me.cbRegion.SelectedIndex = -1
Me.txtIssueDate.ReadOnly = False
Me.txtCasenum.ReadOnly = False
Me.txtCommnum.ReadOnly = False
ClearForm()
frmPDF.Hide()
Else
Debug.Print("UnChecked")
Me.cbRegion.SelectedIndex = -1
Me.txtIssueDate.ReadOnly = True
Me.txtCasenum.ReadOnly = True
Me.txtCommnum.ReadOnly = True
End If
End Sub
You can uncheck the checkbox without an infinite loop like this:
Private Sub chkManual_CheckedChanged(sender As Object, e As EventArgs) Handles chkManual.CheckedChanged
Static counter As Integer
If chkManual.Checked Then
counter = counter + 1 ' just to show we're not in an infinite loop...
Debug.Print("Checked " & counter) ' just to show we're not in an infinite loop...
chkManual.Checked = False
Else
Debug.Print("UnChecked")
End If
End Sub
Not sure why you'd want to do that...seems like that would basically be a "reset" button as it couldn't stay in a checked state...
Can you remove the code that changes the checkbox state? Ex:
Me.chkManual.Checked = False
The box will check or uncheck without your code having to do it, and the event will only throw once.
I think the easiest way is to remove event listener before handling checkbox checked state. Use try-finally block to ensure that checkbox event listener is always set back.
Try
RemoveHandler chkManual AddressOf chkManual_MouseClick
Me.chkManual.Checked = False
...
Finally
AddHandler chkManual AddressOf chkManual_MouseClick
End Try

MS DataGridView.show fails to work

I used to have a single DataGridView (DGV) on a form. I formatted and populated this, then used DGV.Show to make it appear on my form. This worked fine.
I upgraded my form, to included 2 DGVs. Within a sub I dim a new DGV, populate and format it as before then set this equal to whichever DGV on the form it's meant to be. For example:
Dim pDGV as new DataGridView
with pDGV
.ColumnHeadersVisible = True
.RowHeadersVisible = False
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
.ScrollBars = ScrollBars.Both
.DataSource = pTable
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.ReadOnly = True
end with
frm1.DGV1 = pDGV
frm1.DGV1.show
During debug, I can see that Frm1.DGV appears to be indentical to pDGV, in that it has the same number of columns and rows etc. However, it fails to show.
I can revert back to populating and formatting each DGV individually, but that duplicates a lot of code. I thought this would be more elegant.
Any ideas as to why the .show won't work?
thanks
You are trying to assign an instance of DataGridView create at run-time to a DataGridView already created on the form. This is not possible.
You can implement something similar to this to achieve your goal.
Public Class Form1
Dim _DT As New DataTable
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
_DT.Columns.Add("0")
For i As Integer = 0 To 9
_DT.Rows.Add(i)
Next
FormatDataGridView(DataGridView1)
FormatDataGridView(DataGridView2)
End Sub
Public Sub FormatDataGridView(ByVal dgv As DataGridView)
With dgv
.ColumnHeadersVisible = True
.RowHeadersVisible = False
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
.ScrollBars = ScrollBars.Both
.DataSource = _DT
.AllowUserToAddRows = False
.AllowUserToDeleteRows = False
.ReadOnly = True
End With
End Sub
End Class
Otherwise you can create the DataGridView at run-time and then adding to a Panel for example.