CurrentRow in Datagridview changed before Validating by RowHeaderClick. Can i stop this? - vb.net

I have my current validation of the entered data in the DataGridView located in the RowValidating event. This is working fine for every scenario so far, besides the User clicking the Row Header.
In this case the CurrentRow will be set to nothing even before the RowValidating event triggers. Alot of my methods that are triggered in the case of the data validation are using the currentRow to access data from the DataGridView.
Is there a way to fix this issure without changing the usage of currentRow?

Related

Excel VBA Userform Global Counter

I have created a VBA UserForm whose purpose is to allow the user to update records held in that Workbook. On Initialization, the UserForm populates with certain cell values in various text boxes, the user is then asked to add certain information in other text boxes, and on clicking the 'Next' button, the new information is added to the data table and the next entry populates the UserForm.
I am currently achieving this by keeping a count of the current row (currentRow) and once the 'Next' button is clicked, currentRow = currentRow + 1. This works fine.
My problem now is that I need to show a different UserForm if the value of a specific cell is different, for example:
If Range(Cells(currentRow, 3).Address).Value = "Planning" Then
PlanningUserForm.Show
Else
... rest of code ...
This works, but I am struggling to maintain the counter once this new PlanningUserForm is initialized. I need it to know the current value of currentRow so that it can display the correct cell values in its text boxes.
I have declared the variable currentRow as Public, but it doesn't seem to carry over the value into the new userform. Is this possible? Or am I asking too much of Excel?
Many thanks
Matt
If you have declared currentRow as public, then in PlanningUserForm you can access the currentRow value as UserForm1.currentRow where UserForm1 is the userform where you have declared currentRow as Public
You can always use the registry. It can be used to many other things too in the future.
SaveSetting "Your macro", "Values", "CurrentRow", currentRow
Now the currentRow is saved in your registry.
Now in your PlanningUserForm:
currentRow = GetSetting("Your macro", "Values", "CurrentRow")
and you got the saved value from your registry.
I have bad experiences with global variables, that is why I suggest registry.

VB.Net ComboBox (as Dropdown) not translating text to DisplayMember with Databinding

I inherited a fairly large project at work that is undocumented and written in VB (originally started pre .NET, ended around .NET 2). I'm in the process of updating / refreshing a lot of the code, but have run into an annoying issue that I haven't found the solution for yet. This system utilizes a UI, a Web Service, and a SQL DB.
Problem: I have a Databound Combobox (originally set to DropDownList - I'm changing it to DropDown, which is what started this mess - going back isn't an option) that is tied to a DataSet that comes from a Web Service. When a user types in the item they want manually, the data from the text field doesn't seem to associate itself with the DisplayMember, which forces the WS/SQL query to fail (it is sent a blank value when it's expecting a ValueMember). If the user types in a partial selection and then chooses the value they want from the DisplayMember list using the arrow keys or tab, the query goes off without a problem.
My Question: How do I get the text field to translate to the DisplayMember which will then properly tie itself to the ValueMember which will then allow the query to execute correctly? Sorry for making this sound complicated or convoluted; I'm sure the answer is easy and I'm just glazing over it.
The relevant bit of code is:
With cmbDID
If dtsLU.Tables.Contains(reqTable) = True Then
.DataSource = dtsLU.Tables(reqTable)
.DisplayMember = "zip"
.ValueMember = "gridID"
End If
End With
cmbDID.DataBindings.Clear()
cmbDID.DataBindings.Add("SelectedValue", dtsData, strDT & ".gridID")
I've tried changing "SelectedValue" to "Text", which almost works - but it directly translates to gridID and skips zip which ends up with an incorrect Web Service response since the zip and gridID field values are not synced (zip (DisplayMember) may be 5123 while gridID (ValueMember) may be 6047). I've tried changing "SelectedValue" to "SelectedIndex", and that got me no where.
Any help is greatly appreciated.
EDIT
To add some clarification to the process, the below pseudo code / description is roughly what happens. I could post the whole module, but I feel that would just muddy the whole question even more.
Private Sub A
FormAlpha is created with 1 ComboBox in the form of a DropDown
This DropDown is populated with a DataSet
DataBinding with a blank DataSet is added to the control to keep track of the users input
End Sub
lblSubmit_Click event is triggered on FormAlpha by the user after they have populated the DropDown with their data. lblSubmit_Click calls Private Sub Submit
Private Sub Submit
BindingContext(DropDown DataSet, tableName).EndCurrentEdit() is called
DataSet.HasChanges() is processed
If changes are present, changes are processed
HERE lies the problem
If the user has manually typed in the DropDown field, but not hit an arrow key or tab, then the DataSet registers a change, but returns a null value in all fields - it knows something was entered, but that data apparently didn't pass through the DataSet for the ComboBox (ListItems or SelectedIndex didn't change / fire I'm guessing). If the user selects the item with the arrow keys, the DataSet has the proper input (I'm assuming the Data was validated by the control at this point).
If the processed data is good, a value is entered into the database
If the processed data is bad (empty), an error is returned
End Sub
If the above can't be solved with what I've provided, but someone still knows a better way to handle this type of situation, I'm all ears. Rewriting the module isn't ideal, but fixing this problem is a necessity.
Alright, while this fix may not be ideal, it is a fix none the less.
The bare bones problem was that the text value of the DropDown wasn't causing the data to actually affect the SelectedIndex / SelectedValue of the control unless you interacted with it using the arrow keys or a mouse click. So, while the DropDown would read "1234", in reality the control saw "".
The fix I have in place for this is simply calling comboBox.text = comboBox.text whenever the user hits the submit button.

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

Losing cell data when datagridview gets focus

I know I need to provide some code, but I'm not sure what I should show, so please suggest if you can.
I have a bound datagridview on a Windows form. After the form loads and the datagridview gains focus (on mouse click), the first row (and a specific column) loses it's data, changing the cell's state to dirty. It doesn't matter where I click to bring the dgv into focus, that row/column always goes blank. What event is firing that may trigger that loss of data?
Again, any suggestions as to what code to post would be great. I know that will help answer this question.
Edit #1
This code is an infinite loop, but I'm adding it in response to a comment:
Private Sub dgQCOrders_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles dgQCOrders.CellPainting
If e.RowIndex = 0 And e.ColumnIndex = 9 Then
If e.FormattedValue <> e.Value Then
MsgBox("Changed")
Else
MsgBox("Unchanged")
End If
End If
End Sub
Edit #2:
Private Sub dgQCOrders_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles dgQCOrders.CellPainting
If e.RowIndex = 0 And e.ColumnIndex = 9 Then
If e.FormattedValue <> e.Value Then
Me.txtTest.Text = "Changed"
Else
Me.txtTest.Text = "Unchanged"
End If
End If
End Sub
This test tells me that the new value is null, it is deleting that first record (which I already knew)--still don't know how to fix it!
Edit #3
More explanation:
Currently, the only event I'm handling is form_Load, which fills the dgv using the tableadapter for my (bound) dataset. I then bind the dgv to the binding source.
I know that this error only occurs when the dgv gains focus (I tested this by setting the focus to the dgv when the form loads). I have a series of checkboxes/listboxes/textboxes on this form as well that allows the user to filter the dgv dynamically (back-end, I filter the binding source). If I filter the dgv first, the same row and the same column (their indexes do not change) maintains it's value when I move the focus to the dgv. When I clear the filter, the same row and the same column, loses it's data again.
I did have the _CellStateChanged event firing after a user makes an edit. Currently, it is commented out so the data loss isn't reflected in my dataset.
Additionally, I have another dgv on a different form, bound the exact same way, with the _CellStateChanged event and everything fires and saves correctly. I have gone through the designer coding for both forms, I can't find any setting difference between the two.
I'm losing my mind over here! Any help is GREATLY appreciated!
I decided to recreate the form from scratch and this error is no longer occuring. I have compared the two sets of code and can't find one discrepancy between them. If anyone has this problem in the future, save time and recreate all of the objects related to your dgv.
Maybe I understand that statement within the focus cell is not saved in the database table if U save
this problem I solved
add blank textbox control to your form which contain dgv and named txtFocus
placed it behand dgv and use its properties send to back Or
Evoked by the bottom of the screen so do not show it
then
before save
white then :
txtFocus.Focus()
sendKeys.send("{F2}")
only in this case U can save the data inside last cell changed in dgv
best Reg
Ashraf

DataGridView detect changes not working as expected

I have a program that is going to load data into a DataGridView, where users can edit/add/delete data. When they close out of the form, if there are any changes made, it will ask if the user wants to save the changes to the database.
So I have a DataTable that I load and assign to the DataSource of the DataGridView. I can then make changes to the data within the table, and if I call the DataSet.Update method, it updates.
However, if I call the DataTable.GetChanges method and look to see the changes, I get nothing, unless I have tabbed/clicked/whatever off of the current row of the DataGridView (in which case .GetChanges works) This leads me to believe that the changes are not committing to the DataTable unless the row loses focus.
So, is there a way to check to see if any cell is changed in a DataGridView, or a way to commit those changes without tabbing off of the row?
Again, this fails me if I don't change the row in the GridView, but works otherwise. I want it to work in both situations.
Dim changedRows As New DataTable()
changedRows = dtInfo.GetChanges(DataRowState.Modified Or DataRowState.Added Or DataRowState.Deleted)
If Not changedRows Is Nothing Then
....
End If
You can call the Form.ValidateChildren method, this will validate and commit all controls in the form, including your DataGridView. This method returns false if there is a validation error.