Looking for a way to dynamically delete rows from a datalist, providing a user a way to 'clean up' their input interface. The asp datalist gets loaded from SQL, then the user gets to manipulate the table before sending it on to another database.
I have a functioning 'addRows' by using a datatable session variable, adding rows to it then re-binding to the datalist, however I can't seem to get the same function with deleting rows.
Current logic is to use datalist 'delRows' command, get current typed-in or modified data from the asp datalist, assign it to a datatable, loop thru datatable and delete rows where certain fields are empty, then re-bind datatable to asp datalist.
Current code workup, but cannot get dt filled, error "dt = null" :
if (e.CommandName == "delRows")
{
DataList DataList1 = (DataList)FindControl("DataList1"); //find datalist in current state
Session["dataList1"] = DataList1; //assign datalist to session variable
DataTable dt = Session["dataList1"] as DataTable; //populate datatable with datalist session
for (int i = dt.Rows.Count - 1; i >= 0; i--)
{
DataRow dr = dt.Rows[i];
string check = dr["item_no"].ToString();
if (check == String.Empty)
{
dr.Delete();
}
}
DataList1.DataSource = dt;
DataList1.DataBind();
}
Hopefully there is a better way to accomplish this! Not to mention working....
For any future info seekers: Had to loop thru table to get most current textbox text into dt, then modify dt datatable in code behind, then rebind dt to datalist.
protected void doDataTable(string command, int e)
{
DataTable dt = new DataTable();
dt.Columns.Add("no", typeof(string));
dt.Columns.Add("desc", typeof(string));
dt.Columns.Add("code", typeof(string));
dt.Columns.Add("measure", typeof(string));
dt.Columns.Add("qty", typeof(int));
dt.Columns.Add("price", typeof(double));
foreach (DataListItem item in DataList4.Items)
{
string no = ((TextBox)item.FindControl("no")).Text;
string desc = ((TextBox)item.FindControl("desc")).Text;
string code = ((TextBox)item.FindControl("code")).Text;
string measure = ((TextBox)item.FindControl("measure")).Text;
int qty = Convert.ToInt16(((TextBox)item.FindControl("qty")).Text);
double price = Convert.ToDouble(((TextBox)item.FindControl("price")).Text.TrimStart('$'));
dt.Rows.Add(no, desc, code, measure, qty, price);
}
if (command == "add")
{
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
DataList4.DataSource = dt;
DataList4.DataBind();
}
else if (command == "del")
{
dt.Rows[e].Delete();
DataList4.DataSource = dt;
DataList4.DataBind();
}
}
Called with:
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "addRow")
{
doDataTable("add", e.Item.ItemIndex);
}
if (e.CommandName == "delRows")
{
doDataTable("del", e.Item.ItemIndex);
}
}
Related
I have a DataTable bound to a dataGridView using the following code :
dataGridView1.DataSource = ReducedColTable;
At some point i would like to move the selected rows into another Table.
So here is the loop :
List<DataGridViewRow> rows = (from DataGridViewRow row in dataGridView1.SelectedRows
where !row.IsNewRow
orderby row.Index
select row).ToList<DataGridViewRow>();
foreach (DataGridViewRow item in rows)
{
DataRow newRow = dtarget.Rows.Add();
newRow.SetField("artiste", item.Cells[0].Value);
newRow.SetField("album", item.Cells[1].Value);
newRow.SetField("song", item.Cells[2].Value);
newRow.SetField("year", item.Cells[3].Value);
newRow.SetField("file_path", item.Cells[4].Value);
newRow.SetField("file_size", item.Cells[5].Value);
dataGridView1.Rows.RemoveAt(item.Index);
}
Ps : I didnt find a way to copy the row into the new table (dtarget) which is declared globally hence the approach col by col.
DataTable dtarget = new DataTable();
My issue is that the last line is removing the row from the DataGridView but not from the original table (ReducedColTable)
Any hint how to achieve this ?
I found that the DataTable’s ImportRow works well for this. If you set the grids SelectionMode to FullRowSelect then you should be able to loop through the grids SelectedRows collection and “import” the selected row(s) into the other DataTable. Below is a simple example.
dt and dt2 are two DataTables with similar schemas. dt is a data source for datagridview1 and dt2 is a data source to datagridview2. Initially, dt is filled with some data and dt2 is empty. Once the user selects one or more rows, a button's click event initiates moving the selected rows from dt to dt2.
To start, a simple loop through the selected rows. A check if the “new row” is selected which we do not want to copy, therefore we ignore it. Next, get the “data bound” row from the data table in the form of a DataRowView object. Then we “import” that row into dt2, and finally removing the copied row from dt. I did not do a lot of testing on this however it appears to work as expected.
private void button1_Click(object sender, EventArgs e) {
DataRowView drv;
foreach (DataGridViewRow row in dataGridView1.SelectedRows) {
if (!row.IsNewRow) {
drv = (DataRowView)row.DataBoundItem;
dt2.ImportRow(drv.Row);
dt.Rows.Remove(drv.Row);
}
}
}
To make the example complete, drop two grids and button onto a form.
DataTable dt;
DataTable dt2;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
dt = GetTable();
dt2 = GetTable();
FillTable(dt);
dataGridView1.DataSource = dt;
dataGridView2.DataSource = dt2;
}
private DataTable GetTable() {
DataTable dt = new DataTable();
dt.Columns.Add("Col1", typeof(string));
dt.Columns.Add("Col2", typeof(string));
dt.Columns.Add("Col3", typeof(string));
return dt;
}
private void FillTable(DataTable dt) {
for (int i = 0; i < 10; i++) {
dt.Rows.Add("C0R" + i, "C1R" + i, "C2R" + i);
}
}
Hope this helps.
I have a datatable 'tblTest'. When I try to add next row, the first row will get deleted. I need to add data as the second row. Find my code below.
DataTable dt = new DataTable("tblTest"); // Declare as Global.
public JsonResult SaveTestData(string itemCode,int quantity)
{
dt.Columns.Add("ItemCode", typeof(string));
dt.Columns.Add("Quantity", typeof(int));
DataRow dr;
dr = dt.NewRow();
dr["ItemCode"] = itemCode;
dr["Quantity"] = quantity;
dt.Rows.Add(dr);
return Json(1);
}
The 'SaveTestData' function repeats and need to add rows as the next row.
Store DataTable in Session, like this:
public JsonResult SaveTestData(string itemCode, int quantity)
{
DataTable dt = new DataTable("tblTest"); // Declare as Global.
// A table saved in session
if (Session["tblTest"] != null)
{
dt = (DataTable)Session["tblTest"];
}
else // create new table and store in session
{
dt.Columns.Add("ItemCode", typeof(string));
dt.Columns.Add("Quantity", typeof(int));
}
DataRow dr;
dr = dt.NewRow();
dr["ItemCode"] = itemCode;
dr["Quantity"] = quantity;
dt.Rows.Add(dr);
//store new row in session
Session["tblTest"] = dt;
return Json(1);
}
I have been trying to convert GRIDVIEW to DataTable but it doesn't give me data, it only gives me HEADERS of GridView but not the data inside it. Why ? I am using template fields in gridview
Calling it from event:
DataTable dt = GetDataTable(GridView DenominationsWiseTransactions);
Conversion function:
DataTable GetDataTable(GridView dtg)
{
DataTable dt = new DataTable();
// add the columns to the datatable
if (dtg.HeaderRow != null)
{
for (int i = 0; i < dtg.HeaderRow.Cells.Count; i++)
{
dt.Columns.Add(dtg.HeaderRow.Cells[i].Text);
}
}
// add each of the data rows to the table
foreach (GridViewRow row in dtg.Rows)
{
DataRow dr;
dr = dt.NewRow();
for (int i = 0; i < row.Cells.Count; i++)
{
dr[i] = row.Cells[i].Text.Replace(" ", "");
}
dt.Rows.Add(dr);
}
return dt;
}
So, when you are looping through the rows in the datagrid, it will include headers, the rows and the footer.
To see just the data rows you need to do something like:
if (e.Row.RowType == DataControlRowType.DataRow)
{ //convert that row }
Your conversion line might need some work, but at least you'll only need to concern yourself with datarows now.
Hey guys I've just started programming and I'm running into a problem. The new Datatable i created doesnt show in GridView2 when button1 is clicked. Although it is filled with data from the "planning" table(checked that dtPlanning is filled with the TextBoxes in comment).
So in short: I want to get DataTable planning into the new DataTable dtPlanning and display it in a gridview.
Code Behind:
protected void Button1_Click(object sender, EventArgs e)
{
DataTable dtPlanning = new DataTable();
dtPlanning.Columns.Add("Courseday", typeof(int));
dtPlanning.Columns.Add("Part", typeof(string));
dtPlanning.Columns.Add("Design", typeof(string));
dtPlanning.Columns.Add("Lesson", typeof(string));
//DataRow dr = planning.Rows[1];
//TextBox2.Text = (dr["Daynumber"]).ToString();
//TextBox3.Text = (dr["Part"]).ToString();
//TextBox4.Text = (dr["Design"]).ToString();
//TextBox5.Text = (dr["Lesson"]).ToString();
for (int i = 0; i < dtPlanning.Rows.Count; i++)
{
DataRow dr = dtPlanning.NewRow();
foreach (DataRow datarow in planning.Rows)
{
dtPlanning.Rows.Add(datarow);
}
}
GridView2.DataSource = dtPlanning;
GridView2.DataBind();
}
Source code:
<asp:GridView ID="GridView2" runat="server">
Thank you for your help.
Logically, dtPlanning.Rows.Count = 0 because this table is just initialized!
Secondly, you cannot Add a row from one table to another, user Import
for (int i = 0; i < planning.Rows.Count; i++)
{
dtPlanning.ImportRow(planning.Rows[i]);
}
I wonder why don't you just use the table planning?
You must:
Add to DataSet a new DataTable
Add to DataTable a new Columns
And GridView2.DataSource=YourNameDataSet.Tables[index_of_DataTable_in_DataSet].DefaultView;
My homework is in ASP.NET and my prof wants me to delete a row from a gridview that doesn't use a SqlDataSource. Is this possible? Because I think my prof wants to fail me just because I asked a question and he wasn't able to answer it.
Yes you can delete a row from gridview that doesn't use sqldatasource. All you have to do is delete the row from the source (whatever the source is...), that is bind to your gridview.
heres sample code for the issue:
public static DataTable dt;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = "column1cell";
dr["Column2"] = "column2cell";
dt.Rows.Add(dr);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
if (dt.Rows.Count > 0)
{
dt.Rows.RemoveAt(0);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
not the best code, but if your prof wants you to do, here you are.
hope this helps you...
I you Just want to delete the row find the row index and the simply call the method
datagridview.rows.removeat(rowindex);
There is a better way without having to rebind the Gridview and it forcing a call to the SqlDataSource.
Use ViewState.
When you load the Gridview, save the "data" into a ViewState variable.
ie:
//ok let's load the gridview with data as normal and display it
//'sdsClasses' is the SQL data source
gvStudents.DataSourceID = "sdsClasses";
gvStudents.DataSource = null; // Null out the source, as we have a SourceID instead
gvStudents.DataBind(); //load the gridview and display it
//save the data in a viewstate for later use
DataView dvClasses = (DataView)sdsClasses.Select(DataSourceSelectArguments.Empty);
DataTable dt = new DataTable();
if (dv != null)
{
dt = dvClasses.ToTable();
ViewState["gv"] = dt;
}
So now when ever the Gridview loads, you have the data its used in memory as a ViewState.
If you need to delete a row, do this ...
In my example I am using a search feature to look for the row I want to delete, based on a SelectValue from a dropdownlist control. You'll have to use something like that to pin-point the row you want to delete. If you wanted to delete the last row, then do a ForEach on the DataTable, row-by-row until you get to the last row and delete!
//Load the dataview that was already saved in the ViewState
DataTable dt = (DataTable)ViewState["gv"];
//find the student in the datatable, row by row
bool found = false;
bool wsAtt = false; //flag to indicate if the student is already in the roll or not saved yet (ie: sdsClasses recordset)
foreach (DataRow dr in dt.Rows)
{
//compare studentID in the datatable with the selected value of the student to delete
//check that the field has TECNQ studentIDs otherwise use the 2nd cell in the row
if (dr[0].ToString().Contains("NQ"))
found = (found || dr[0].ToString() == ddlRemoveStudents.SelectedValue);
else
{
found = (found || dr[1].ToString() == ddlRemoveStudents.SelectedValue);
wsAtt = true;
}
//he should!
if (found)
{
//remove the row to the datatable
dt.Rows.Remove(dr);
//Bind the grid view to the datatable and refresh
gvStudents.DataSource = dt;
gvStudents.DataSourceID = null; // Null out the id, we have a source
gvStudents.DataBind();
//update the viewstate with the new amount of rows
ViewState["gv"] = dt;
}
}
So you can see, using a ViewState as a replacement to the SqlDataSource, you're able to manipulate the Gridview as you wish and never call the original SqlDataSource again, except the first time to get the data.
And tell your professor he's an arrogant pig.