Add different Buttons on a single column of a GridView - c#

I've added an Edit button to the Action column of my Gridview using a TemplateField. I want every column to have the edit button in the first column except for the last row, which should have an Add button there instead. How would I implement this separate last row with the different button? Here is the code I have.
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="Edit" runat="server" text="Edit" OnClientClick="btnEditClick()" />
</ItemTemplate>
</asp:TemplateField>
DataTable dt = new DataTable();
dt.Columns.Add("Action");
DataRow row1 = dt.NewRow();
...
dt.Rows.Add(row1);
gridRoles.DataSource = dt;
gridRoles.DataBind();

First you have to add 2 button 1st Edit(visible) and 2nd Add (make it display=none initially)
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="Edit" runat="server" text="Edit" OnClientClick="btnEditClick()" />
<asp:Button ID="Edit" runat="server" text="Edit" OnClientClick="AddClick()" />
</ItemTemplate>
</asp:TemplateField>
Then Find Gridview Last row and find the Button Controls
GridViewRow row = GridView1.Rows[GridView1.Rows.Count-1];
Button Edit = ((Button)row.FindControl("btnedit")).Text;
Button Add = ((Button)row.FindControl("btnadd")).Text;
Edit.visible =false;
Add.Visible =true;
Here reverse the button display option : False for Edit and true for Add

That item template column is going to add whatever it's contents are to every row. One way around this is to add and empty column, and add your button during the OnRowDataBound event.
You can check to see if you are on the last row, and if so, add the other button, rather than the edit button.

One way to do it is to use the footer as the last line of the GridView. It could look like this:
<asp:GridView ID="GridView1" runat="server" ShowFooter="true" ... >
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="btnEdit" runat="server" text="Edit" OnClientClick="btnEditClick()" />
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnAdd" runat="server" text="Add" OnClientClick="btnAddClick()" />
</FooterTemplate>
</asp:TemplateField>
....
</asp:GridView>
You can look at this article for a complete example, with input controls and validation: Inserting a New Record from the GridView's Footer.

Related

I have to click the update button twice and the first time all values in the cells of the Gridview disappear

I have a Gridview set up and populated by binding my data. I have created a column that holds an "Edit" button. Clicking that button changes all of my fields to a text box populated with the data that is pulled from the database and replaces the "Edit" button with an "Update" and "Cancel" button. Up to this point all is working as intended. I change the value in the textboxes that I want to update and click the "Update" button. At this point everything is cleared out of all of the text boxes in each cell. I can enter the data again at this point and click the "Update" button a second time and any values that I have entered (the second time) will be passed back to my updating event procedure, but that is not quite the functionality I'm looking for.
I have run across a couple reports of the "Edit" button requiring 2 clicks to function, but the fixes didn't really apply to my situation.
This is my page_load
{
if (!this.IsPostBack)
{
Build_DDL();
Build_Turn_Checkbox_List();
Show_Data();
}
CheckBox_Selected_Values();
}
This is my gridview declaration:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" HeaderStyle-CssClass="headerClass" HeaderStyle-VerticalAlign="Bottom"
RowStyle-Wrap="true" HeaderStyle-Wrap="true" OnDataBound ="OnDataBound" AllowSorting="True" HeaderStyle-Height="50px"
OnSorting="GridView1_SelectedIndexChanged" CssClass="reportData" OnRowDataBound="GridView_OnRowDataBound"
OnRowCancelingEdit="GridView1_RowCancelEdit" OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating">
<HeaderStyle VerticalAlign="Bottom" Wrap="True" Height="50px" />
<RowStyle Wrap="True" CssClass="oddRow" />
<AlternatingRowStyle CssClass="evenRow" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID ="btn_Edit" runat="server" Text="Edit" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="btn_Update" runat="server" Text="Update" CommandName="Update"/>
<asp:Button ID="btn_Cancel" runat="server" Text="Cancel" CommandName="Cancel" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="State" Visible="false">
<ItemTemplate>
<asp:Label ID="lbl_state" runat="server" Text='<%#Eval("STATE") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txt_state" runat="server" Text='<%#Eval("STATE") %>'></asp:TextBox>
</EditItemTemplate>
There are more fields, but they are all built exactly the same.
Here is my update code:
{
//declare variables
string stateVal;
//set up textboxes
GridViewRow row = GridView1.Rows[e.RowIndex];
TextBox txt_State = (TextBox)row.FindControl("txt_state");
stateVal = txt_State.Text;
}
I didn't notice that when I clicked the "Edit" button on row 2, it was row 5 that was transitioning into text boxes. This was because I have the following code creating groupings in the gridview and each group creates a new row that is not accounted for in the row index scheme:
helper.RegisterGroup("State", true, true);
helper.RegisterGroup("Project Type", true, true);
helper.GroupHeader += new GroupEvent(Helper_GroupHeader);
helper.ApplyGroupSort();
GridView1.DataBind();
I will have to somehow account for the group headers and adjust the neweditindex accordingly.

Error updating row in asp.net GridView

I'm trying to understand why i'm getting the following error when executing an update on a GridView's row.
"No key property values were found during an update or delete operation. Check to ensure that key properties specified as binding expressions are available to the data source."
I've already setted the DataKeyNames property of the GridView.
The strange is i have 2 LinkButton in the same item template of the GridView: 1 for the update and one for the delete.. the delete one is working, the update one not.
Here is the piece of code in the FrontEnd of the page
<asp:GridView runat="server" ID="gridView" DataSourceID="listDataSource" AllowPaging="false" AllowSorting="false"
AutoGenerateColumns="false" AutoGenerateDeleteButton="false" AutoGenerateEditButton="false" AutoGenerateSelectButton="false" OnRowCommand="gridView_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<div class="valoriFields">
<asp:DynamicEntity runat="server" Mode="Insert" />
</div>
<div class="buttonsFields buttonsFieldsEnabled">
<asp:LinkButton runat="server" ID="btnSalva" ClientIDMode="Static" CommandName="Update" CssClass="btnSaveMulti" CausesValidation="true">
<span class="icon-save"></span>
</asp:LinkButton>
<asp:LinkButton runat="server" ID="btnDelete" ClientIDMode="Static" CommandName="Delete" CssClass="btnDeleteMulti" CausesValidation="false">
<span class="icon-delete"></span>
</asp:LinkButton>
</div>
<div style="clear:both;"></div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<ef:EntityDataSource ID="listDataSource" runat="server" EnableInsert="false" EnableDelete="true" EnableUpdate="true" OnUpdating="listDataSource_Updating" />
And the following is the CodeBehind related to the GridView and his DataSource
listDataSource.WhereParameters.Clear();
listDataSource.EntityTypeFilter = entityType.Name;
listDataSource.ContextType = contextType;
listDataSource.EntitySetName = entityType.Name;
listDataSource.AutoGenerateWhereClause = true;
listDataSource.WhereParameters.Add(parentIdName, DbType.Int32, parentID.ToString());
gridView.SetMetaTable(table, table.GetColumnValuesFromRoute(Context));
gridView.DataKeyNames = new string[] { IdName };
ThankYou
Ok i found out you have to set and EditIndex to the GridView and so it seems to work.
Now i would like to know how it works.. because u can set the EditIndex to 0 and it doesn't matter what row you are trying to edit it works anyway.
I think when you set an EditIndex u set the state of the GridView to "Edit" or something like this..
Know i have a further question.. the first time i clic on the update button it works but after the postback if i try to click and save a different row the old error come back.
Anyone knows how it really works and how to fix this second problem?
THankYou

How to select a cell in datagrid onClick in ASP.net C#

I am importing a column in datatable to my grid. Now I want navigate to a new page on selecting a cell in grid by fetching the selected value. I have tried this by including bound field in my grid like
<asp:GridView ID="GDV_1" runat="server" EnableModelValidation="true" AutoGenerateColumns="false" OnSelectedIndexChanged="GDV_1_SelectedIndexChanged" AutoGenerateSelectButton="false" DataKeyNames="SROID">
<Columns>
<asp:BoundField DataField="SRONameinEnglish" HtmlEncode="False" DataFormatString="<a target='_blank' href='Test.aspx?code={0}>ClickHere</a>" />
</Columns>
</asp:GridView>
Doing this way my requirement is achieved but the all cells are displaying Common text Click here instead of showing data from Database.
Please give your suggestion on how to get the value from database into cell and make it clickable. I don't want to use Select button. Please find my current output.
This is my current output I want my data from DB instead of ClickHere.
You can use TemplateField
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lnk<%# Eval("SRONameinEnglish")%>"><%# Eval("SRONameinEnglish")%></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
and click of LinkButton put your code to navigate anywhere.
In your case you are binding boundfield with static a tag which have href attribute so your not able to change text on that boundfield from your database.To get your approach you should
use TemplateField and bind data with text attribute using eval keyword as below example.
Try it:
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" Text='<%# Eval("name") %>' />
</ItemTemplate>
</asp:TemplateField>
OR
you can also bind link with your hyperlink using NavigateUrl property of hyperlink as below example.
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:HyperLink id="HyperLink2" NavigateUrl='<%#Eval("YourUrl") %>' Text='<%#Eval("name") %>' runat="server"/>
</ItemTemplate>
</asp:TemplateField>
I hope it will helpful to you.

Delete and Edit button on new line in a single column

I am trying to add edit, delete button on my gridview using,
<asp:CommandField HeaderText="Edit/Delete" ShowEditButton="true" ShowDeleteButton="True" />
however it looks like this now,
I want Delete button on a new row, what can I do ?
like this
Edit
Delete
Try
first convert commandbuttons to template then
adding <br /> between edit button and delete button
UPDATE In Gridview Task then Select the commands that you want to convert to TemplateField in "Selected Fields:" then check your source code. You will see in the ItemTemplate
<asp:ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit"></asp:LinkButton>
<br />
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>

Validating Entries in an ASP.NET GridView without JavaScript

Background
I have a GridView where input in Column1 depends on the input Column2.
If a user enters a N in Column2 the system will put a Y in Column1.
The Validatons are implemented using Regexs and Custom validation. I would prefer a validation solution that doesn't use JavaScript.
|Column1| Column2|
__________________
| Y | N
__________________
|N | Y
__________________
|N | N
Question
How can I validate these entries in the Gridview without using JavaScript?
Why not use two radio buttons?
<asp:templatefield>
<itemtemplate>
<asp:radiobutton id="rbYes" runat="server" groupname="YesNo" text="Yes" />
<asp:radiobutton id="rbNo" runat="server" groupname="YesNo" text="No" />
</itemtemplate>
</asp:templatefield>
You could use radio buttons and the 'Template' column feature of a GridView. The GridView markup would look like this:
<asp:GridView ID="gvTest" runat="server" AutoGenerateColumns="false"
OnRowDataBound="gvTest_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Column 1">
<ItemTemplate>
<asp:RadioButton ID="rbSelect1" runat="server" Text="" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column 2">
<ItemTemplate>
<asp:RadioButton ID="rbSelect2" runat="server" Text="" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The trick then would be to correctly set the 'GroupName' property of each radio button so that each row of the resulting grid is treated as a single radio button group by the browser. That's where the 'OnRowDataBound' handler specified on the grid comes into play. The definition of the 'gvTest_RowDataBound' handler method could be something like:
protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
RadioButton rb1 = (RadioButton)e.Row.FindControl("rbSelect1");
RadioButton rb2 = (RadioButton)e.Row.FindControl("rbSelect2");
rb1.GroupName = rb2.GroupName = string.Format("Select_{0}", e.Row.RowIndex);
}
}
By appending the row index to the group name to both of the radio buttons in each row you're going to ensure that the browser will treat them as a group and only allow the selection of one value per row. The result would look something like this:

Categories