I'm just at a function, which outputs a list of file names from the database. I get this also from the database and store it into a DataTable. The DataTable give the list to a DataGrid, which displays it on the page. That works fine.
My problem is that I want next to each file name have a check box on the right, which I can tick and Next time when I save the form, the database entry will be deleted.
How can I do this so the program dynamically displays the checkbox to the DataTable and the checkbox would know to which entry it has?
Best Regards
Michael Ryter
<asp:TemplateField HeaderText="name" SortExpression="Name">
<ItemTemplate>
<asp:Checkbox id="chkIsDeletable" runat="server" />
<asp:HiddenField id="hndFileId" runat="server" Value='<%#Eval("FileID")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="name" SortExpression="Name">
<ItemTemplate>
<%#Eval("filename") %>
</ItemTemplate>
</asp:TemplateField>
Now on button click event:
protected void Button_Click(object sender, EventArgs e)
{
String SelectedFileIds ="";
foreach (GridViewRow item in GridView1.Rows)
{
CheckBox chkIsDeletable = item.FindControl("chkIsDeletable") as CheckBox;
HiddenField hndFileId = item.FindControl("hndFileId") as HiddenField;
if (chkIsDeletable.Checked)
SelectedFileIds = hndFileId.Value + ",";
}
SelectedFileIds = SelectedFileIds.TrimEnd(",");
}
Now you will have all those file ids for which you have ticked the checbox, now you can delete those records from the database which contains selected fileids.
Hope, it will help you!!!
Related
GridView contains ShowDeleteButton CommandField along with other textbox fields.
I'm adding new row to this grid in C# that is adding new textboxes for each newly added row. How to add Delete link while adding new row?
<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" OnRowDataBound="Gridview1_OnRowDataBound"
OnRowDeleting="Gridview1_RowDeleting" AutoGenerateColumns="false" ShowHeaderWhenEmpty="True" EmptyDataText="No Record Available">
<asp:TemplateField HeaderText="Question">
<asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox>
</asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" ReadOnly="true" Enabled="false" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="true" />
</Columns>
</asp:GridView>
private void AddNewRow()
{
DataTable dt = new DataTable();
DataRow dr;
dt.Columns.Add(new System.Data.DataColumn("Question", typeof(String)));
dt.Columns.Add(new System.Data.DataColumn("Answer", typeof(String)));
foreach (GridViewRow row in Gridview1.Rows)
{
TextBox txtQuestion = (TextBox)row.FindControl("txtQuestion");
TextBox txtAnswer = (TextBox)row.FindControl("txtAnswer");
dr = dt.NewRow();
dr[0] = txtQuestion.Text;
dr[1] = txtAnswer.Text;
dt.Rows.Add(dr);
}
dt.Rows.Add(dt.NewRow());
dt.Rows[dt.Rows.Count - 1]["Question"] = "";
dt.Rows[dt.Rows.Count - 1]["Answer"] = "";
dt.AcceptChanges();
Gridview1.EditIndex = dt.Rows.Count - 1;
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
I recommend that you simple add the delete button to each row. That way the user can easy delete a row.
I also recommend that you load the grid one time with the datatable, and then add the row to the datatable - NOT the grid.
I could write tuckloads of advantages of this approach. But some advantages are:
user does not get presented with multiple UI
user can edit any row on the grid - not have to hit edit, or save
a single un-do button can un-do all changes
a single SAVE button in ONE operation can save the WHOLE TABLE and change back to database
Your code to add a row, and the code to setup and create the database are seperate. This means that you can change the data table, or even have the source of the table come from sql server. And as noted, this also allows you to save the WHOLE table. The result is the user can edit one rows, many rows - tab around MUCH like a excel spreadsheet. When done, they can:
hit save - all data back to database
hit un-do - un-do all their edits
hit + (add row) - add a new row to edit
hit delete key - it will delete the row in question (but UN-DO STILL ACTIVE!!!).
so we have a far more pleasant way to edit.
And thus, I suggest you don't use the built in delete button. Drop in your own button - it will look nicer anyway. (and thus no edit button required either!!!!).
So, here is our markup:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Question">
<ItemTemplate>
<asp:TextBox ID="txtQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:TextBox ID="txtAnswer" runat="server" Text='<%# Eval("Answer") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Button ID="btnAddNewQuestionnaire" runat="server" Text="+Add New Row" OnClick="btnAddNewQuestionnaire_Click" />
When you drop the button (I used a image button), then in the code editor do this:
Note how RIGHT after you hit "=" then intel-sense pops up - choose create new event. It looks like NOTHING occurs, but if you flip over to code behind, you see a code sub was generated. You can't double click on the controls inside the grid, but you CAN create a event click for a button - or in fact any event for a standard asp.net control this way.
I also to save world poverties also added a custom attribute to that button called MyRowID - this will set the row index for that button.
Since the add new row button is OUTSIDE of the grid, then we can just double click on that button, and jump to the code behind.
Now, our code looks like this:
private DataTable MyTable = new DataTable();
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
{
LoadGrid();
ViewState["MyTable"] = MyTable;
}
else
MyTable = ViewState["MyTable"];
}
public void LoadGrid()
{
MyTable.Columns.Add(new DataColumn("Question", typeof(string)));
MyTable.Columns.Add(new DataColumn("Answer", typeof(string)));
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void btnAddNewQuestionnaire_Click(object sender, EventArgs e)
{
DataRow MyRow = MyTable.NewRow;
MyRow("Question") = "my question";
MyRow("Answer") = "my ans";
MyTable.Rows.Add(MyRow);
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = sender;
int RowID = btn.Attributes.Item("MyRowID");
MyTable.Rows(RowID).Delete();
GridView1.DataSource = MyTable;
GridView1.DataBind();
}
Note VERY carefull - we added a MyTable to the form class. Thus we have a persited table, and we operate against that table.
In fact, the EXACT same above desing can be used if the data came from SQL server. And not only MORE amazing, but we can NOW thus SAVE + SEND the whole table BACK to sql server in one update operation. (you just loop the grid, put values back into table, and execute one save).
And the above has no messy edit button to edit a row. and I suppose we COULD add for extra marks a delete conformation box - the user if they bump or hit delete button, they would get a confirm dialog box. That code could be this:
<asp:ImageButton ID="ImageButton1" runat="server"
ImageUrl="~/Content/uncheck1.jpg" Height="35px" Width="45px"
OnClick="ImageButton1_Click"
MyRowID = '<%# Container.DataItemIndex %>'
OnClientClick="return confirm('Delete this row?');"/>
So now when you hit delete row, you get this:
If you click ok - it deletes - cancel - nothing occurs.
So, you can save a LOT of code and complexity here with:
Persist the data table
Pass the row ID with the button
use the intel-sense trick to wire up a separate and specific button event code.
As noted, this whole above process would ALSO work if you load the table with data from sql server - the REST of the code "as is" will work.
And to save the data back to sql server, then you can as noted:
Pull data from grid back to that persisted table. And then with a data adaptor, ONE update command will send all changes back to sql server.
It seems like this would be simple, but for the life of me, I can't figure out how it would work.
I have a gridview.
I have a standard button.
How do I use the button click to display the gridview?
Any suggestions?
This is a brief example from the MSDN page: (https://msdn.microsoft.com/en-us/library/bb907626.aspx)
You might to add an asp:TemplateField inside your GridView and through the CommandArgument property in the Button, set the current row index.
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="AddButton" runat="server"
CommandName="AddToCart"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Add to Cart" />
</ItemTemplate>
</asp:TemplateField>
And in your code, in the RowCommand event:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) {
if (e.CommandName == "AddToCart") {
// Retrieve the row index stored in the
// CommandArgument property.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button
// from the Rows collection.
GridViewRow row = GridView1.Rows[index];
// Add code here to add the item to the shopping cart.
}
}
Hope this help you.
So I have a GridView for a C# web application, that has a Buttonfield, and when that button is clicked, I need to get the value of one of the fields for that row and store it in a variable for processing in some way.
However, neither the GridView nor the ButtonField seem to possess any means of doing this.
Can anyone recommend a way of getting data from a GridView, or if this is not possible, a different type of view that does offer this functionality, while still displaying a whole table (eg, not a DetailsView)
You can Check this link: https://msdn.microsoft.com/en-us/library/bb907626(v=vs.140).aspx.
Define the CommandName of the Button.
In the GridView Define the RowCommand Event and Check the CommandName.
Get the Index of the Row.
Get the Column with GridView.Rows[index](columnIndex)
If you are using asp:TemplateField like shown below then you can access the row content using RowCommand
Markup
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblCode" runat="server" Text='<%# Eval("CustomerID") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField CommandName="AddCode" Text="Add New"/>
Code
protected void gvwSearch_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "AddCode")
{
var clickedButton = e.CommandSource as Button;
var clickedRow = clickedButton.NamingContainer as GridViewRow;
var rows_lblCode = clickedRow.FindControl("lblCode") as Label;
// now you can acccess all the label properties. For example,
var temp = rows_lblCode.Text;
}
}
ok so I have this ASP:Table which pulls its rows of info from a stored procedure query, only two columns but wish to add a third with a button for each row that when clicked will grab the information in the prior columns for use in another function.
not sure how the hell to code it though as the buttons are generated per row and how can I programme events for a unknown number of buttons there must be a way of doing It programmatically.
Table Header
Datacolumn1 Datacolumn2
a 2 Select
b 4 Select
e 9 Select
so when I press select on the second row it gives me string1=b string2=4
I imagine the code would look something like this (not likely but in a ideal world :D)
protected void select_row (eventargs as e)
{
string data1 = Row(e).cell(0).text
int data2 = Row(e).cell(1).text
}
For a grid like this
<asp:GridView ID="Grid1" runat="server" onrowcommand="Grid1_RowCommand" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Datacolumn1" HeaderText="Data column1" />
<asp:BoundField DataField="Datacolumn2" HeaderText="Data column2" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" CommandName="SelectIt" Text="Select" CommandArgument='<%# Eval("Datacolumn1") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Use RowCommand event
protected void Grid1_RowCommand(object sender, GridViewCommandEventArgs e)
{
var btn = (Button)e.CommandSource ;
if (e.CommandName == "SelectIt")
{
var Row =(GridViewRow) btn.NamingContainer;
var Datacolumn1 = Row.Cells[0].Text;
var Datacolumn2 = Row.Cells[1].Text;
btn.Text = "selected: " + Datacolumn1 + "," + Datacolumn2;
}
}
Ok... I have a database table called employees..
This has columns called ID, Name, datejoined and Cannotbedeleted (check boxes)...
Now i want to add a delete column which deletes the rows when clicked.
But there are some entries which cannot be deleted if the Cannotbedeleted field is true (checked)... so the delete button should be invisible for these rows.
Please tell me a way of how to do this...
<asp:CheckBoxField DataField="CannotBeDeleted" HeaderText="CannotBeDeleted"
SortExpression="CannotBeDeleted" />
<asp:BoundField DataField="TimeAdded" HeaderText="TimeAdded"
SortExpression="TimeAdded" />
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete" ></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I also tried using in delete template field...
' >
But i did not know what to do in code behind??
protected bool GetShowDeleteButton()
{
}
The solution is below.... but is there a way i can refresh the page once i click the delete button in the gridview....
Try looping through the rows in GridView_DataBound, and hide the button for each row that has the checkbox checked.
protected void GridView1_DataBound(object sender, EventArgs e)
{
foreach(GridViewRow myRow in GridView1.Rows)
{
//Find the checkbox
CheckBox ckbox1 = (CheckBox)myRow.FindControl("nameOfCheckBox");
if(ckbox1.Checked)
{
//Find the Delete linkbutton and hide it
LinkButton deleteButton = (LinkButton)myRow.FindControl("nameOfDeleteLinkButton");
deleteButton.Visible = false;
}
}
}
Now, here's the difference you need:
Implement the CheckBox column as a TemplateField with a CheckBox in it. You can bind the CheckBox to the data from your datasource.
Do it like this:
if($row['cannotbedeleted'] == true) {
$buttonDisplay = 'none';
}
echo "<button onclick='delete();' style='display: $buttonDisplay;'>Delete</button>";
Well that would be the solution in PHP but if the style of the button has "display: none;" in it the button will be hidden. :) HTH