All Data have checkbox on Gridview for Delete - c#

I have a one Gridview (Gridview1) and one Button (Delete).
And AVUKAT table (Columns--> HESAP, MUSTERI, AVUKAT)
My Gridview code is
<asp:GridView ID="GridView1"
runat="server" AutoGenerateColumns="False"
CellPadding="4" DataSourceID="GridviewDataSource" ForeColor="#333333"
GridLines="None" Width="329px" AllowSorting="True" >
My DataSource code is
<asp:SqlDataSource ID="GridviewDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:SqlServerCstr %>"
SelectCommand="SELECT * FROM [AVUKAT] ORDER BY [MUSTERI]">
And one Button (Delete)
What i want is, when i show the data in Gridview all data have a checkbox (Like this picture)
And then, When i click Delete Button, deleting all checked datas on gridview and table.
How can i do that?
Best Regards,
Soner

Here is an article that answers exactly what you're looking for and is complete with full code samples: http://csharpdotnetfreak.blogspot.com/2009/04/delete-multiple-rows-gridview-checkbox.html
The magic happens when you click the Delete button. The code loops through the gridview and checks each row for a checked checkbox. When it finds a checked checkbox, it stores the ID of the row in a stringcollection. Once the entire GridView has been scanned, it then deletes all IDs in the stringcollection.
protected void btnDelete_Click(object sender, EventArgs e)
{
//Create String Collection to store
//IDs of records to be deleted
StringCollection idCollection = new StringCollection();
string strID = string.Empty;
//Loop through GridView rows to find checked rows
for (int i = 0; i < GridView1.Rows.Count; i++)
{
CheckBox chkDelete = (CheckBox)
GridView1.Rows[i].Cells[0].FindControl("chkSelect");
if (chkDelete != null)
{
if (chkDelete.Checked)
{
strID = GridView1.Rows[i].Cells[1].Text;
idCollection.Add(strID);
}
}
}
//Call the method to Delete records
DeleteMultipleRecords(idCollection);
// rebind the GridView
GridView1.DataBind();
}

Use a TemplateField, for the ItemTemplate, put there a server-side checkbox. When clicking delete, loop through the GridView.Rows collection, for item or alternate item rows, then find the checkbox in the first cell, and see if its checked, then delete if it is.
HTH.

Related

Dynamically created Items in DropDownList in GridView not working

I have a .ascx user control on an .aspx page. When the user clicks a button, information is gathered and stored in the database. Then a Gridview is databinded and in the Gridview is a dropdownlist. This dropdownlist's Items are created dynamically based on the users previous input, now in the database. This is all good and the Gridview is displayed with the dropdownlist with the dynamically created Items.
The problem is on the postback for this dropdownlist. I obviously have to recreate the Gridview with the dynamically created Items in the dropdownlist. This does not work. The postback happens and calls the Page_Init and then the Page_InitComplete. This has the databind on the Gridview which calls the SectionGV_OnRowDataBound method. The dropdownlists are recreated. But the SectionDD_OnSelectedIndexChanged method is never hit and then the dropdownlist just reverts back to its original value. I can not change the dropdownlist's selected value.
.ASCX
<asp:GridView ID="MyGV" runat="server" AutoGenerateColumns="False" DataSourceID="MyDS" Width="100%" OnRowDataBound="MyGV_OnRowDataBound">
<Columns>
<asp:TemplateField >
<ItemTemplate>
<asp:DropDownList runat="server" ID="SectionDD" AppendDataBoundItems="True" AutoPostBack="True" OnSelectedIndexChanged="SectionDD_OnSelectedIndexChanged" >
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code Behind of .ASCX
protected void Page_Init(object sender,EventArgs e)
{
this.Page.InitComplete += Page_InitComplete;
}
private void Page_InitComplete(object sender, EventArgs e)
{
MyGV.DataBind();
}
protected void SectionDD_OnSelectedIndexChanged(object sender, EventArgs e)
{
}
protected void MyGV_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
using (EntitiesModel dbContext = new EntitiesModel())
{
// get array[][] array from database
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList sectionDd = (DropDownList)e.Row.FindControl("SectionDD");
sectionDd.Items.Clear();
if (array.Length == 3)
{
if(array[0][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[0][0], array[0][1]));
if(array[1][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[1][0], array[1][1]));
if(array[2][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[2][0], array[2][1]));
}
else if (array.Length == 2)
{
if (array[0][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[0][0], array[0][1]));
if (array[1][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[1][0], array[1][1]));
}
else if (array.Length == 1)
{
if (array[0][2].ToDecimal() > 0) sectionDd.Items.Add(new ListItem(array[0][0], array[0][1]));
}
}
sectionDd.DataBind();
}
}
}
}
private void SaveToDB()
{
//save information to database
NOTE
This is one of many ways I have tried to solve this issue. The reason I have saved the information in the database is just a temporary fix. I just want to solve the issue outlined above and then I will add a ViewState solution.
First up, no, you do not have to re-create or load the grid again, or the dropdown list in the post back.
The user can type into the grid - change values, select drop downs. At that point you can loop all the grid rows and get/grab the dropdown values selected.
You CAN of course fire/trigger a event for the dropdown, but it not at all clear if you really need that event here.
If your grid is getting messed up on post-backs?, then it means you not limiting the load up in the FIRST page load - after that, it should not matter.
Say we have this grid markup:
<asp:GridView ID="MyGrid" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false" OnRowDataBound="MyGrid_RowDataBound" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server"
DataTextField="City"
DataValueField="City"
>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Province" HeaderText="Province" />
</Columns>
</asp:GridView>
And of course non templated fields (such as the first few boundField - they appear in the .Cells collection. but for templated columns, you use findcontrol.
However, in EVERY and NEAR ALL web pages, as a general rule, you ONLY load + mess + create the grid ONE time, and you ONLY do this on the first page load - END OF STORY! You don't follow this rule, then you are in a world of hurt big time.
Ok, so lets load up the grid. Since we have a dropdown, then we have to fill that out on item data bound.
So, our code will look like this:
public DataTable rstCity = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
}
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT City from City Order by City",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
// locd city for drop down list
cmdSQL.Connection.Open();
rstCity.Load(cmdSQL.ExecuteReader());
// now load grid
cmdSQL.CommandText = "SELECT * from tblHotels ORDER BY HotelName";
DataTable rst = new DataTable();
rst.Load(cmdSQL.ExecuteReader());
MyGrid.DataSource = rst;
MyGrid.DataBind();
}
}
Note how I did scope the city table to the class level (no reason to load it over and over for each row - and after the first page load, it will go out of scope - we don't care - it will live during the first page load and the data binding.
Ok, now, lets do the item data bind for the grid.
We have this:
protected void MyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList MyDrop = (DropDownList)e.Row.FindControl("DropDownList1");
MyDrop.DataSource = rstCity;
MyDrop.DataBind();
// get City from current data row source - set the drop to data row City
MyDrop.SelectedValue = ((DataRowView)e.Row.DataItem)["City"].ToString();
}
}
Ok, that's it. (note how the "dataitem" exists ONLY during data binding - a handy tip, since then you have use of the FULL data row - including PK values, and columns that you don't even include in the grid markup. But, once data binding is over, then DataItem can NOT be used - it only EVER exists during the bind process. But this information is VERY valuable, since you have full use of the Actual data SOURCE you used to bind. In above, I needed the City from that Row to set the drop list.
Ok, the output now looks like this:
Ok, at this point since we ONLY bind on first page load. The view state of that grid is 100% automatic handled by asp.net for you at this point in time.
You can drop other buttons on this form - post backs should NOT matter. The BIG lesson here is that gridview does persist (at least it will if we don't re-load it each time on post-back - you should NOT have to re-load).
Ok, next issue:
In most cases, I don't see the need for the dropdown list event in the grid?
So, you can as a general rule select and change any row combo. Once done, then you can get values of each row by looping the data grid rows - including that of dropdown selected.
However, Lets wire up the dropdown list event anyway.
tip of the day:
Since we can't select the dropdown and use the property sheet?
Then in markup do this:
You can in the markup type in OnSelectedIndexChanged=
WHEN you hit the "=" sign, note VERY close how intel-sense pops up a event create option:
So, click on CreateNewEvent - it "seems" like nothing occurs, but in fact if you flip over to code behind, you have a nice event stub created.
So lets put our code in that event - grab the row - show the value just slected.
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
// user changed the combo box
DropDownList MyDrop = (DropDownList)sender;
GridViewRow gRow = (GridViewRow)MyDrop.Parent.Parent;
Response.Write("<h2>Row index is = " + gRow.RowIndex.ToString() + "</h2>");
Response.Write("<h2>Hotel Name is = " + gRow.Cells[2].Text + "</h2>");
Response.Write("<h2>City from Drop selected = " + MyDrop.SelectedValue + "</h2>");
}
Of course we set auto post back = true in the drop markup also - right?
And note how we pick up the "sender", and then use .Parent.Parent to get the grid row that we are operating on. The first parent is some cell or some such.
I actually built recursive function to get that value, but for here we just used .parent.Parent (often with a extra markup, then you need to go op one more .parent).
Anyway, now say I select the last drop down in above, and change it.
I get this output:
In summary:
Only EVER load the grid - first page load - (you check IsPostBack).
You can have all kinds of additional post backs - the grid should survive and just be fine - no need to re-load at all. (GridView has built in viewstate).
Now, after I have fun, change the drop down on many rows?
I can loop the gridview - and any changes to that grid will persist.
In fact, if you make the columns text boxes (in templated fields), then you can tab around and edit almost like Excel, and again the values will persist for you, and they survive post backs. (and then you can send the whole grid of changes back to the database in one update command - I can show how to do this, but this post already has lots of good stuff anyway.
Now, having said the above, having done the above?
Well now that we have this working, then one can go back to building a custom user control - but if done right, it also should behave correctly, and should also survive post-backs.

how edit, delete, add gridview rows without using command buttons C# asp.net?

How can I delete, edit and add rows in a gridview with 3 buttons out of it for deleting, editing and adding rows in C# asp.net and refresh grid after changing?
I don't want to use the command buttons of the gridview that is repeated in every row.
You need to select the row some how in order for the code to know which row to delete or edit. Then you can grab the the content of that row on GridView1_SelectionChanged in order to delete or update it.
Edit:
Here is what to do:
1. Drag a gridview and a textbox to page.
2. Populate gridview
3. Override Render
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
foreach (GridViewRow row in GridView1.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
row.Attributes["onclick"] =ClientScript.GetPostBackClientHyperlink(GridView1,
"Select$" + row.DataItemIndex, true);
}
}
base.Render(writer);
}
4) In GridView1_SelectedIndexChanged event
//retrieve the id for selected row
int id=int.Parse(GridView1.SelectedDataKey.Value.ToString());
GridViewRow row = GridView1.SelectedRow;
TextBox1.Text = row.Cells[0].Text;
Now you can easily customize this simple example up to your taste.
Edit 2:
Specify the Id as DataKeyName in gridview
<asp:GridView ID="GridView1" runat="server" DataKeyNames="id"
onselectedindexchanged="GridView1_SelectedIndexChanged">
Check the updated GridView1_SelectedIndexChanged to see how to retrieve the id for selected row.

asp.net gridview onrowcommand -->( GridViewCommandEventArgs)

I want to ask how to get a text or value of a button inside the gridview?
but i want to get the text value from this onrowcommand which use GridViewCommandEventArgs as its parameter.
as if im using onrowdatabound is (GridViewRowEventArgs), which makes it easy for me to get the button.text inside the gridview
string example = ((Button)e.Row.FindControl("btnStop")).Text;
I want to get the button.text to do an if else loop inside the onrowcommand.
Anyone know how?
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" CellPadding="2" CellSpacing="2" HorizontalAlign="Center" PageSize="5" Width="133%" DataKeyNames="SurveyID" DataSourceID="SqlDataSource1"
AutoGenerateColumns="False" onrowcommand="stop_survey"
onrowdatabound="filter_select" onselectedindexchanging="selected"
>
code behind
public void filter_select(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{....
((Button)e.Row.FindControl("btnStop")).Text = "Start";
}
}
public void stop_survey(object sender, GridViewCommandEventArgs e)
{
//i want to get the "btnStop" button text which is nested on the gridview.
}
i want to get the btnStop text, as I want to have different sqlstatement depending on its text (eg. Start or Stop)
the problem is i cant do e.Row inside stop_survey.
Please guide me.
Create a object of GridViewRow from refrence of command source row.
GridViewRow row = (GridViewRow)((LinkButton)e.CommandSource).NamingContainer;
But keep in mind that which type of object control is you are using to call event in above code is LinkButton. But if You Calling Rowcommand event from Simple Button then You need to Write this:
GridViewRow row = (GridViewRow)((Button)e.CommandSource).NamingContainer;
After Creating Row Object You can simply find any control from Gridview using rowindex.
Label LabelEmail = (Label)GridView1.Rows[row.RowIndex].FindControl("LabelEmail");
Finally You Can Access that Properties of that Control.
LabelResult.Text = LabelEmail.Text;
Same as Above You can also find Datakeys of gridview using GridViewRow rowindex.
int code = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Values[0].ToString());

Adding Links to grid cells(autogenerated gridview using C#), and getting information based on what user clicked

I autogenerate a column of values from a List UserID; which is generated using stored Oracle procedure, which takes input string(if...id Like "%string%" return refcursor) ; So the UserId list looks like that in the grid:
UserID
1111555
2222111
3331113
...
Now based on search parameters lenth, this column migh be from 1 record to 10(if UserID.count>10 then error message),so everytime we see different values in the grid
My questrion is how to put links on these autogenerated UserID's(which are in cells) that when user cliks on one of them I could get the selected id(1111555) and using it show another grid to the user:)
It's probably very simple...
You can handle the OnRowDataBound event as so:
protected void GridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Display the company name in italics.
e.Row.Cells[0].Text = ""+e.Row.Cells[0].Text+"";
}
}
Where the UserID is the first column in the grid (Cell[0]). Here's the markup:
<asp:gridview id="GridView1"
autogeneratecolumns="true"
allowpaging="true"
onrowdatabound="GridView1_RowDataBound"
runat="server">
</asp:gridview>

Hide a gridView row in asp.net

I am creating a gridView that allows adding new rows by adding the controls necessary for the insert into the FooterTemplate, but when the ObjectDataSource has no records, I add a dummy row as the FooterTemplate is only displayed when there is data.
How can I hide this dummy row? I have tried setting e.row.visible = false on RowDataBound but the row is still visible.
You could handle the gridview's databound event and hide the dummy row. (Don't forget to assign the event property in the aspx code):
protected void GridView1_DataBound(object sender, EventArgs e)
{
if (GridView1.Rows.Count == 1)
GridView1.Rows[0].Visible = false;
}
Please try the following
protected void GridView1_DataBound(object sender, EventArgs e)
{
GridView1.Rows[0].Visible = false;
}
I think this is what you need:
<asp:GridView ID="grid" runat="server" AutoGenerateColumns="false" ShowFooter="true" OnRowDataBound="OnRowDataBound">
<Columns>
<asp:TemplateField HeaderText="headertext">
<ItemTemplate>
itemtext
</ItemTemplate>
<FooterTemplate>
insert controls
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and the codebehind:
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["style"] = "display:none";
}
}
But I do not understand why you are adding your "insert controls" to the footer instead of placing them below the grid.
Maybe try:
e.Row.Height = Unit.Pixel(0);
This isnt the right answer but it might work in the meantime until you get the right answer.
Maybe use CSS to set display none?!
This is the incorrect usage of the GridView control. The GridView control has a special InsertRow which is where your controls should go.
GridView has a special property to access Footer Row, named "FooterRow"
Then, you cold try yourGrid.FooterRow.Visible = false;
I did this on a previous job, but since you can add rows, I always had it visible in the footer row. To make it so that the grid shows up, I bound an empty row of the type that is normally bound
dim row as Datarow = table.NewRow()
table.AddRow(row)
gridView.DataSource = table
gridView.Databind()
then it has all the columns and then you need. You can access the footer by pulling this:
'this will get the footer no matter how many rows there are in the grid.
Dim footer as Control = gridView.Controls(0).Controls(gridView.Controls(0).Controls.Count -1)
then to access any of the controls in the footer you would go and do a:
Dim cntl as Control = footer.FindControl(<Insert Control Name Here>)
I'd assume you'd be able to do a:
footer.Visible = false
to make the footer row invisible.
I hope this helps!
Edit I just figured out what you said. I basically delete the row when I add a new one, but to do this you need to check to see if there are any other rows, and if there are, check to see if there are values in it.
To delete the dummy row do something like this:
If mTable.Rows.Count = 1 AndAlso mTable.Rows(0)(<first column to check for null value>) Is DBNull.Value AndAlso mTable.Rows(0)(<second column>) Is DBNull.Value AndAlso mTable.Rows(0)(<thrid column>) Is DBNull.Value Then
mTable.Rows.Remove(mTable.Rows(0))
End If
mTable.Rows.Add(row)
gridView.Datasource = mTable
gridView.Databind()
Why are you not using the EmptyDataTemplate? It seems to work great even though I have only been using it for a couple days...
You should use DataKeyNames in your GridView:
<asp:GridView ID="GridView1" runat="server" DataKeyNames="FooID">
And then retrieve it on your code:
GridView1.DataKeys[0].Value.ToString()
Where "0" is the number of the row you want to get the "FooID"
To make it visible, just use:
Gridview.Rows.Item(i).Attributes.Add("style", "display:block")
And to make it invisible
Gridview.Rows.Item(i).Attributes.Add("style", "display:none")
If you do not want to display data when the column/row is null:
if (!String.IsNullOrEmpty(item.DataName))
{
e.Row.Visible = false;
}
It can easily be done by SQL
USE YourdatabaseName select * from TableName where Column_Name <> ''

Categories