How do you sort an unbound DataGridView filled from a DataTable with added rows? - vb.net

I am having some trouble with a sorting an unbound DataGridView. I am filling a DataTable from a StreamReader, and then manually transferring the items from the DataTable to the DataGridView. The AllowUserToAddRows property is set to true on the DataGridView.
This populates the DataGridView, without any trouble. I can sort the columns by clicking on the column headers without any issue. If I add a value to the first column in a new row, and then try to sort the column, I get an error message that shows: "Object must be of type String."
I have tried different ways of converting all of the cells in the column to the same datatype, but I cannot get around this issue. Am I missing something here?
In the form load event, I have the following code:
dgvStartingGrid.Columns(0).ValueType = GetType(Integer)
I also am making sure that the values from the StreamReader are Integer types before entering them in the DataGridView:
If IsNumeric(strColumnValue) Then
dtbFillGrid.Rows(intCurrentRow).Item("Starting Position") = strColumnValue
End If
I have also tried:
dtbFillGrid.Rows(intCurrentRow).Item("Starting Position") = CInt(strColumnValue)
What could cause this issue? I have verified that all of the cells in the column are of the same datatype, but it still gives me an error, and I am sure that it is this column that is the problem.
The other columns are of string type, and I do not have any issue sorting them by their column headers, unless I click the first column, and then the exception is thrown.

Right, after some testing I found this out.
Even though you have set your DataGridView column to be Integer it doesn't mean that it will be filled with Integers. Unless you alter the datatype of the DataTable the DataGridView is actually filled with strings. The sorting function on a DataGridView is not based on column type, it is based on the first value it finds. And since you that value is a string, you get an error when it reaches your typed value (which is an Integer).
So here is what you have to do.
dtbFillGrid.Columns.Item(0).DataType = GetType(Integer)
Where 0 is the column containing Integer.

Related

Question About Datagridview Format Styling

i want to Show Thousand Separator in Datagridview Column
So i added One Column in datagridview so i Run this code But It's not working with me
You need to explicitly specify the column's ValueType if you don't have a DataSource to bind (ex. DataTable) which is the source of the data types as well. Here, you need a column of a numeric type such as Decimal.
So, before you populate the grid or add new rows, do:
With DataGridView2.Columns(0)
.ValueType = GetType(Decimal)
.DefaultCellStyle.Format = "#,#.##"
End With
In case the control is bound to DataSource, make sure that the type of the data field/property in question is numeric.

Value Retrieve from Datagridview's Columns

I am working on VB in Visual Studio 2010. And I've seen errors of greatness in which when I double click on a line of datagridview, I get the values of its columns in such a way.
Datagridview1.SelectedRows(0).Cells(1).Value
But the most surprising thing is that with this same code I get the values ​​of different columns each time without changing the index value in Cells(). I also put the name of the column inside the Cells(), but I did not get any value from this too.
Datagridview1.SelectedRows(0).Cells("name").Value
And the first column of this datagridview Cells(0) always returns the null value itself. I do not know how.
I have also used some column formating. like
With Datagridview1
.ColumnCount =2
.Columns(0).HeaderText ="Name"
.Columns(0).DataPropertyName = "pname"
.Columns(0).Width =100
.Column(1).HeaderText = "Son of"
.Column(1). DataPropertyName = "fname"
The big problem here is that it gives value to different columns each time with a single code
Is there any solution available for this?

Can't clear a DataGridView combobox without 100s of errors

I'm using VB.NET to make a stand-alone executable containing an unbounded DataGridView.
One of its columns is a combobox. I add rows to the combobox with some simple code
like this:
For r As Int16 = 0 To eachLine.GetUpperBound(0)
Dim dgvcbc As DataGridViewComboBoxColumn = grd.Columns(col)
' Errors: dgvcbc.Items.Clear()
dgvcbc.Items.Add(eachLine(r))
Next r
Works great the first time, but when I try to clear it, in order to add some different
items in the combobox, I get this error 100s of times:
> DataGridViewComboBoxCell value is not valid
Any ideas on how to fix this and why it occurs?
The issue is that, if you clear the Items in that column, every cell in that column becomes invalid. Every value in that column has to match one of the items in the drop-down list and, if there's no items, no value can be valid. It doesn't make sense to clear the drop-down list. You must leave at least the items that match the values in the cells of that column.

vb.net change value of a cell in a databound datagridview

I have a datagridview that has been populated from a datatable using the datasource property. I need to change the value of a cell without affecting the database. So far I could only find that I have to first change the databound item but no information about how to do that. Besides, I don't want to change the databound item.
The reason for wanting to do this is that I have a list of records with a start and end time and there is a computed field that gives the difference in seconds. I need to change the value of the computed field and change the height of the row accordingly, that is, the height of each row is proportional to the duration it represents. Changes are done from a text box which increments quickly if the "increase" button is kept down and therefore I cannot change the database with each increment. Rather I would change the value in the table frequently and update the database once the increments stops.
I have tried updating the datagridview directly using this code:
dgvTasks.Rows(SelectedRowIndex).Cells(5).Value = DateAdd(DateInterval.Minute, DateDiff(DateInterval.Minute, CDate("00:00:00"), CDate(txtDuration.Text & ":00")), dgvTasks.Rows(SelectedRowIndex).Cells(4).Value)
But receive the error:
System.Data.ReadOnlyException: Column 'Column1' is read only.
I also tried updating the datatable, and allowing the calculated column to update:
dtblTasks.Rows(SelectedRowIndex)(5) = DateAdd(DateInterval.Minute, DateDiff(DateInterval.Minute, CDate("00:00:00"), CDate(txtDuration.Text & ":00")), dtblTasks.Rows(SelectedRowIndex)(4))
dgvTasks.DataSource = dtblTasks
But the calculated value doesn't change.
I am also providing an additional calculated value (in the SQL) where I find the difference in minutes and the append a string literal to that:
( CAST ( DATEDIFF(MINUTE, Tasks.TaskStart, Tasks.TaskEnd) AS NVARCHAR(10) ) + ' mins') AS TaskDurationString
Is there a way to detach the grid from the datasource but still keep the data visible in the datagrid and manipulate it (without affecting the databound object)? Or perhaps some other approach to this problem?
Updating the calculated column in the DataTable should work - I've just tried it, and both when I edit one of the values that are part of the calculated value, and when I change the value in code, that column is recalculated and the grid UI updates.
One thing to check is that you are calculating the value correctly. You should be using the DataTable~ column [Expression` property]1. Something like this:
dt.Columns["FullName"].Expression = "FirstName + LastName";
Since it appears that you don't actually need to bind any of these values to the DataTable or persist them to the database, one possible solution is to do all of this in an unbound DataGridView calculation column.
To do that add a column using the designer, then in the cell validating event have something like this:
void dataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.Rows[e.RowIndex].Cells["TargetColumn"].Value = dataGridView1.Rows[e.RowIndex].Cells["FirstName"].Value.ToString() + dataGridView1.Rows[e.RowIndex].Cells["LastName"].Value.ToString();
dataGridView1.Rows[e.RowIndex].Height = dataGridView1.Rows[e.RowIndex].Cells["LastName"].Value.ToString().Length + dataGridView1.Rows[e.RowIndex].Cells["FullName"].Value.ToString().Length;
}

Add values to listbox from dataset - NullReferenceException error (VB.NET)

I'm trying to populate a single record from a dataset into a listbox. I can see that the dataset is populated with the expected value with the column header "PLI" in the dataset visualizer. I've tried to use the following command to populate the listbox with the value in the dataset:
lstExistingPLI.Items.Add(New ListItem(ds.Tables("PLI").ToString()))
I keep getting an unhandled NullReferenceException error. I've also tried using
lstExistingPLI.Items.Add(ds.Tables("PLI").ToString())
and getting the same error. Can anyone help me out with what I'm doing wrong? Thanks!
First i must admit that i don't know what causes your NullRefernceException.
Your ListBox lstExistingPLI might be null if you haven't initialized it. The DataSet ds might be null if it was not initialized. Maybe you have initialized it but you haven't added a DataTable with name "PLI" to it, then null would be returned from the DataTableCollection.Item property.
However, ds.Tables returns a DataTable. Why do you think that DataTable.ToString returns anything that could be added to a ListBox in a useful way? Do you want to add the fields of every DataRow?
(assuming that all is initialized correctly)
For Each row As DataRow In ds.Tables(0).Rows
'assuming that PLI is not the table but the field that you want to add to the ListBox'
lstExistingPLI.Items.Add(New ListItem(row.Field(Of String)("PLI")))
Next