Trying to move items from one to the other - vb.net

]I am having strange problem when i try to move items from one grid view to another using a bindingsource it adding in an extra blank row some reason
Private Sub btnMove_Click(sender As System.Object, e As System.EventArgs) Handles btnMove.Click
Dim bs As New BindingSource
Dim a As Integer
Dim removeList As List(Of infoRemoteFiles) = fileList
For a = 0 To grdAvailFiles.SelectedRows.Count
grdProcessFiles.Rows.Add(grdAvailFiles.Rows(a).Cells("filename").Value)
removeList.RemoveAll(Function(p As infoRemoteFiles) p.filename = grdAvailFiles.Rows(a).Cells("filename").Value)
Next
bs.DataSource = removeList
grdAvailFiles.DataSource = bs
End Sub
please see what i mean its the row below what I have selected I dont no where its comming from thanks

The extra blank row is added automatically if you have the AllowUserToAddRows property set to True on the DataGridView control.
From the documentation:
If the DataGridView is bound to data, the user is allowed to add rows if both this property and the data source's IBindingList.AllowNew property are set to true.
On a separate note, you shouldn't have to create anew binding source (for the source data grid). Instead, modify the collection that is already bound to the DataSource property.

Try:
For A = 0 To grdAvailFiles.SelectedRows.Count - 1
Note the minus 1, because you're starting from zero.

Related

How to get Design > Name property of DGV column from Header Text property

I am trying to go through un-checked items within a CheckedListBox1 and based on the values returned hide relevant columns within DataGridView1 but the issue is that the values displayed in CheckedListBox1 are the HeaderText property of DGV column and not the Name property which is required for hiding the column within DGV.
See below code:
For Each checked_item As Object In CheckedListBox1.Items
If Not CheckedListBox1.CheckedItems.Contains(checked_item) Then
DataGridView1.Columns("").Visible = False
End If
Next
Is there a way to retrieve "Name" property of DGV column when referencing the column's HeaderText property?
You don't need the column name to hide the column. You need the column. The name is just a means to get the column. The issue is the way you're populating your CheckedListBox. Displaying the HeaderText makes perfect sense, because that's what the user actually sees. What you should be doing is putting the columns themselves into the CheckedListBox and just displaying the HeaderText. That way, the items are the columns, e.g.
Dim columns = DataGridView1.Columns.Cast(Of DataGridViewColumn)().ToArray()
With CheckedListBox1
.DataSource = columns
.DisplayMember = NameOf(DataGridViewColumn.HeaderText)
End With
The code you posted then becomes this:
For i = 0 To CheckedListBox1.Items.Count - 1
Dim column = DirectCast(CheckedListBox1.Items(i), DataGridViewColumn)
column.Visible = CheckedListBox1.GetItemChecked(i)
Next
Note that you should generally set the DataSource last when binding but that doesn't seem to work with a CheckedListBox, which doesn't offically support data-binding. For that reason, the DataSource is set first.
EDIT:
I'm adding this after the comment was added to the question about the ItemCheck event and the checking of the items at startup. The key here is to not actually act on the event until the list has been initialised, i.e. all the items have been initially checked. One way to do that would be like so:
Private isLoaded As Boolean = False
Private Sub Form1_Load(...) Handles MyBase.Load
'Bind the data and check the items in the CheckedListBox here.
isLoaded = True
End Sub
Private Sub CheckedListBox1_ItemCheck(...) CheckedListBox1.ItemCheck
If isLoaded Then
'Act here.
End If
End Sub
The other way to is to prevent event being raised by not handling it while the initialisation is taking place. That can be done in a couple of ways but I'll leave that to you as an exercise if that's what you want to do.
As the ItemCheck event is raised before the state of an item changes, you will need to treat the current item differently to the other items. My loop above would become this:
For i = 0 To CheckedListBox1.Items.Count - 1
Dim column = DirectCast(CheckedListBox1.Items(i), DataGridViewColumn)
'For the item that is being checked/unchecked, use its new state.
'For other items, use their current state.
column.Visible = If(i = e.Index,
e.NewValue = CheckState.Checked,
CheckedListBox1.GetItemChecked(i))
Next
That said, if all items are initially checked and all columns are initially visible, it's only the current item that you need to care about, so there's no need for a loop at all:
Dim column = DirectCast(CheckedListBox1.Items(e.Index), DataGridViewColumn)
column.Visible = (e.NewValue = CheckState.Checked)
Try this:
For Each checked_item As Object In CheckedListBox1.Items
Dim oCol As DataGridViewColumn = DataGridView1.Columns _
.Cast(Of DataGridViewColumn)() _
.Where(Function(x) x.HeaderText = checked_item).SingleOrDefault()
If oCol IsNot Nothing Then oCol.Visible = _
Not CheckedListBox1.CheckedItems.Contains(checked_item)
Next
Note: System.Linq is required!
[EDIT]
this code is executed in the .ItemCheck event. When the form starts up
I loop through all available columns, populate CheckedBoxList1 and as
default they are un-checked but I want them checked as I want the
columns to be visible at start
If you would like to change the visibility of column of currently selected item in CheckListBox (in ItemCheck event), use this:
Dim oCol As DataGridViewColumn = DataGridView1.Columns _
.Cast(Of DataGridViewColumn)() _
.Where(Function(x) x.HeaderText = checked_item).SingleOrDefault()
If oCol IsNot Nothing Then oCol.Visible = _
Not CheckedListBox1.CheckedItems.Contains(CheckedListBox1.SelectedItem)
Do you see the difference?
The main difference is: there's no foreach loop ;)

MAX & MIN Value on GridView Column VB.NET

I am developing a small program to get the maximum of a specific column in a gridview (DevExpress), but I could not execute it as I wanted.
Can you support me in seeing where I have the error?
Dim cells() As GridCell = GridView2.GetSelectedCells()
Dim values As New List(Of Decimal)()
For i As Integer = 0 To GridView2.RowCount - 1
Dim value As Decimal = Convert.ToDecimal(GridView2.GetRowCellValue(cells(i).RowHandle, cells(i).Column))
values.Add(value)
Next i
values.Sort()
MsgBox(values.Max().ToString())
Regards.
With the built in DataGridView, the number of rows can be Rows.Count -2 because there is an extra row for the user to enter a new record. I have no idea if DevExpress works that way but it is worth a try.
For i As Integer = 0 To GridView2.RowCount - 2
If your GridView uses a DataTable as a DataSource, then the following code might help. If the DataTable is still available then just start with that. Otherwise extract it from the grid.
DataTable does not implement IEnumerable but there is an extension method to get the interface (.AsEnumerable).
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt = DirectCast(DataGridView1.DataSource, DataTable)
Dim maxValue = Aggregate r In dt.AsEnumerable
Into MaxID = Max(r("ID")) '"ID" is the name of a column
MessageBox.Show(maxValue.ToString)
End Sub
Same thing for Min just change Max to Min.
Calculate Total Summary for Grid Column
gridView1.Columns("UnitsInStock").Summary.Add(DevExpress.Data.SummaryItemType.Average, "UnitsInStock", "Avg={0:n2}")
gridView1.Columns("UnitsInStock").Summary.Add(DevExpress.Data.SummaryItemType.Sum, "UnitsInStock", "Sum={0}")
Dim item As GridColumnSummaryItem = New GridColumnSummaryItem(DevExpress.Data.SummaryItemType.Max, "UnitsInStock", "Max={0}")
gridView1.Columns("UnitsInStock").Summary.Add(item)
Devexpress Documentation:
https://documentation.devexpress.com/WindowsForms/DevExpress.XtraGrid.Columns.GridColumn.Summary.property
https://documentation.devexpress.com/WindowsForms/9677/Controls-and-Libraries/Data-Grid/Examples/Summaries/How-to-Calculate-Single-Total-Summary-for-Grid-s-Column

How to set a custom DataGridViewColumn for an autogenerated column?

I've downloaded some code relative to establishing a column on my
DataGridView which allows me to use the DateTimePicker.
So far so good. If I add a column using Dim col as new CalendarColumn the grid works great.
However...I need to assign an existing column ...
from a database. How do I make datagridview1.columns("NoteDate") my
CalendarColumn?
Also I tried the following codes
Dim col As New CalendarColumn()
col.DataPropertyName = "NoteDate"
col.HeaderText = "Headertext"
Dim loc As Integer =
dataGridView1.Columns.IndexOf(dataGridView1.Columns("NoteDate"))
dataGridView1.Columns.RemoveAt(loc)
dataGridView1.Columns.Insert(loc, col)
I thought it solve my problems but it only work once if I refresehed my datagrid the NoteDate is populated with values from the database but I cannot make the calendar column working again
Any suggestions?
When you say "an existing column from a database", I guess you mean than you have AutoGenerateColumns property of DataGridView set to True. In this case, you can use the ColumnAdded event and define the CellTemplate for the column.
The example above supposes that your custom DataGridViewTextBoxCell class is named "CalendarCell".
Private Sub dataGridView1_ColumnAdded(sender As Object, e As DataGridViewColumnEventArgs) Handles dataGridView1.ColumnAdded
If e.Column.DataPropertyName = "NoteDate" Then ' for your specific column
e.Column.CellTemplate = New CalendarCell()
End If
End Sub

How to fill combobox column in DataGridView in vb.net?

My DataGridView contains three columns, column types are checkbox, textbox and combobox.
How can I load a row's combobox when the checkbox in the same row is checked?
maybe this could help (example)
Dim dgvcc As DataGridViewComboBoxCell
dgvcc = DataGridView1.Rows(2).Cells(0)
dgvcc.Items.Add("comboitem1")
dgvcc.Items.Add("comboitem2")
source
You can bind like this -
Dim dtRange As DataTable = GetQueryTable("select range_name from table_name")
Me.grid_column_name.ValueMember = "range_name"
Me.grid_column_name.DisplayMember = "range_name"
Me.grid_column_name.DataSource = dtRange
and this will bind table record to complete DataGridViewColumn of DataGridView.
Another approach is to filter the Datasource (in my case a dataset) when you edit another column that needs to filter the combobox column. I find this super easy to code and efficient.
Private Sub DGV_CellBeginEdit(sender As Object, e As DataGridViewCellCancelEventArgs) Handles DGV.CellBeginEdit
Select Case e.Column.Name
Case "TabID"
Me.FormTabBindingSource.RemoveFilter()
Me.FormTabBindingSource.Filter = String.Format("FormID = {0}", DGV.Rows(e.RowIndex).Cells("FormID").Value)
End Select
End Sub

Error trying to rebind DataSource to DataGridViewComboBoxCell?

I have a DataGridView with two DataGridViewComboBoxColumns. I want to use the selected item in the first column to trigger a re-population of the items in the second column, on a per-row basis.
Here's the code I have so far. "addlInfoParentCat" identifies the first column, and currentRow.Cells.Item(1) is the DataGridViewComboBoxCell that I want to re-populate. ExtEventAdditionalInfoType is a type I defined that contains the string/value pairs.
Private Sub dgvAdditionalInfo_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvAdditionalInfo.CellValueChanged
Dim currentCell As DataGridViewCell
currentCell = Me.dgvAdditionalInfo.CurrentCell
If Not currentCell Is Nothing Then
If currentCell.OwningColumn.DataPropertyName = "addlInfoParentCat" Then
Dim parentTypeID As Integer = currentCell.Value
Dim currentRow As DataGridViewRow = Me.dgvAdditionalInfo.CurrentRow
Dim subtypeCell As DataGridViewComboBoxCell = currentRow.Cells.Item(1)
Dim theChildren As New List(Of ExtEventAdditionalInfoType)
theChildren = Custom_ExtEventAdditionalInfoType.GetChildrenOfThisParentOrderByTypeName(parentTypeID)
subtypeCell.DataSource = Nothing
subtypeCell.DataSource = theChildren
subtypeCell.DisplayMember = "ExtEventAdditionalInfoTypeDescr"
subtypeCell.ValueMember = "ID_ExtEventAdditionalInfoType"
End If
End If
End Sub
Basically what I see is that the binding works great the first time around. When I select a item in the first column, it populates the items correctly in the second. I can add rows to the DataGridView and repeat the process.
The problem comes when I try to change the first-column item after the second column has already been bound. I get an endless string of dialog boxes with the following:
System.ArgumentException: DataGridViewComboBoxCell value is not valid.
Any idea why this is happening? Thanks in advance!
UPDATE CodeByMoonlight's suggestion appears to work.
I clear the DataGridViewComboBoxCell's value before re-binding:
....
subtypeCell.DataSource = Nothing
subtypeCell.Value = Nothing 'here's the change
subtypeCell.DataSource = theChildren
....
Well, it looks like as soon as you remodify the first combo's value, you're invalidating the binding and datasource you used to populate the second combo, causing all the errors.