I have a situation where I want to make a generic codebehind function to show a message row that spans the whole table. I have previously passed the Table object and the number of columns so that it could set the column span, but this is somewhat error prone as we sometimes add new columns and I have to update the column count numbers for the messages.
There doesn't seem to be any column count in the Table object and neither any way to get the TableHeaderRow that has been added in the aspx file. I'd like to avoid having to add id's to all the TableHeaderRow's as well.
Try this, should work (assuming the TableHeaderRow is the first child of the Table):
int j = 0;
foreach (Control current in tableId.Controls[0].Controls)
{
if (current.ToString() == "System.Web.UI.WebControls.TableHeaderCell")
{
j++;
}
}
Related
If I use OnAutoGeneratingColumn to cancel some columns that I don't necessarily want to generate, will it affect the number of columns in Table.Columns.Count?
Context
I'm iterating through a table, row by row, taking each value and passing it through to an insert SQL command. Right now it lines up so that each entry is associated properly. Will I disrupt this with e.cancel? Will row[1] no longer point to what it once did if row[0] was e.cancel'd?
for (int i = 0; i < table.Dummy.Columns.Count; i++)
{
// if we're past our first entry, add room for the next before entering it
if (i != 0)
{
InsertIntoTableQuery.AddIntPrm();
}
//if our column has an entry, add it into our table.
if (row[i] != null)
{
InsertIntoTableQuery.Prms[i].Val = row[i];
}
}
No! I figured out why I was erroring and this wasn't the cause. you can cancel column generation in the wpf datagrid without actually altering the table index's. In hindsight that's pretty obvious.
I am trying to query my DataSet and display the results in an unbound DataGridView. I feel like I am quite close with my programming logic here, but I keep getting the error ArgumentOutOfRange Exception. Index was out of range. Must be non-negative and less than the size of the collection.
My code snippet:
DataRow[] foundRows;
//Queries the Reservations table with the 'searchExpression' variable
foundRows = this.reservationMasterDataSet.Tables["Reservations"].Select(searchExpression);
//If there is at least one record found...
if (foundRows.Length > 0)
{
//Used to count our row indexes
int i = 0;
//Populate the DataGridView with the queried response
foreach (DataRow row in foundRows)
{
//Used to count our column indexes
for (int j = 0; j < reservationMasterDataSet.Tables["Reservations"].Columns.Count; j++)
{
//THIS LINE IS THROWING AN EXCEPTION
dataGridView1.Rows[i].Cells[j].Value = row.ItemArray[j];
}
i++;
}
}
My DataRow contains 12 objects so I made sure that the DataGridView has 12 columns to correspond (and there are 12 in the original database). I think I am getting the exception right away (i is still 0 in debugger). I first tried it using just row[i] but got the same error.
This is meant to be a search results pane, not an editable thing, which is why I want to only return certain results. I figured the DataGridView is the nicest and easiest way to layout the record on a Windows form.
Before you access to DataGridView1.Rows[i].Cells[j], you need to make sure DataGridView1.Rows[i] exists. If no, you need to add it to the DataGridViewRowCollection.
You can find a lot of sample on on this page.
I am using a DataGridView to display some data in my application.
The data in the table gets changed dynamically according to the users input.
I am able to retrieve the data according to the user.
I have to add an extra column named ID and fill in the values serially starting from 1 to the number of rows which are generated dynamically.
I had added the column using dgrid.columns.add("UID");
But how to insert values at runtime?
Seeing your code, it is not correct to do:
dgrid.Columns.Add("UID");
You will have to do:
dgrid.Columns.Add("uidColumn", "UID");
To modify/add the value of an existing cell, if the row already exists, you can do:
dgrid.Rows[0].Cells["uidColumn"].Value = myValue;
That will modify the value of the column with name uidColumn and row 0. According to your problem, all you have to do is:
for (int i = 0; i < dgrid.Rows.Count; i++) {
dgrid.Rows[i].Cells["uidColumn"].Value = GetValueOfRow(i);
}
supposing that you have a method GetValueOfRow that receives a row index and returns the value you need in the ID column in that row.
To whom this may concern, I have searched a considerable amount of time, to work a way out of this error
"Deleted row information cannot be accessed through the row"
I understand that once a row has been deleted from a datatable that it cannot be accessed in a typical fashion and this is why I am getting this error. The big issue is that I am not sure what to do to get my desired result, which I will outline below.
Basically when a row in "dg1" is deleted the row beneath it takes the place of the deleted row (obviously) and thus inherits the deleted rows index. The purpose of this method is to replace and reset the rows index (via grabbing it from the corresponding value in the dataset) that took the deleted rows place and as such the index value.
Right now I am just using a label (lblText) to try and get a response from the process, but it crashes when the last nested if statement trys to compare values.
Here is the code:
void dg1_Click(object sender, EventArgs e)
{
rowIndex = dg1.CurrentRow.Index; //gets the current rows
string value = Convert.ToString(dg1.Rows[rowIndex].Cells[0].Value);
if (ds.Tables[0].Rows[rowIndex].RowState.ToString() == "Deleted")
{
for (int i = 0; i < dg1.Rows.Count; i++)
{
if (Convert.ToString(ds.Tables[0].Rows[i][0].ToString()) == value)
// ^ **where the error is occurring**
{
lblTest.Text = "Aha!";
//when working, will place index of compared dataset value into rowState, which is displaying the current index of the row I am focussed on in 'dg1'
}
}
}
Thanks ahead of time for the help, I really did search, and if it is easy to figure out through a simple google search then allow myself to repeatably hate on me, because I DID try.
gc
You can also use the DataSet's AcceptChanges() method to apply the deletes fully.
ds.Tables[0].Rows[0].Delete();
ds.AcceptChanges();
The current value for the data column in the inner if statement will not be available for deleted rows. To retrieve a value for deleted rows, specify that you want the original value. This should fix your error:
if (Convert.ToString(ds.Tables[0].Rows[i][0, DataRowVersion.Original].ToString()) == value)
In your "crashing if", you can check if the row is deleted before accessing it's values :
if (ds.Tables[0].Rows[i].RowState != DataRowState.Deleted &&
Convert.ToString(ds.Tables[0].Rows[i][0].ToString()) == value)
{
// blaaaaa
}
Also, I'm not sure why you ToString() the RowState instead of comparing it to DataRowState.Deleted.
after deleting the row , rebind your grid with the datatable , no need to manually resetting index , datatable handels it.
so you onl;y need to rebind grid's datasource.
I'm trying to figure out where DataRowCollection.Add(DataRow row) inserts the new row into its datatable. Is it at the end of the table, like an append? Is it random?
Also, I want to use this while I'm for looping through a datatable. If some condition exists, add a new row containing different data to run through the For loop to the end of the datatable. Are there any specific problems with this approach? How else might I handle it?
EDIT: I am For Looping through a .Net DataTABLE stored in memory. I'm not touching the dataBASE where the original data is stored during this looping operation. The DataTABLE is populated prior to the loop and is not a problem.
Here is relavant code:
DataTable machineANDlastDate = new DataTable();
//Populate machineANDlastDate
for (int i = 0; i < machineANDlastDate.Rows.Count; i++)
{
lastFutureDate = DateTime.Parse(machineANDlastDate.Rows[i]["MaxDueDate"].ToString());
newDateTime = lastFutureDate.AddDays(frequency); //This is where the new date is created.
machineSerial = machineANDlastDate.Rows[i]["machineSerial"].ToString();
if (newDateTime < DateTime.Now)
{
machineANDlastDate.Rows.Add(new String[] { machineSerial, newDateTime.AddDays(frequency).ToString() });
continue;
}
...Removed for irrelevancy...
}
Is this a valid way to add a row to the end of the datatable?
As far as I know, it is always added to the end of the collection.
If you for loop through the database, there shouldn't be a problem, if you begin at the beginning of the data table and finish at the end of it or smth similar. However, you will then also loop through the newly created data rows, and I don't know whether you want to achieve this. You only could get problems if you take a foreach loop instead because it cannot handle modifications of the underlying collection.
If you want to know if a row is new or not you can check the DataRow.RowState property.
// your code to add rows
...
// process added rows
foreach (DataRow row in machineANDlastDate.Rows)
{
if (row.RowState == DataRowState.Added)
{
// do stuff
}
}
// now confirm new rows (they won't have a RowState of Added after this)
machineANDlastDate.AcceptChanges();
It's always at the end of the table, as far as i know most of the DataBase conectors, whe you use their add row, its always at the end.
The Add method will insert a DataRow into a DataRowCollection object only. To actually add the DataRow to the data table, you will need to call the NewRow method which appends itself onto the DataTable, and thus appends the row to the table in that database. For reference, check out http://msdn.microsoft.com/en-us/library/9yfsd47w.aspx