I have a drop-down menu in my web application that is data-bound to a DataTable. I want to make the first item in the drop-down list blank and be the first thing in the list. I am trying to do this by inserting a new DataRow where the text value is "" and the primary key value is DBNull.Value because I want the blank to raise an SQL exception if it is submitted. However if I try to insert this row I get a NoNullAllowedException.
I've tried myTable.PrimaryKey = null; and myTable.Constraints.Clear(); but no luck.
Is there a way around this? Or maybe even a better way to do this?
EDIT: for clarity I do understand that raising exceptions for validation is bad, and it's not for that. I want it to raise an exception in the case someone forgets to validate the input before sending it off to the database.
Related
C#, WinForms, DataGridView, DataTable. My form allows the user to enter data into a new row (as opposed to, say, popping up a single record view of the record). When the user clicks my Save button, the click event looks like this:
DataTable dtAddRows = this.SomeFictitiouslyNamedDataSet.SomeFictitiouslyNamedDataTable.GetChanges(DataRowState.Added);
My assumption is that calling GetChanges with that enum is going to get me a set of the rows that were added to the grid at run time. However, it errors out because 1 of the columns "Last_Updated_DT" (which must be displayed and readonly) is a date column that will be populated when we write to the datatable. However, the DataSet has a rule that this column cannot be null.
The problem is, I get an error indicating that the Last_Updated_DT column is actually null (surprise surprise). Its a new row, and the column is readonly in the grid, so of course it is null.
How do I get around this error or stuff a value in that (or those) rows for that column before I actually try to get the added rows?
For the sake of posterity:
private void myGrid_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
{
e.Row.Cells["MyColumnNameGridViewTextBoxColumn1"].Value = String.Empty;
}
Adding that event to my code fixed my issue. I set the value to String.Empty so it wouldnt put a date/time value in the column until after the Save was clicked.
Then, in the Save_Click event, I get the added rows with this code:
DataTable dtAddedRows = this.dsMyDataSet.MyDataTable.GetChanges(DataRowState.Added);
Then, in the TableAdapter.Insert parameter list, I added DateTime.Now for the date parameter.
Eventually call MyTableAdapter.Update method using the DataSet overload.
All fixed.
Hat tip to #KiNeTiC for providing the necessary guidance.
Environment: Web Development in Visual Studio
Language: ASP.NET
I'm afraid I already know the answer, but it can't hurt to ask. I have an application that gets data from SAP and can return specific results or a list of possible results for each row of a DataGridView. So the user might enter "abcd" and get "1234" as a result or he might get "1234 or 2345 or 3456" as a result. For each row I would like to have each column where multiple results were returned as a combobox. The rest should stay fixed though, since having the table littered with comboboxes that only have one result would be annoying.
Is there any trick to do this? I know you can "convert" an entire column into a column of comboboxes using DataGridViewComboBoxColumn like in this blog:
http://mytactics.blogspot.de/2014/01/convert-datagridview-column-to-combo-box.html
.Is there any way to have a combobox only for specific cells though? I know I could put a combobox next to each row of the table and let the user choose from that one or I could have a combox in every single row and maybe lock the ones with only one result. I'm not happy about either of those solutions though.
You can try and add a ComboBox to yourDataGridViewCell.Controls and make the label.Visible = false; or remove it. It would be something like:
yourDataGridViewCell.Controls.Clear();
yourDataGridViewCell.Controls.Add(new ComboBox());
yourDataGridViewCell.Controls[0].DataSource = yourList;
//set the value member etc.
I'm constructing a GUI that allows the user to manipulate XML data. A helpful fellow named Peter was able to point me to a direction leading me to question why my cell values were null even when the user selects a value in the combobox.
I've read up on a few things: the comboboxcolumn's value member, display member, data source, and datapropertyname. I've figured out what display and value members do, but decided to stick with a data source so I wouldn't have to specify a display member and value member; I believe it made things easier and plus the choices in the combobox are stored in a string array.
The premise is, the user enters in choices into a rich text box. Then, the textbox is read line by line and every line becomes a choice in the combo box. I then create a new combobox column in the datagridview and the choices are available for the user to choose. After the user is done, I have a button called "save with combo column..." which creates a new datacolumn in the datatable that the datagridview is displaying and I try to copy the values over via this code: (since I cannot directly merge the combobox column with a datatable)
int size = dataGridView1.Rows.Count - 1;
DataColumn column = new DataColumn(combo.HeaderText);
data_set_array[(int)IndexNumber.Value].Tables[(int)TableNumber.Value].Columns.Add(column);
for (q = 0; q < size; q++)
{
data_set_array[(int)IndexNumber.Value].Tables[(int)TableNumber.Value].Rows[q][combo.HeaderText] = dataGridView1["combo", q].Value;
}
when that is all said and done, the new column is created and a message is displayed. However, the datatable's values are null, which means the cell values are also null. This implies that the item that the user selected in the combo box wasn't copied over to the cell value. What am I doing wrong? I set the datasource to the string of arrays where the strings are the user's choices for the combobox, and yet when the I selected choices from the combobox and tried to save it, the values are null. I also read that I did not need to worry about value member or display member since setting the datasource would provide me valid display text and valid values.
If any additional information is needed please ask. Thanks in advance.
.NET 3.5 SP1, Visual Studio 2008 C#.
Sincerely,
tf.rz
I am not sure
However I think you will find that the datarows have been created using the old column definitions.
when you add a new column i doubt it is resizing the arrays for each row to add a column.
Although if this was true i would expect an index out of range exceptions.
you need to break that big line of code up so so that it is easier to debug.
IE when you leave the loop does the cell have the value you expect? Or has the assign failed?
It will tell you where things are going wrong.
If it is assigning then you lose the data later then you need to expand your search (this could happen if you have somehow assumed a value type was a reference type for instance)
you may finid you need to create a new data table with the correct column definitions and then copy the old data into the new one ... but first you need to establish where it is failing - you are currently doing too much in 1 line of code.
Are you sure the value syou are getting from the combo box are not null?
hi i m having one datagrid...that have one check box field...whenever i check the check box that time that row will be inserted in database...but check box value is not set true value...it always return false value...i m using C# asp.net 2003 version..please help me...
If you data bind the grid in Page_Load, maybe you don't check for IsPostBack, so, your grid gets rebound and all previous changes like check are not persisted.
if(! Page.IsPostBack)
{
// Data bind the grid
}
Another possible reason is how you try to retrieve the checbox.
We really need to see some code in order to help you.
Its not immediately clear what your problem is. But if I had to guess, since ASP.NET 1.1. doesn't support two-way data binding, I would start with the code that reads the data from the form and updates your data source.
Okay big brains here's something that's more of a challenge than a requirement. I am a bit stumped. I usually just need a prod in the right direction, so get your prodding sticks ready.
I have a tabcontrol covered in textboxes. I want to perform a check of the contents of all the textboxes during the SelectedIndexChanged event on a listview on the same form. If one of the textboxes has data different from a DataTable row - represented by the ListView Item - I want it to ask if the user would like to keep the change they just made. If nothing has changed I want it to just change the selection.
So obviously I'm comparing the contents of the text boxes against associated columns in the datarow.
I could just brute force the check and do each individual check one at a time. I'd prefer to come up with some clever algorithmic way of cycling through the tabcontrol textboxes and checking the values against the columnar values.
Any suggestions?
EDIT: I like the "cleverly named textboxes" solution below best, although both are good. If no one else has a better idea in the next 14 days the textbox answer gets the green.
Give the textboxes a clever name as in a portion of the name is the column/row name.
Group the textbox controls an loop through them. For each control, get the (portion)name and use that as a reference to your datatable. Check the values.
If I'm understanding you right, you want to avoid comparing every textbox on every change, in favour of just checking the textboxes that are changed, driven by the SelectedIndexChanged event of the ListView control. Is that right?
Well, DataRows and DataTables already have row versioning and rollbacks implemented, so if you bind the text boxes to the underlying row (either by writing events to write back on change/lose focus or by using an automated mechanism to accomplish the same task), then check the RowState property on SelectedIndexChanged. If the RowState is anything other than unchanged, prompt the user to save. If he saves, commit the changes, otherwise reject them.
So, for example, you'd want something like this in your SelectedIndexChanged event handler:
if (row.RowState == DataRowState.Modified) {
// prompt for user input
if (promptResult == PromptResult.Save) {
row.AcceptChanges();
}
else {
row.RejectChanges();
}
}