Change datagriview cell value on CellValidating - vb.net

I would like to change the value of cell value which user inputs there and do the trim before to avoid left and right spaces over value before it will be validated. Currently this is my code without this feature:
Private Sub Grid_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles Grid.CellValidating
Dim newValue = e.FormattedValue.ToString
If Not Grid.Rows(e.RowIndex).IsNewRow Then 'And Not e.RowIndex = Grid.NewRowIndex - 1 Then
Select Case e.ColumnIndex
Case 1 'Name
If String.IsNullOrEmpty(newValue) Then
e.Cancel = True
Exit Select
End If
Case Else
End Select
End If
End Sub
What I tried to do was this way, but it completely doesn't work:
Private Sub Grid_CellValidating(sender As Object, e As DataGridViewCellValidatingEventArgs) Handles Grid.CellValidating
Dim newValue = e.FormattedValue.ToString.Trim '<---trim added
'change value of cell without trims
Dim aaa As DataGridViewCell = CType(sender, DataGridView).Rows(e.RowIndex).Cells(e.ColumnIndex)
aaa.Value = newValue
If Not Grid.Rows(e.RowIndex).IsNewRow Then 'And Not e.RowIndex = Grid.NewRowIndex - 1 Then
Select Case e.ColumnIndex
Case 1 'Name
If String.IsNullOrEmpty(newValue) Then
e.Cancel = True
Exit Select
End If
Case Else
End Select
End If
End Sub

That's the wrong event. CellValidating is for determining whether the contents of the cell is valid or not. CellValidated or CellLeave would be more suited to your situation.

In the CellValidating event this works for me.
//remove the event
grdDetails.CellValidating -= grdDetails_CellValidating;
//update current cell
grdDetails.CurrentCell.Value = "My New Value";
//force grid to commit update
grdDetails.EndEdit();
//rehook the event
grdDetails.CellValidating += grdDetails_CellValidating;

Related

Add CheckBox To DataGridView Cell Programmatically

I’m trying to add a CheckBox programmatically to a DataGridVew cell if the cell next to it has a value of “1”. I’m trying to do this as the rows are added
I’m hoping someone can help me out with the correct code here. I understand one of the lines of code is incorrect but I’ve put it in to illustrate what I'm trying to do.
Thanks in advance.
Private Sub Controls_DGV_RowsAdded(sender As Object, e As Windows.Forms.DataGridViewRowsAddedEventArgs) Handles Controls_DGV.RowsAdded
If Controls_DGV.Rows(e.RowIndex).Cells(2).Value = "1" Then
Controls_DGV.Rows(e.RowIndex).Cells(1).AddCheckBox ' THIS LINE IS INCORRECT
End If
End Sub
This is the same as #miguel except for the checking the value, in this case Option Strict is On as it should be.
Public Class Form1
Private Sub dataGridView1_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) _
Handles dataGridView1.RowsAdded
If CStr(dataGridView1.Rows(e.RowIndex).Cells(1).Value) <> "1" Then
dataGridView1.Rows(e.RowIndex).Cells(0).Value = False
dataGridView1.Rows(e.RowIndex).Cells(0) = New DataGridViewTextBoxCell()
dataGridView1.Rows(e.RowIndex).Cells(0).Value = ""
dataGridView1.Rows(e.RowIndex).Cells(0).ReadOnly = True
End If
End Sub
Private Sub AddRowsButton_Click(sender As Object, e As EventArgs) _
Handles AddRowsButton.Click
For index As Integer = 0 To 5
If CBool(index Mod 2) Then
dataGridView1.Rows.Add(False, "0")
Else
dataGridView1.Rows.Add(False, "1")
End If
Next
End Sub
End Class
The column number 1 that you want to display a checkbox should already be of type DataGridViewCheckBoxColumn and then if the value is not "1" you can transform the type of the cell for a DataGridViewTextBoxCell, so there is no checkbox and you can even put there some text if you want. Because you're using 3 columns, i'll try to do the same.
In your Form1_Load() you should have something like this if you are adding columns programmatically:
Dim ChkBox As New DataGridViewCheckBoxColumn
Controls_DGV.Columns.Add("TextBox1", "TextBox1")
Controls_DGV.Columns.Add(ChkBox)
Controls_DGV.Columns.Add("TextBox2", "TextBox2")
Then using your code it should be like this:
Private Sub Controls_DGV_RowsAdded(sender As Object, e As Windows.Forms.DataGridViewRowsAddedEventArgs) Handles Controls_DGV.RowsAdded
If Controls_DGV.Rows(e.RowIndex).Cells(2).Value <> "1" Then
' replace the checkbox cell by textbox cell
Controls_DGV.Rows(e.RowIndex).Cells(1) = New DataGridViewTextBoxCell()
Controls_DGV.Rows(e.RowIndex).Cells(1).Value = "(empty or some text)"
End If
End Sub

How to make cell readonly if the second cell is empty

The user should not be able to input a qty where the unit is empty in the datagridview.
To make it clear, I want to make the cell readonly = true if unit column is empty.
The colUOM4 is the name of the column that if the cell of this column is empty the olNewQty2 cell will be readonly.
I tried this code but it didn't work
Public Sub UnitEmpty()
For i As Integer = 0 To dgvCount.RowCount - 1
If dgvCount.Rows(i).Cells("colUOM4").Value Is Nothing Then
MessageBox.Show("It worked!")
dgvCount.Rows(i).Cells("colNewQty2").ReadOnly = True
Else
MessageBox.Show("Nothing happened!")
Exit For
End If
Next
End Sub
I'd recommend not using a loop because that will only set the state when you execute it and not react to any changes. I'd suggest working at the row and cell level, i.e. set the default state when a row is added and then react when a specific cell changes, e.g.
Private Sub DataGridView1_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles DataGridView1.RowsAdded
For i = e.RowIndex To e.RowIndex + e.RowCount - 1
'Make the first cell in each new row read-only by default.
DataGridView1(0, i).ReadOnly = True
Next
End Sub
Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
'Check whether the change is in the second column.
If e.RowIndex >= 0 AndAlso e.ColumnIndex = 1 Then
Dim row = DataGridView1.Rows(e.RowIndex)
'Make the first cell in the row read-only if and only if the second cell is empty.
row.Cells(0).ReadOnly = (row.Cells(1).Value Is Nothing)
End If
End Sub

Visual Basic- Loop to make listbox update as checkbox is checked

I'm having trouble having the listbox update as the checkbox is checked. I have a total of 8 "test_location" check boxes and I want the listbox to add items to "Steps_Queue_List" and store "1" in the "Test_Locations" array when the location is checked. Also want to clear the list when the checkbox is unchecked. This works so far but I would much prefer to learn how to make a loop for this:
Private Sub Location_CheckBox_1_CheckedChanged(sender As Object, e As EventArgs) Handles Location_CheckBox_1.CheckedChanged
If Location_CheckBox_1.Checked Then
Test_Locations(0) = 1
Steps_Queue_List.Items.Add("test for location" & 1, 1)
ElseIf Location_CheckBox_1.Checked = False Then
Test_Locations(0) = 0
Steps_Queue_List.Items.RemoveAt(0)
End If
End Sub
Private Sub Location_CheckBox_2_CheckedChanged(sender As Object, e As EventArgs) Handles Location_CheckBox_2.CheckedChanged
If Location_CheckBox_2.Checked Then
Test_Locations(1) = 1
Steps_Queue_List.Items.Add("test for location" & 2, 2)
ElseIf Location_CheckBox_2.Checked = False Then
Test_Locations(1) = 0
Steps_Queue_List.Items.RemoveAt(0)
End If
End Sub
Private Sub Location_CheckBox_3_CheckedChanged(sender As Object, e As EventArgs) Handles Location_CheckBox_3.CheckedChanged
If Location_CheckBox_3.Checked Then
Test_Locations(2) = 1
Steps_Queue_List.Items.Add("test for location" & 3, 3)
ElseIf Location_CheckBox_3.Checked = False Then
Test_Locations(2) = 0
Steps_Queue_List.Items.RemoveAt(0)
End If
End Sub
Thanks in advance.
You don't need a loop but you can just handle everything in a single method.
Set the property Tag of your Checkboxes to a progressive value starting from 1 to 8 matching the text value you want to be displayed in the listboxes.
Then setup an event handler that manages all the CheckBoxChanged events for all the CheckBox.
In this event handler retrieve the tag and use it to address the array index and the listbox to update
' Handle all Checkbox changed with the same handler
Private Sub OnCheckBoxChanged(sender As Object, e As EventArgs)
Handles Location_CheckBox_1.CheckedChanged,Location_CheckBox_2.CheckedChanged,
Location_CheckBox_3.CheckedChanged,Location_CheckBox_4.CheckedChanged,
Location_CheckBox_5.CheckedChanged,Location_CheckBox_6.CheckedChanged,
Location_CheckBox_7.CheckedChanged,Location_CheckBox_8.CheckedChanged
' Discover which checkbox has been clicked
Dim chk = DirectCast(sender, CheckBox)
' Now read the value of the Tag property of that checkbox
Dim idx = Convert.ToInt32(chk.Tag)
If chk.Checked Then
Test_Locations(idx - 1) = 1
Steps_Queue_List.Items.Add("test for location" & idx, idx)
Else
Test_Locations(idx - 1) = 0
Steps_Queue_List.Items.RemoveAt(0)
End If
End Sub

C1FlexGrid - Change "Highlight" behavior for a range of cells

My scenario:
I have a C1FlexGrid with Column and Row headers. Additionally, the first row of the C1FlexGrid is a boolean row (checkboxes). Based on the state of these checkboxes, the desired effect is a disabling of the cells for that column. The difficulty is that, due to the first row being a boolean data type that must not be disabled, using the .Cols(index).AllowEditing property is not an option. I have already successfully implemented a work-around using the BeforeEdit event handler, to prohibit changes to the cells in the column, along with a CellStyle to grey-out the cells when disabled.
Private Sub C1FlexGrid1_BeforeEdit(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.RowColEventArgs) Handles C1FlexGrid1.BeforeEdit
If e.Row > 1 And Me.C1FlexGrid1.Item(1, e.Col) = False Then e.Cancel = True
End Sub
Private Sub C1FlexGrid1_AfterEdit(ByVal sender As Object, ByVal e As C1.Win.C1FlexGrid.RowColEventArgs) Handles C1FlexGrid1.AfterEdit
If e.Row = 1 And Me.C1FlexGrid1.Item(1, e.Col) = False Then
Call FormatColAsDisabled(e.Col)
ElseIf e.Row = 1 And Me.C1FlexGrid1.Item(1, e.Col) = True Then
Call FormatColAsEnabled(e.Col)
End If
End Sub
Private Sub FormatColAsDisabled(ByVal col As Integer)
Dim color As C1.Win.C1FlexGrid.CellStyle
color = Me.C1FlexGrid1.Styles.Add("Gray")
color.BackColor = Drawing.Color.Gray
For row As Integer = 2 To Me.C1FlexGrid1.Rows.Count - 1
Me.C1FlexGrid1.SetCellStyle(row, col, color)
Next
End Sub
Private Sub FormatColAsEnabled(ByVal col As Integer)
For row As Integer = 2 To Me.C1FlexGrid1.Rows.Count - 1
Me.C1FlexGrid1.SetCellStyle(row, col, Me.C1FlexGrid1.Styles("Normal"))
Next
End Sub
My Question
Is there a way to modify the "Highlight" behavior for only these cells, such that the disabled cells do not highlight at all?
In order to avoid highlighting the disabled cells you can set Cancel EventArgs of BeforeSelChange event to true in case the new selected cell is a disabled one.
Private Sub C1FlexGrid1_BeforeSelChange(sender As Object, e As RangeEventArgs) Handles C1FlexGrid1.BeforeSelChange
If e.NewRange.r1 > 1 And Me.C1FlexGrid1.GetCellCheck(1, e.NewRange.c1) = CheckEnum.Unchecked Then
e.Cancel = True
End If
End Sub

Capturing value of DataGridView CheckBox in VB.Net

I have a datagridview (unbound). Fields are Name, Family Name and Phone No and a checkbox colum.
There are ten rows in that DataGridView.
There is an OK button
I need to get message of showing which rows user has checked. The message should appear when user clicks on the OK button. There could be several messages, checking each row one by one, in a loop.
I am not able to get this message. I tried following code in OK button :
Dim strCB As String = dgvChooseQs.Rows(0).Cells(3).Value.ToString
Cell(3) is my checkbox. Do not consider Rows(0), at the moment I am just checking value at row 0
Thanks for your help.
Furqan
Do not use the cell index. Your checkbox column must have a name so you should use it.
Otherwise, what you want to do would be something like this
For each oRow as DataGridViewRow in dgvChooseQs.Rows
If oRow.Cells("ColNamE").Value = True then
'do whatever you need to do.
End if
Next
If you feel you need to cast the column, then you can use CType, but the type is DataGridViewCheckBoxCell, not CheckBox.
You need to do something like this:
if ctype(dgvChooseQs.Rows(0).findcontrol("whateverYourCheckBoxIsNamed"), checkbox).checked then
'throw the message
end if
You may cast the cell value to Boolean, and then check it, as follows:
Dim RowIndex As Integer = ...
Dim ColumnIndex As Integer = ...
Dim IsTicked As Boolean = CBool(DataGridView1.Rows(RowIndex).Cells(ColumnIndex).Value)
If IsTicked Then
MessageBox.Show("You ticked the box.")
Else
MessageBox.Show("You cleared the box.")
End If
Only the third example worked for me but I had to add a Timer
Private Sub DgvElencoFile_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DgvElencoFile.CellClick
'Variabili gestione programma
Dim numerocolonnaSelezionata As Integer
Dim numeroColonnaSelezionataPerDowonload As Integer
Dim numeroRigaSelezionata As Integer
numeroRigaSelezionata = e.RowIndex
NumerocolonnaSelezionata = e.ColumnIndex
If NumeroRigaSelezionata < 0 Then
ClaFunzSgnSon.SegnaleSonoro(ClaFunzSgnSon.EnTipoSgnSon.ErroreImpostazioneDati)
GoTo FineSubFunz
End If
numeroColonnaSelezionataPerDowonload = -1
If DgvElencoFile.Rows(numeroRigaSelezionata).Cells(ClnDownLoad.Name).Selected Then numeroColonnaSelezionataPerDowonload = numerocolonnaSelezionata
If numeroColonnaSelezionataPerDowonload >= 0 Then
TimVisCheckDownLoad.Start()
End If
FineSubFunz:
End Sub
Private Sub TimVisCheckDownLoad_Tick(sender As Object, e As EventArgs) Handles TimVisCheckDownLoad.Tick
TimVisCheckDownLoad.Stop()
Dim isTickedOn = CBool(DirectCast(DgvElencoFile.CurrentCell, DataGridViewCheckBoxCell).EditingCellFormattedValue)
If isTickedOn Then
MessageBox.Show("You ticked the box.")
Else
MessageBox.Show("You cleared the box.")
End If
End Sub
I found a simple solution.
Just change the cell focus after click on cell.
Private Sub DGV_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGV.CellContentClick
If e.ColumnIndex = "Here checkbox column id or name" Then
DGV.Item(e.ColumnIndex, e.RowIndex + 1).Selected = True
'Here your code
MsgBox DGV.Item(e.ColumnIndex, e.RowIndex).Value
End If
End Sub
Don't forget to check if the column of your (ckeckbox + 1) index exist.
Set type of grid in dataGridView to 'DataGridViewCheckBoxXColumn' instead of DataGridViewCheckBoxColumn.
all problems will be solved
The post is old but it can help in need:
You have these three properties after casting your cell:
Private Sub YourDataGridView_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles YourDataGridView.CellMouseClick
Dim b, b1, b2 As Boolean
b = DirectCast(YourDataGridView.CurrentCell, DataGridViewCheckBoxCell).EditingCellValueChanged
b1 = CBool(DirectCast(YourDataGridView.CurrentCell, DataGridViewCheckBoxCell).EditingCellFormattedValue)
b2 = CBool(DirectCast(YourDataGridView.CurrentCell, DataGridViewCheckBoxCell).EditedFormattedValue)
End Sub
it's a long time since this question was sent, but can be useful this answer to anybody with the same issue. In my case, I used (I'm using your notation):
dgvChooseQs.Item(6, vCont).State
where 6 is the checkbox column number, in my case column 6. vCont is an iteration counter in a FOR NEXT loop. If State equals 32, checkbox was checked, else State will be zero. I hope this can be of help.