TextBox.Text Changing Unexpectedly - c#

I'm updating a LINQ object prior to SubmitChanges. The values of the object's properties are being taken from a series of TextBoxes.
When I read in one specific TextBox, another TextBox changes its value with no apparent cause.
//...
loc.Lattitude = txtLocLat.Text; // txtLocLong.Text changes to previous value
loc.Longitude = txtLocLong.Text; // Which is now the previous value
dc.SubmitChanges();
// ...
As a result, loc.Longitude never gets updated with the user input. Why would it do this?
The TextBoxes have no databindings
The TextBoxes have no events defined
Breakpointing into the first line merely steps through the DataContext's loc.Lattitude setter.

Try putting a breakpoint on the txtLocLong TextChanged event and see if the stack trace is any help.

Related

How do I update object data after editing a DataGridView cell when the DataGridView is bound to a DataTable?

first time poster. Sorry if the code I post is poorly formatted or hard to interpret.
I am trying to figure out how to update the object property data I have in a class object "AnalogInput" located in a DataGridView that has it's DataSource property set to a DataTable. So, after I edit a cell in the DataGridView, I would like to send that updated value back to the DataTable and thus the AnalogInput property value.
I am trying to do this in a WinForms application.
Below is some code that sums up pretty much where I am at right now:
Create a DataGridView to display some select and editable AnalogInput properties
DataGridView dataGridView_AnalogPoints = new dataGridView();
Create a new instance of a class object "AnalogInput" with public string properties initialized as shown below
AnalogInput point = new AnalogInput() { Name = "Something", Address = "2", Minimum = "-32768", Maximum = "32767"};
Create a new DataTable to hold the desired properties of the object "AnalogInput"
DataTable analogPoints = new DataTable();
Add the columns to the DataTable
analogPoints.Columns.Add("Name");
analogPoints.Columns.Add("Address");
analogPoints.Columns.Add("Minimum");
analogPoints.Columns.Add("Maximum");
Add the object data into a new row in the DataTable analogPoints
analogPoints.Rows.Add(point.Name, point.Address, point.Minimum, point.Maximum);
Set the source of the dataGridView.
dataGridView_AnalogPoints.DataSource = analogPoints;
So, once I edit the DataGridView cell that contains the object data from the DataSource as DataTable, which gets it's data from the AnalogInput object, how can I update it to the newly entered value from the DataGridView? I feel like I'm pretty far off from achieving this.
I only have about 9 months worth of experience working with C# and WinForms so I apologize if my code looks messy. I'm also not sure what I should be searching for specifically to solve this.
I don't think you are very far from achieving your intended behaviour. The DataGridView class has a wonderful event called CellValueChanged. In case you don't know what events are, think of them like a case that a developer believes may happen (like value changed, control clicked, mouse hover etc.) that s/he wants to allow you to subscribe methods to be invoked whenever the case occurs.
What you wish to do is run a function whenever a value of a cell was changed. To subscribe a method to an event you need to write the following line of code:
objectInstanceName.EventName += MethodName; // subscribes a method to be invoked when event occurs
This is not necessarily relevant for your case here, but if you no longer want a method that you have previously subscribed to be invoked, you can unsubscribe it with the following line of code:
objectInstanceName.EventName -= MethodName; // unsubscribes a method to cancel it from being invoked when event occurs
You can also subscribe as many methods as you wish for an event. Note that every event expects the methods subscribed to it have a specified return type, amount of parameters and their type (those are specified by a thing called a delegate).
In order to create a method that matches the expected return type and parameters you can press TAB twice right after typing the += and visual studio will automatically generate a method for you, or write the method's name and then hover on it with the mouse, open the suggestions menu and click "Generate method".
The CellValueChanged event "wants" its subscribed methods to have the following parameters (their names don't matter, what matters is their order and type):
object sender, DataGridViewCellEventArgs e
The parameter sender is the object caused the method to be invoked (i.e your DataGridView) and e is of type DataGridViewCellEventArgs, which has some properties that'll be very helpful for you: RowIndex, and ColumnIndex. Using those parameters you can simply update the values of your DataTable and also your actual AnalogPoint instance in case you assigned it to some object.

Set Datasource of DataGridViewComboBoxCell in Virtual mode

When using virtual mode with DataGridView, I am subscribing to the CellValueNeeded event to get data on the fly. In the handler for that I have logic to differentiate between the columns, and if it is a DataGridViewComboBoxColumn, I want to give it a data source. My issue is that when I assign a data source to the cell, I get a stack overflow because in the DGV code, another call to CellValueNeeded is made, and an infinite loop occurs. Is there some clean way around this?
It is going in the loop since cell value is not setting correctly. It requesting data again and again then.

DataGridViewComboBox value is not valid?

I keep getting an error that states DataGridViewComboBox value is not valid. It seems like it is also in an endless loop: I will click ok and it will continuously keep popping up. I am running a program with a windows form application written in C# and .NET. Does anyone know how to fix this error?
Here is some portions of my code:
// authorityTypeDataGridViewTextBoxColumn
//
this.authorityTypeDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.authorityTypeDataGridViewTextBoxColumn.DataPropertyName = "AuthorityType";
this.authorityTypeDataGridViewTextBoxColumn.DataSource = this.AuthorityTypeBindingSource;
this.authorityTypeDataGridViewTextBoxColumn.DisplayMember = "Description";
this.authorityTypeDataGridViewTextBoxColumn.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.ComboBox;
this.authorityTypeDataGridViewTextBoxColumn.Frozen = true;
this.authorityTypeDataGridViewTextBoxColumn.HeaderText = "AuthorityType";
this.authorityTypeDataGridViewTextBoxColumn.MaxDropDownItems = 100;
this.authorityTypeDataGridViewTextBoxColumn.Name = "authorityTypeDataGridViewTextBoxColumn";
this.authorityTypeDataGridViewTextBoxColumn.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.authorityTypeDataGridViewTextBoxColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
this.authorityTypeDataGridViewTextBoxColumn.ValueMember = "Value";
this.authorityTypeDataGridViewTextBoxColumn.Width = 121;
//
// AuthorityTypeBindingSource
//
this.AuthorityTypeBindingSource.DataMember = "AuthorityType";
this.AuthorityTypeBindingSource.DataSource = this.lookUpDataSet;
Does anyone have any suggestions?
Here is the Handler:
private void TaskSummaryGrid_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
MessageBox.Show(this, e.Exception.Message);
e.Cancel = true;
}
yeah the solution is to make datagridviewcombobox cell value the same you are getting in the code behind.
if i want to show typeof(int) value , i must set property of the datagridviewcombobox cell like:
this.ComboboxCellcolumnName.ValueType = typeof(int);
the value type that you got(e.g int) should be the same you want to show in the combobox cell (int).
It looks like your DataGridViewTextBoxColumn at some point was a DataGridViewComboBoxColumn, because you have ComboBox properties that do not belong to a TextBox column.
The DataGridViewTextBoxColumn does not have:
.DataSource = this.AuthorityTypeBindingSource;
.DisplayMember = "Description";
.DisplayStyle = DataGridViewComboBoxDisplayStyle.ComboBox;
.MaxDropDownItems = 100;
.ValueMember = "Value";
I can only guess editing the designer file by hand can cause this.
If, however, you wanted to revert back to your combo box column, you would need to set some special handling to set it up.
You can refer to the MSDN article here, or this example below:
MSDN: Binding Enums to DataGridViews
InitializeComponent();
// special setup for enum column
DataGridViewComboBoxColumn stateColumn = dgLedger.Columns[0] as DataGridViewComboBoxColumn;
if (stateColumn != null)
{
stateColumn.DataSource = Enum.GetValues(typeof(TransactionState));
}
_ledger = new BindingList<LedgerItem>();
dgLedger.DataSource = _ledger;
I just had a similar experience with one of my datagridviews: DataError was getting thrown non-stop... It eventually turned out to be because the id in the combobox DataSource was of a different type (bigint) than the column that referenced it (int)...
I used all the solution above but none of them worked, so I tried to override the DataError event and it works very well without any problem:
private void dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
//do nothing
}
Ten years later now, I recently ran into the same problem and ended up working through the datagridview combobox source code to understand the problem and the solution. It turns out that even though swallowing error events is rarely the right course, #mamoun was correct: capturing the error and discarding it may be the correct solution in some scenarios. Here's why.
In a DataGridView with a ComboBox column, when grid data is loaded and the data in the grid column bound to the combobox value cannot be validated, a data error event is raised.
This can be tricky because the comboBox value is bound to a column in the DGV that may not be the same column in which the combobox itself appears (e.g., it may be a hidden column or another column that reflects the combobox value).
Validation can fail due to dev errors such as type mismatch, of course, but a common reason for failure is a scenario in which the dropdown data source is fixed (non-editable and does not allow adding new rows) and the datasource has delivered data in the value column that does not match any existing entry in the dropdown. This may occur, for example, if some of the data was originally entered as free-text and was misspelled, or if data is round-tripping to another system that changes white space or capitalization. It may occur if you change the list feeding the dropdown.
In this scenario, catching and ignoring (or preferably logging) the event will cause the value that triggered the error to be replaced with the default value from the combobox (usually the first row of the dropdown). If this is the desired handling, swallow away!
I wasn't able to find another event that allowed detection and correction to be carried out before the error event fires. In particular, the CellValidating event does not fire in this scenario.

Databound DateTimePicker fires validation error

I have a databound DateTimePicker:
dateDateTimePicker.DataBindings.Add(new Binding("Value", paymentBindingSource, "Date", true);
paymentBindingSource.DataSource = payment;
payment is Entity Framework object. payment.Date contains valid DateTime. When form is shown, dateDateTimePicker contains correct value, but an ErrorProvider is shown next to it, saying "Value of '01.01.0001 00:00:00' is not valid for 'Value'." It disappears when I change dateDateTimePicker value to anything.
Try reversing those two lines of code. The first line is probably looking to the data source, which, at that point, is null.
Would it be possible to see your validation code? I am guessing the validation error occurs when you first load the form, and that the way you bind the data does not clear the (existing) validation error, while when you manually change the value, that is triggering the relevant code.

How to retrieve a changed value of databound textbox within datagrid

ASP.NET 1.1 - I have a DataGrid on an ASPX page that is databound and displays a value within a textbox. The user is able to change this value, then click on a button where the code behind basically iterates through each DataGridItem in the grid, does a FindControl for the ID of the textbox then assigns the .Text value to a variable which is then used to update the database. The DataGrid is rebound with the new values.
The issue I'm having is that when assigning the .Text value to the variable, the value being retrieved is the original databound value and not the newly entered user value. Any ideas as to what may be causing this behaviour?
Code sample:
foreach(DataGridItem dgi in exGrid.Items)
{
TextBox Text1 = (TextBox)dgi.FindControl("TextID");
string exValue = Text1.Text; //This is retrieving the original bound value not the newly entered value
// do stuff with the new value
}
So the code sample is from your button click event?
Are you sure you are not rebinding your datasource on postback?
When are you attempting to retrieve the value from the TextBox? i.e. when is the code sample you provided being executed?
If you aren't already, you'll want to set up a handler method for the ItemCommand event of the DataGrid. You should be looking for the new TextBox value within that method. You should also make sure your DataGrid is not being re-databound on postback.
I would also highly recommend reading through Scott Mitchell's excellent article series on using the DataGrid control and all of it's functions:
https://web.archive.org/web/20210608183626/https://aspnet.4guysfromrolla.com/articles/040502-1.aspx

Categories

Resources