WinForms binding - vb.net

I have some controls bound to a BindingSource control.
I want to do a calculation when the value changes in one control and set the result on another control.
Do I update the textbox the property is bound to or do I update the underlying entity which would update the control anyway (I hope)?
When I change combobox A (OnPropertyChange) textbox B is updated with the new calculated result. This works fine, but I have noticed that when I leave combobox A it reverts back to its original value. What is going on here!
Private Sub ComboBoxEditCostCode_EditValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBoxEditCostCode.EditValueChanged
Select Case ComboBoxEditCostCode.EditValue
Case "7"
CType(TransactionEntityBindingSource.Current, TblTransactionsEntity).Qbdescription = "7-is here"
Case "2"
CType(TransactionEntityBindingSource.Current, TblTransactionsEntity).Qbdescription = "2-is here"
Case Else
CType(TransactionEntityBindingSource.Current, TblTransactionsEntity).Qbdescription = "7-is here"
End Select
End Sub

if we bind a control to a source, then if the source changes, we can make the its value automatically reflected in the control. About the problem you are facing, it would be better if you show the code snippet.

Tell more about your changing, how second text box is bound?
You have to change your initial data instead of changing textbox b value.
Also when textbox A loses it focus raises EndEdit event and I think binding mechanism refreshes value in textbox B.
You can control on which action editing is done when you setting your binding to textboxes.

as a rule of thumb, if you are using a binding source you always CRUD the data through it. Don't forget to call BindingSource.EndEdit when you are done, hope this helps

Related

DataGridView column names not accessable after adding new column

I'm trying to add a column to an existing data grid view and I'm getting an error after adding a column. Referencing the column by it's name throws a null reference exception and after some debugging I noticed, the names of the columns have disappeared after adding a column.
Before I add a new column you can see in the first image, that each column has a name. After I add a column, the second image shows the names of each column as being empty. No code was changed and the column being added to the data grid view was the only change.
DGV_List.Columns("Vendor").Visible = CB_Vendor.Checked
I've found one or two ways to get around this, such as directly referencing the column like Me.Vendor.Visible. But I'm curious why adding a new column could cause existing working code to fail.
Edit adding code
The code is really long so I'm linking it on pastebin. Also note the column was added manually and not with code. Nothing besides the form designer code changed when the error started.
Code that has null reference error after adding column
https://pastebin.com/inZCT27A
Form designer before adding column
https://pastebin.com/2nv33pA3
Form design after adding column
https://pastebin.com/7ULHpNwE
I am pretty sure that the problem lies in “WHEN” the CheckBoxs CheckedChanged event is fired.
If the check box is set to True in the designer, then, its CheckedChanged event will get fired "once" in the InitializeComponent method.
If the check box is set to False in the designer, then its CheckedChanged event will NOT be fired in the InitializeComponent method.
Because the check box is set to true in the designer, then "sometime" in the InitializeComponent method the CheckChanged event is going to get fired and when it does... you can NOT guarantee that the grid has been fully initialized.
Checking “anything” relating to the grid “before” it has been fully initialized is risky. This would easily explain some of the inconsistencies I and I am sure you have seen.
The main point would be that, because you DO want to reference the grid in the CheckChanged event of the check boxes, AND you DO want to have the check box initially checked, then you need to make sure the grid is fully initialized "before" you set the check box to True/False (checked/unchecked).
One way to do this is from the “designer”, UNCHECK the check boxes that reference the grid. This will prevent the CheckedChanged event from firing in the InitializeComponent method when the grid may not be fully initialized.
Then in the forms Load event, where we can pretty much guarantee the grid is initialized fully, set the check boxes state to checked. Then the CheckedChanged event can fire without errors. …
Private Sub MCRI_Checker_Form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CB_Description.Checked = True
CB_Drawing.Checked = True
CB_FilePath.Checked = True
CB_Quantity.Checked = True
CB_ReqType.Checked = True
CB_Vendor.Checked = True
CB_WhereUsed.Checked = True
End Sub
I hope this helps and makes sense.

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

Combobox not updating bindtable fields in VB

I have a combobox that is of type dropdown, i.e. allows user to either select something from the list or to type in a new value. Based on this combo value, other values are selected in the form automatically as they are databound.
Customer_ID is the field that needs to be picked or typed in, and based on it Customer first name and second name are updated in the form automatically. This works fine if I pick some value from dropdown, lets say Customer Id = 1111.
Now in place of picking, if i type in this value and press tab, no udpate happens on the Name fields. Please suggest what am I missing here.
I think the best you are going to do with the standard ComboBox is to handle the Leave event, or possibly the TextChanged event. I did some experimenting and typing in a value does not add to the list, it just changes the Text property. It doesn't even change the value of the item you typed over. And, it doesn't fire SelectedItem or IndexChanged events.
So if you handle the Leave event, you have a place to do your lookup when someone tabs off the ComboBox. But the item won't get added to the list.
If you need functionality not provided in the default control, you could redesign your UI with perhaps a TextBox and Button that add an item. Or, you could look for third party implementations of ComboBox controls that would have more functionality.
Private Sub ComboBox1_Leave(sender As Object, e As EventArgs) Handles ComboBox1.Leave
Dim theCB As ComboBox = DirectCast(sender, ComboBox)
DoLookup(theCB.Text)
End Sub

Binding combobox selected value to a specific column of current row (not a datagridview)

I have a database that I am using in a VB 2010 project. What I did was removed a textbox for a database field that I dragged onto the form and replaced it with a combobox. The field name was orderstatus.
The problem is this: since I removed the textbox field from the form, I can't seem to bind the combobox value to the field in the active record. In other words, orderstatus textbox doesn't exist anymore. I want to let the user pick a status from the combobox and store that value to orderstatus so that it's saved to the current record my database.
I want to do something like this:
Private Sub Button16_Click_1(sender As System.Object, e As System.EventArgs) Handles Button16.Click
orderstatus = ComboBox13.SelectedValue
Me.OrdersDataSet.orders(0).orderstatus = orderstatus
Me.Validate()
Me.OrdersBindingSource.EndEdit()
Me.TableAdapterManager12.UpdateAll(Me.OrdersDataSet)
End Sub
but it doesn't like my second line where I try to assign the value to the field, saying there is no row 0. All I want to do is put the selected value of the combobox into the orderstatus field of the record being created (or updated).
I've also tried using:
Me.OrdersDataSet.orders.orderstatusColumn = orderstatus
and I get a message saying that the property of the column is ReadOnly. I'm not sure how that's possible because I configured the dataset to update, etc.
I should probably mention that I'm not using a datagridview but a details view, if that makes a difference. I've seen some talk about how to do this using datagridview and don't know if that would work in my case.
What am I doing wrong? What should I use to update just the column I want in the current row?
Ugh, turns out I had forgot to set the databinding properties of the field in question to save directly to the binding source and also select the selecteditem to bind. It was right there and I didn't realize. Ya live and learn. :)

Make a button have multiple uses

okay... How do I explain this without being totally confusing?... Alright, I have this form that has MenuScripts (top-levels and second-levels). The problem that I am having is one of the second-levels is "Add" which brings you to another form when clicked. This other form has a button ("Record") and text boxes. This other form allows the user to input data and when the record button is clicked, the inputted data is written into a text file. Ok, so back to the first form. Another second-level MenuScript is "Update" which also brings the user to the other form; but first, the user has to click an item within a listbox to proceed. How do I get the data from the selected item to appear in the appropriate textboxes and how do I get the record button to update data instead of being confused and thinking it is only a add-data button?
Is there a way to use an "if" statement to say something like "if mnuAdd is clicked then" "elseif mnuUpdate is clicked then". Would something like that work for giving the record button multiple uses?
Also, if someone can give me some pointers on making sure the user selects an item within the listbox would definitely be a plus! Thanks, guys!
Unfortunately, I cannot add images since my reputation is too low.
Here is a visual representation of my ultimate goal
Easiest way: before displaying the second form set it's Tag property to something distinct – say "Add" or "Update" – depending on which menu item is selected. Then you just test the Tag value in the button's Click event and proceed accordingly.
As for determining whether a list item is selected: well if there isn't the ListBox's SelectedIndex property will be set to -1.
You need to put a public property on the second form (Details) which specifies which mode it is in. For instance, you could create a mode enumeration like this:
Public Enum EntryModes
AddBook
UpdateBook
End Enum
Then, define a public mode property on the second form, like this:
Public Property EntryMode As EntryModes
Get
Return _entryMode
End Get
Set(ByVal value As EntryMode)
_entryMode = value
End Set
End Property
Private _entryMode As EntryMode
Then, when you show the second form from the menu, just set the property first, before showing it:
Private Sub mnuAdd_Click(sender As Object, e As EventArgs)
Dim dialog As New DetailsDialog()
dialog.EntryMode = EntryModes.AddBook
dialog.ShowDialog()
End Sub
Private Sub mnuUpdate_Click(sender As Object, e As EventArgs)
Dim dialog As New DetailsDialog()
dialog.EntryMode = EntryModes.UpdateBook
dialog.BookToUpdate = ListBox1.SelectedItem
dialog.ShowDialog()
End Sub
As you can see, in the Upate menu click, I also added a line that passes the information for which book should be updated.