Error updating row in asp.net GridView - c#

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

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.

Add different Buttons on a single column of a GridView

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.

Hyperlink in datagrid

I am inserting record in datagrid by binding it with data table and I had set autogenerate field ON for datagrid. Now all I want is first column which will comes in datagrid should be hyperlink field and when I will click on link it should redirect to another page. Please help
do like :
<ItemTemplate>
<asp:HyperLink ID="Edit" runat="server" Text="Edit" NavigateUrl='<%# Eval("DataKeyName", "~/View.aspx?Id={0}") %>' />
</ItemTemplate>
Edit:
You need to change the column type to a Hyperlink column.
and where to set is your job Sandesh
<Columns>
<asp:hyperlinkfield headertext="NewsHeadline"
datatextfield="NewsHeadline"
datanavigateurlfield="NewsURL"
datanavigateurlformatstring="http://{0}" />
</Columns>

asp.net DropDownList inside GridView

I'm using GridView and inside that I have DropDownList
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Product">
<ItemTemplate>
<asp:DropDownList ID="drop_prod" runat="server" OnSelectedIndexChanged="drop_prod_SelectedIndexChanged"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Email">
<ItemTemplate>
<asp:DropDownList ID="drop_mail" runat="server" OnSelectedIndexChanged="drop_mail_SelectedIndexChanged"></asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Dropdownlist is already populated by values(dynamically) and if user will select some other value from dropdownlist I would like to get that value without postback action.
I hope you will help me.
Thanks
"I would like to get that value without postback action."
If you dont want postback at all , you can catch dropdown change event in jquery.
<asp:DropDownList class="dropdown" ID="drop_prod" runat="server" OnSelectedIndexChanged="drop_prod_SelectedIndexChanged"></asp:DropDownList>
Note class 'dropdown' above.
$(document).ready(function(){
$(".dropdown").change(function(){
var selectedValue= $(this).val();
$(".ddl-value").val(selectedValue);
});
});
EDIT:
You can put one hidden variable in page like
<input type="hidden" id="selectedvalue" runat="server" class="ddl-value"/>
on server side access it like :
selectedvalue.Value
Add a hidden field with each dropdownlist and set the hidden field value to dropdownlist value using javascript. On submit loop through hidden field and get the value.

how to add a link button in the grid view by visual studio?

I want to add a link button in grid view that will navigate to the next form in the website. but i want to know how to insert that button into the grid view column? please help me..
You can add Link buttons in the Item template of a gridview.
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Link" runat="server" PostBackUrl="MyNextPage.aspx">Edit</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<Columns>
<asp:TemplateField>
<HeaderTemplate>
// TEXT FOR COLUMN NAME
</HeaderTemplate>
<ItemTemplate>
// ADD LINK BUTTON HERE.
</ItemTemplate>
</asp:TemplateField>
</Columns>
Add this inside grid view.
try this
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:ButtonField ButtonType="Link" HeaderText="LinkButton"/>
</Columns>
</asp:GridView>
Make Sure your GridViews datasource is bound. Set Auto-Generate Columns to false.
Open GridViewTask , add new column with Hyperlink Field proper name and path . You are done.

Categories