I want to delete rows from my dataset. Below is the code...
When the checkbox is selected a value is getting stored as a hiddenfield value
The code is not firing. The values are not getting added to the "rowstodelete".
protected void BtnRmvFile_Click(object sender, EventArgs e)
{
string[] IDs = hdnFldSelectedValuesAp.Value.Trim().Split('|');
//Code for adding items
foreach (string Item in IDs)
{
try
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
ViewState["CurrentTable"] = dtCurrentTable;
List<DataRow> rowsToDelete = new List<DataRow>();
foreach (DataRow row in dtCurrentTable.Rows)
{
if ((row["FileMasterID"] == Item))
{
rowsToDelete.Add(row);
}
}
foreach (DataRow row in rowsToDelete)
{
row.Delete();
}
dtCurrentTable.AcceptChanges();
}
If you say the code is not firing i suggest to start by checking with some kind of pop up that your method(BtnRmvFile_Click) is responding.
Other than that I don't know if its just the way you pasted the code but make sure the brackets are organized.
If the method responds to the click event start debugging, see which steps are executed and what values you pass/get make sure that its what you expect.
Good luck!
Related
I have a WinForms application that has some data in a DataGridView. If a user double clicks on a cell then that row needs to be removed, and that works fine unless they click on a column first to sort the data by that column. If it has been sorted then the row index of the event still refers to the origional value in that row (I.E. Double clicking on the first item after sorting the data will remove the row that was at the top before the sort).
Is there a way for me to update the row indexes when the sort occurs?
Current initialize is similar to:
DataTable dt = new DataTable();
NpgsqlDataAdapter da = new NpgsqlDataAdapter(query, connection);
da.Fill(dt);
this.dgv1.DataSource = dt;
And the double click event is similar to:
private void dgv1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
DataTable dt = (DataTable)dgv1.DataSource;
if (e.RowIndex > -1)
{
dt.Rows.RemoveAt(e.RowIndex);
}
}
I suspect the issue is something very simple that I am not seeing right now..
You can use the property DataBoundItem of a DataGridViewRow to reference to the underlying DataRow and use the Remove method instead:
private void dgv1_CellDoubleClick(object sender, DataGridViewCellEventArgs e){
DataTable dt = (DataTable)dgv1.DataSource;
if(e.RowIndex>-1)
dt.Rows.Remove(((DataRowView)dgv1.Rows[e.RowIndex].DataBoundItem).Row);
}
I'm working in C# displaying some data in a DataGridView and I'd like it to not allow you to add a duplicate key.. Right now, my DataGridview is pretty simple with just 2 columns. One is called "Key" the other is called "Value". What i want, is for when the user edits or adds a new entry to the DataGridView, it checks if there is already a duplicate and cancels the edit/creation of the new row. Here is my current code:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[0].Value.Equals(dataGridView1.Rows[e.RowIndex].Cells[0].Value))
{
dataGridView1.Rows.Remove(dataGridView1.Rows[e.RowIndex]);
break;
}
}
refresh();
}
It isn't working at all... Can someone tell me how I should be doing this?.. Thanks!
Edit: I'm also getting this error on the dataGridView1.Rows.Remove() call -
Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.
Edit:
The DataGridView looks like this
Key | Value
----------------
blah | something
somekey | somevalue
It is probably your foreach loop, which doesn't allow deleting rows.
Try something like this:
private void dgv_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
for (int i = 0; i < DataGridView1.Rows.Count; i++) {
DataGridViewRow row = DataGridView1.Rows[i];
if (row.Cells[0].Value == DataGridView1.Rows[e.RowIndex].Cells[0].Value) {
DataGridView1.Rows.RemoveAt(e.RowIndex);
DataGridView1.FirstDisplayedScrollingRowIndex = i;
return;
}
}
}
I do not allow row editing, though, so I could be wrong.
EDIT: Just a quick edit. I'd set the FirstDisplayedScrollingRowIndex to e.RowIndex, but that row would have just been deleted!
I'm only guessing but I've tried your code and I've seen a logical error:
if you debug it you'll see that with the foreach loop you'll necessary hit the element you just edited, which is obviously equal to itself.
I suggest you to change the loop to a for or to check if the row index is the same.
try with this code for that,
protected void GV_RowCommand(object sender, GridViewCommandEventArgs e)
{
DataTable dt1 = ViewState["dt"] as DataTable;
if (e.CommandName == "Add")
{
DataRow dr;
dr = dt1.NewRow();
dr["DED_Id"] = Material_Id;
dr["DED_Name"] = Material;
dt1.Rows.Add(dr);
dt1.AcceptChanges();
ViewState["dt"] = dt1;
}
}
I am creating a website where our customers can order parts directly from us. I have a datatable setup and when users click a button it adds a quick detail of the order to a gridview. In the gridview, I have the edit and delete buttons enabled. the delete function works fine, however when you try to edit the information, it doesn't change the gridview with the new info. Here's what I have so far:
protected void griditems_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
DataTable dt = (DataTable)Session["table"];
foreach (DataRow dr in dt.Rows)
{
part = Convert.ToString(dr["Part"]);
dr["Part"] = part;
dr["Quantity"] = qty;
dr["Ship-To"] = shipto;
}
griditems.EditIndex = -1;
BindData();
}
when trying this, it displays the gridview back with the original input values. I have also tried this (not working and get an error that says "There is no row at position 0":
DataTable dt = (DataTable)Session["table"];
GridViewRow row = griditems.Rows[e.RowIndex];
dt.Rows[row.DataItemIndex]["Part"] = ((TextBox)(row.Cells[1].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["Quantity"] = ((TextBox)(row.Cells[2].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["Ship-To"] = ((CheckBox)(row.Cells[3].Controls[0])).Checked;
griditems.EditIndex = -1;
BindData();
Am I missing an EditItemTemplate in the aspx file, or am I just doing the RowUpdating all wrong?
You probably need to step back a bit and first check out how you could do create, update, delete and read with a grid view. Also, you may wanna check this post.
I deleted a row in my DataGridView by selecting it and pressing Delete and would like to get the row's index. How could i do that?
You may obtain an index before you delete a row by handling UserDeletingRow event.
dataGridView1.UserDeletingRow += (sa, ea) =>
{
MessageBox.Show(ea.Row.Index.ToString())
};
You can get the selected index of the current selected item:
int index = DataGrid1.SelectedIndex;
You can do this before deleting the item and you will know the index.
Most of the answers in StackOverflow mentioned UserDeletedRow as an event to handle and get the user deleted row index. this event only fired after deleting that row.
The correct one must be UserDeletingRow, where by this event you can do something before you lose the deleted row.
Now how to get the row index? the answer by using the below code
private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
int tmp = e.Row.Index;
}
Maybe this will help you.
private void EvtBindingNavigatorDeleteItemClick(object sender, System.EventArgs e)
{
ToolStripButton MyToolStripButton = (ToolStripButton)sender;
CustomBindingNavigator MyCustomBindingNavigator =
(CustomBindingNavigator)MyToolStripButton.GetCurrentParent();
CustomDataGridView MyDataGridView = GetDataGridView(MyCustomBindingNavigator);
int RowIndexDelete = -1;
BindingSource MyBindingSource = MyCustomBindingNavigator.BindingSource;
DataTable MyDataTable = (DataTable)MyBindingSource.DataSource;
foreach ( DataRow MyDataRow in MyDataTable.Rows)
{
if (MyDataRow.RowState == DataRowState.Deleted)
RowIndexDelete = MyDataTable.Rows.IndexOf(MyDataRow);
}
}
I have an ASP.NET 2.0 (C#) web app, and in it I have a gridview that gets its data from an oracle database.
I want to know how to check if the gridview is empty, and the do something.
I have already tried:
if(GridView.Rows.Count == 0)
{
// Do Something
}
but it doesn't work...
Any ideas?
Thank you.
Your code should work. But only after GridView.DataBind() has been called. Generally I don't check the GridView it's self, but the datasource of the grid view.
DataTable data = DAL.getdata();
if (data.Rows.Count == 0)
{
ShowEmptyData();
}
else
{
Grid.DataSource = dt;
Grid.DataBind();
}
This doesn't work since the GridView is data bound and is going to fetch the actual data at a later time while rendering the page. You should check this by directly querying the data binding source of the gridview (see if the actual list that's grid view bound to is empty or not).
If you just want to display something when it's empty, you should use <EmptyDataTemplate> in your markup:
<asp:GridView runat="server">
<EmptyDataTemplate>The grid is empty</EmptyDataTemplate>
</asp:GridView>
I agree with the other responses. I want to add little information, you should get rows.count after databind method :
int rowCount = GridView.Rows.Count; // returns zero
GridView.DataBind();
rowCount = GridView.Rows.Count; // returns actual row count
If you're using databinding, the the row count of the datasource not the count on the grid itself.
Its very easy: Hope it works for you.. :)
Use event of GridView DataBound: which fires after data is bound.
protected void GridView1_DataBound(object sender, EventArgs e)
{
int rowCount = GridView1.Rows.Count;
if (rowCount == 0)
{
GridView1.Visible = false;
}
else
{
GridView1.Visible = true;
}
}
First create a helper class.
public static class GridViewExtensions
{
public static IEnumerable<GridViewRow> AsEnumerable(this GridView grid)
{
foreach (GridViewRow row in grid.Rows)
{
yield return row;
}
}
public static bool IsEmpty(this GridView grid)
{
return !grid.AsEnumerable().Any(t => t.RowType == DataControlRowType.DataRow);
}
}
Then just call IsEmpty
GridView1.IsEmpty()
In case you've configured your GV to automatically fetch the data from DB, then you may add the following line as the first statement of your GV in Source mode:
<EmptyDataTemplate>No data found.</EmptyDataTemplate>
And then continue with the normal code in your GV.
Based on answers already, GridView.Rows.Count is not enough on its own, depending on the nature of your GridView, especially if it's a dynamic gv, which in most cases it is, plus you have to factor in Paginating, Headers and Footers, which alter the row count.
I use a simple method to tell me ...
//checks if a gridview has any actual rows of data (not just blank rows filled in by the Load
protected bool gvNoData(GridView gv)
{
int wsDataRow = 0;
foreach (GridViewRow gvRow in gv.Rows)
if (gvRow.RowType == DataControlRowType.DataRow)
{
HiddenField hf = (HiddenField)gvRow.FindControl("hfStudentID");
if (hf != null)
if (hf.Value.ToString().Length > 0)
wsDataRow +=1;
}
//if a count was generated then there are data rows, otherwise the rows are blank or nonexistant
if (wsDataRow > 0) return false;
else return true;
}
So running something like this will tell you if the Rows are really "
"DATA" rows, or empty or nothing!
Obviously in my case I have a HiddenField to tell me if the GridViewRow is an actual data row, as I prefill my gridview with blank rows (for my purposes) and some datarows.
However, a simpler version to check based on DataRow vs HeaderRow, etc...
foreach (GridViewRow gvRow in myGridView.Rows)
if (gvRow.RowType == DataControlRowType.DataRow)
{
//do what you need
}
I hope this helps.
In short, there is no GridView.IsEmpty() function unfortunately, unless you enumerate one as shown below.