figure out rowindex on a row I just inserted? - vb.net

I've got a vb project I am updating and it has a datagridview, a panel, and buttons along the bottom. The buttons control CRUD operations. The panel shows numerical up/downs and textboxes to represent the selected row.
I use some logic to keep track of current selected row and current row index for timer updates in the background. Upon delete I reset focus on the first row. Upon loading I set focus on first row. On update I keep current row focus.
Upon a good insert I would like to set the focus to the row I just inserted. But I do not know a way to determine what the rowindex value is for this freshly inserted row. My datatable which the datagridview uses is sorted on two id columns so it's not like the new entry will just jump to the bottom.
Any ideas on how I can implement this?

If you don't want to deal with the RowAdded event as Jay Riggs suggested, if you add it using a row object, as opposed to just Rows.Add, you should be able to pull that off of the row object after it's inserted.
Dim dgr As New DataGridViewRow()
DataGridView1.Rows.Add(dgr)
Me.DataGridView1.Rows.IndexOf(dgr)
This should also work for insert as well.

Check out the DataGridView RowAdded event; its DataGridViewRowsAddedEventArgs parameter includes the RowIndex property which gives you what you need.
The event fires everytime a row is added, so you'll have to either wire the event up when you want to check for added rows, or ignore the event when you don't care when a row is added (such as when your grid fills with data).

If you manually add rows to the DataGridView, then you can just use the return value from the Add method. Examples:
Dim newRowIndex As Integer = myDataGridView.Rows.Add()
myDataGridView.Rows(newRowIndex).Selected = True
No need to call IndexOf. If the DataGridView is bound to a DataSource then Jay Riggs' solution of using the RowsAdded event is the way to go.

Related

Button doesn't work after DataGridView Validating Event

I have a Form with a TabControl on it. On one of the TabPages is a DataGridView with a New- and Delete-Button below it. I also have a Validating-Event for the DataGridView. Inside the Event I do some checking. If the conditions are not met I do a simple:
e.Cancel = True
Return
But after that my Delete-Button isn't working anymore. Even if I set a Breakpoint right at the start of the Click-Event nothing is happening what could that be? I have set the CausesValidation to false on the Button.
Update
I need to handle both Events, because the Sum of this DataGridView is compared to another value. The Sum can't be smaller or bigger than the other Value. But the User can enter what he wants as long as at the End the Sum is correct. I can't do that in the CellValidating because as soon as I change a Value the Sum doesn't match anymore
Update
I have observerd the following Scenarios where it doesn't work:
I change Data in the DataGridView and then trigger the Validating-Event. It starts working again when I input correct Data and switch Tabs
I create a new Row, trigger the CellValidating-Event and after that the DGV Validating-Event

Detect when user has finished editing a cell in a datagridview

I am using DataGridView1.CellEndEdit to detect when the user finishes to edit a cell.
In my program i am doing this:
Filling a Datagridview with a binding source
Filtering with the bindingsource filter
order by the first column alphabetically
edit a cell
Write edited values in the database
The problem is: When I finish CellEndEdit is fired and the cell does this:
write new values to Datagridview
Refresh row order based on the new value of the cell and update the bindingsource filter
Fire CellEndEdit
For me this is a problem because I need to read the content of every cell of the row, in order to update the database and once it gets the new values it is moved to a unknown position OR hidden because it does not meet the filter criteria anymore and thus if I read the row it was before I get the values of a row that has nothing to do with the one I am looking for.
Is there a way to get the values of the entire row containing the cell i just edited from within the CellEndEdit sub?
Solved by adding a KeyUp event handler and storing each cell of the row in a variable on every keyup event.
The CellEndEdit event provides DataGridViewCellEventArgs arguments which contains the RowIndex.

DataGridViewRow Color Changes On DataView RowFilter

Goal
To differentiate different rows from each other based on a custom class object's properties. For example, if the object's available state is not available the row backcolor should be displayed in yellow. Similarly, if the object's deleted state is set to true, the row backcolor should be red.
Current Situation
I have a DataGridView that has it's DataSource set to a DataView. The DataView's Table is set to a DataTable filled with data by the custom class.
I created a method that sets the back colors correctly (tested and it works fine). However, this method is executed on the DataGridView1.RowsAdded event. For some reason, even if I have 20 rows that are added, it only goes through the event twice for the row index 0 and row index 1.
Problem
I need a DataGridView event that will fire my method every time a row is added or every time the RowFilter on my DataView changes. How can I go about doing this?
The best way to deal with custom row/cell style is to subscribe to the following events:
RowPrePaint
RowPostPaint
They are only raised when the row is displayed.

Is there a way to allow only unique values in a column of an Infragistics UltraWinGrid?

I'm using an Infragistics UltraWinGrid with a column of drop-down boxes. I don't want the user to be able to select the same value for multiple rows in that column. Is there a simple (or heck, I'd settle for advanced) way to do this?
I'm using VB.NET
-EDIT-
I tried setting a filter on the data source for the drop-down box. But when I did that, the values in the other boxes in that column started disappearing (not the values themselves, but the descriptions that they were supposed to represent, so instead of reading "Information", it just said "1"). All of the cells in a column refer to the same combo box, so if you filter out a value from the data source for one of them, you filter it out for all of them.
I'm currently trying to catch a CellChange event and check against all other currently-used values. If it was already used, I would put up a message saying as much and revert back to the old value. However, the value comes back as the previously-saved one, so... not helpful. About to see if I can use the "text" property.
Since you're using Infragistics, you could use an UltraDropDown which is bound to a DataTable (or something similiar) which you can add a "Selected" column in addition to a column holding the values you want to show.
As each value is selected (via AfterCellUpdate or AfterCellListCloseUp for instance), you could update the "Selected" column in that data source and use a column filter to only show items which haven't been marked as selected. That way as items are selected or removed, the contents of the drop-down would be automatically updated.
To clear the selected flag from the old value, you can use the BeforeCellUpdate event to access the cell's current value then perform a lookup on the data source bound to the UltraDropDown using that value to clear the flag.
Solved it:
The trick was to use BeforeCellUpdate whose BeforeCellUpdateEventArgs has a "NewValue" and a "Cancel" member. I just look through all of the items in the column to see if any of them match the new value. If one does, I notify the user and cancel the operation.
And that's it. Here's the code:
Private Sub myUltraWinGrid_BeforeCellUpdate(ByVal sender As Object, ByVal e As Infragistics.Win.UltraWinGrid.BeforeCellUpdateEventArgs) Handles myUltraWinGrid.BeforeCellUpdate
If e.Cell.Column.Key = "myColumn" Then
Dim newValue As Integer = CInt(e.NewValue)
For Each row As Infragistics.Win.UltraWinGrid.UltraGridRow In myUltraWinGrid.Rows
If row.Cells("myColumn") IsNot e.Cell _ 'So I'm not checking against the current cell
AndAlso CInt(row.Cells("myColumn").Value) = newValue Then
MsgBox("That value has already been used in this column")
e.Cancel = True
End If
Next
End If
End Sub

showing iteration through a DataGridView, updating the display/redraw

I have a DataGridView with a single column that currently displays a short list of items. When the user clicks a button to run an update, each row/cell is read and processing begins.
I would like to have the selection indicator move down the rows in the DataGridView as it completes processing of each record. How can I display the iteration of the DataGridView rows while the processing is underway? A redraw of the DataGridView or something.
This is a VB.net windows form, I know how to do this with AJAX I think, but how can I achieve this in a Windows form?
Thanks,
For each row As DataGridViewRow in myDataGridView.Rows
'Unselect previous row, then select current row
myDataGridView.ClearSelection()
row.Selected = True
myDataGridView.Refresh()
'Do processing here...
Next
This will select each row but won't scroll down if the current row is out of view. To scroll down automatically you can set the DataGridView FirstDisplayedScrollingRowIndex property.