DataGridViewRow Color Changes On DataView RowFilter - vb.net

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.

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

Can't get DataGridView cell BackColor property

I'm trying to retrieve the current color of a DataGridView cell while iterating through the Grid. I am explicitly setting the BackColor for both RowsDefaultCellStyle and AlternatingRowsDefaultCellStyle in the Form Load event.
I'm trying to get the cell BackColor per this question, however, at run time, while iterating through cells in a row, in the Immediate Window this: ?dgvemployees.Rows(rowIndex).Cells(i + 1).Style.BackColor.ToString returns "Color [Empty]" every time - even if I change the indexes to get another cell that I know has the default color set.
Am I missing something or not doing something right?
This page on the Cell Style says:
The DataGridView control displays its cells using the styles indicated
by the cell InheritedStyle property, which inherits styles from other
properties of type DataGridViewCellStyle. The styles specified through
the Style property override the styles specified through all other
cell-style properties, but do not necessarily indicate all the styles
that contribute to the cell's appearance.
Basically, you are trying to access the specific cell back color when it hasn't been set. Even though you have set the back color of the rows, it can be overridden at the cell level.
Thankfully, Microsoft has given us a nice way to find the inherited style of the cell, which will get you the grid-level setting for these cells (unless something further down the chain has overridden that).
?dgvemployees.Rows(1).Cells(2).InheritedStyle.BackColor.ToString()
If I had something else that could override this value and cause problems, then I think I'd be left doing a modulus on the row count to see if it was an alternating row or not.

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.

Why RowLeave fires before CellLeave/CellValidating?

I have an update statement under RowLeave event of my datagridview. Before I update it I need to validate the cell if there is an empty value. But whenever I moved the focus to another row, RowLeave is called first before CellLeave/CellValidating.
Is there another way of validating the cell when leaving a row?
Note: Leaving a cell in the same row is not a problem.
Well your app is acting as designed, see if you can listen to something in the nature of cellexitEditmode or cell validated (not entirely sure these are all there). Best practice is if the row represents and object that is bound say your row represents an order and your grid is bound to a collection of orders . the cell will be a property in an order you can validate on property changed.

figure out rowindex on a row I just inserted?

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.