I need to change values during edit in GridView. I'm using a method Decrypt(object) from codebehind. It works for Eval(), but not work Bind().
<asp:GridView ID="GridView1" runat="server"
DataKeyNames="ID" DataSourceID="entityDataSource1" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblTab1" runat="server"
Text='<%# Decrypt(Eval("Name")) %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="lblTab1" runat="server"
Text='<%# Decrypt(Bind("Name")) %>' />
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
When I need to do this, I usually set the TextBox Text property on the code behind on the RowDataBound event. It's like this:
protected void GridView1_RowDataBound( Object sender, System.Web.UI.WebControls.GridViewRowEventArgs e ) {
if( e.Row.RowType == DataControlRowType.DataRow && e.Row.RowState == DataControlRowState.Edit ) {
TextBox txt = ( TextBox )e.Row.FindControl( "lblTab1" );
if( txt != null ) {
DataRowView drv = ( DataRowView )e.Row.DataItem;
txt.Text = Decrypt( drv["Name"].ToString() );
}
}
}
For this work, your GridView EditIndex property must be set with your actual index being edited.
Eval() and Bind() are quite different creatures - Eval() is just shorthand for DataBinder.Eval() but Bind() is interpreted by the ASP.NET parser and broken into two parts - one for binding data to the control and the other for moving data from the control to your model.
This is described nicely in this old blog post: How ASP.NET databinding deals with Eval and Bind statements
You don't mention what you are binding to; if you are binding to a business object then you could create a getter/setter property for an un-encrypted Name. Alternatively you could provide an implementation of OnRowUpdating, and perform the Decrypt there. (hint: update the NewValues[] member with the decrypted value).
Related
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;
}
}
im not getting the valu of specic row in row data bound event , value coming null;
<asp:TemplateField>
<HeaderTemplate>
Today's pos
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lbl_TodayPos" runat="server" Text='<%# Eval("CurrentPosition") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
aspx.cs code
protected void GrdKeyWord_RowCommand(object sender, GridViewCommandEventArgs e)
{
string value = GrdKeyWord.Rows[rowindex].Cells[5].ToString();
}
The value you are looking for is stored in a label control not in a table cell. Therefore, you need to use FindControl on that row to access the lbl_TodayPos:
Label myLabel = (Label)GrdKeyWord.Rows[rowindex].FindControl("lbl_TodayPos");
string value = myLabel.Text;
If you autogenerate the columns in the gridview, or if you used 'BoundField' (instead of TemplateField) you could use .Cells[]. Because, in this case, you would have gridview rendered as pure html table with table cells.
I want to obtain the new value of a cell in the gridview rowUpdating event:
roles.RoleName = gvRoles.Rows[e.RowIndex].Cells[GetColumnIndexByName(row, "RoleName")].Text;
But the value is empty.
I have checked e.NewValues which is an ordered Dictionary. It contains the new changed value. How do I retrieve the new values for update?
aspx design is:
<asp:GridView ID="gvRoles" DataKeyNames="RoleId" runat="server"
AutoGenerateColumns="False" GridLines="Vertical" CssClass="table
table-striped table-bordered" AutoGenerateEditButton="True"
OnRowCancelingEdit="gvRoles_RowCancelingEdit" OnRowUpdating="gvRoles_RowUpdating"
OnRowEditing="gvRoles_RowEditing">
<Columns>
<asp:BoundField DataField="RoleId" HeaderText="RoleId" ReadOnly="True" />
<asp:BoundField DataField="RoleName" HeaderText="RoleName" ReadOnly="false" />
<asp:BoundField DataField="Role_Description" HeaderText="Role Description" ReadOnly="false" />
<asp:TemplateField HeaderText="RoleStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" SelectedValue='<%# Bind("Role_Status") %>' >
<asp:ListItem>True</asp:ListItem>
<asp:ListItem>False</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblRoleStatus" runat="server"
Text='<%# Bind("Role_Status") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The easiest way which i found out is to discovered e.NewValues. As I mentioned above it is an ordered dictionary and only i need to manage it.
I need to retrieve new values from this dictionary, which is done i this way.
if (!string.IsNullOrEmpty(e.NewValues["RoleName"].ToString()))
{
roles.RoleName = e.NewValues["RoleName"].ToString();
}
if you have template field it also work for it;
if (!string.IsNullOrEmpty(e.NewValues["Role_Status"].ToString()))
{
roles.Role_Status = Convert.ToBoolean(e.NewValues["Role_Status"].ToString());
}
This is the easiest thing I ever discovered. before that i want just using Find control and casting and then retrieving all lot code.
There is also e.OldValues ordered dictionary. Every one can use it to compare the new value with old ones. If values are same they could notify user to change the value(give new cell value).
GridViewRow row = (GridViewRow)gvRoles.Rows[e.RowIndex];
TextBox textRName = (TextBox)row.Cells[1].Controls[0];
string rname=textRname.Text;
Try This:
protected void gvRoles_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = gvRoles.Rows[e.RowIndex];
TextBox txtBox= (TextBox)(row.Cells[1].Controls[0]);
if(txtBox!=null)
{
String str = txtBox.Text;
}
}
After searching long and hard I found a great article that solved my issue. Take a look at the page load if you are binding on post back then the values get updated before you are able to access them.
Follow this link for more details --> https://taditdash.wordpress.com/2014/06/30/why-gridview-rowupdating-event-is-not-giving-the-updated-values/
The return data type ICollection is a bit tricky. Would have preferred a different data type than a string array but this was simplest direct conversion.
// grabs column headers
String[] keyStrings = new string[e.NewValues.Count];
System.Collections.ICollection keys = e.NewValues.Keys;
keys.CopyTo(keyStrings, 0);
// grabs edit row values
String[] valuesStrings = new string[e.NewValues.Count];
System.Collections.ICollection values = e.NewValues.Values;
values.CopyTo(valuesStrings, 0);
The end result here has two string arrays values and keys which can then be indexed, where the column header has the same index value as the cell value of the edited row.
I am trying to find a DropDownList control on the EditItemTemplate of a grid view, to populate it with results from a query before it is drawn, but the control is never found.
ddlParent == null
Always!
I may be missing something very obvious but i have tried about 8 different methods to get this find control working, but no matter what i do, it comes up null.
I have included both the ASP and the C#, the sql should not be important as i cant even reach the call!
ASP:
<asp:TemplateField SortExpression="LocationArea2.Name" HeaderText="Parent Location Area">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Eval("LocationArea2.Name") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlParent" runat="server" AppendDataBoundItems="true" DataTextField="LocationArea2.Name"
DataValueField="ParentID" AutoPostBack="false" SelectedValue='<%# Bind("ParentID") %>'>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
C#:
protected void gvLocationArea_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (gvLocationArea.EditIndex == e.Row.RowIndex)
{
DropDownList ddlParent = (DropDownList)gvLocationArea.Rows[gvLocationArea.EditIndex].FindControl("ddlParent");
if (ddlParent != null)
{
using (SalesSQLEntities db = new SalesSQLEntities())
{
ddlParent.DataSource = db.GetRecursiveAreaList(Convert.ToInt32(((TextBox)gvLocationArea.Rows[gvLocationArea.EditIndex].FindControl("txtLocationAreaID")).Text), true);
ddlParent.DataBind();
ddlParent.Items.Add(new ListItem("* None", ""));
}
}
}
}
I know there is something missing here, the control is just never found no matter what i've tried!
Instead of doing a FindControl, use an offset index of the column in question and get the first control:
(DropDownList)gvLocationArea.Rows[gvLocationArea.EditIndex].Cells[INDEX OF THE DDL].Controls[0]
I have a gridview with a hyperlink in first column. Upon clicking the hyperlink, the user is redirected to Vendor.aspx. Now, I need to pass the consumer id (of the clicked row) as a query string to the Vendor.aspx.
What is the best method to achieve it? Is there a way in which we can handle it using markup code only?
<asp:GridView ID="grdConsumers" runat="server" AutoGenerateColumns="False"
EnableViewState="True" >
<Columns>
<asp:TemplateField HeaderText="ConsumerID" SortExpression="ConsumerID" >
<ItemTemplate>
<asp:HyperLink ID="lnkConsumerID" href="Vendor.aspx" runat="server"><%# Eval("ConsumerID")%></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Status" DataField="Status" SortExpression="Status"></asp:BoundField>
</Columns>
</asp:GridView>
READINGS:
Set Gridview DataNavigateUrlFormatString Dynamically inside User Control(ASCX)
How do I add "&Source" to DataNavigateUrlFormatString?
Select row in GridView with JavaScript
How to bind the URL of a GridView HyperLinkField when the bound value contains a colon?
asp.net gridview DataNavigateUrlFormatString from DataSource
Try using the DataNavigateUrlFormatString
<ItemTemplate>
<asp:HyperLinkField DataNavigateUrlFields="ConsumerID" DataTextField="ConsumerID" DataNavigateUrlFormatString="Vendor.aspx?id={0}" />
</ItemTemplate>
... it will spare you Eval() and the problem with single/double quotes when putting it inside your href.
You can substitute the DataTextField if you like - I just put the ConsumerID there to be consistent with your example.
Rewrite your hyperlink in gridview in .aspx file like this:
<asp:HyperLink ID="lnkConsumerID" runat="server" Text='<%# Eval("ConsumerID")%>' />
Then in code-behind create a RowDataBound event handler:
protected void grdConsumers_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow) return;
var hlnkhlnk = (HyperLink)e.Row.FindControl("lnkConsumerID");
if (hlnkhlnk != null)
{
hlnkhlnk.NavigateUrl = "Vendor.aspx" + "?Consumer ID=" + hlnkhlnk.Text;
}
}
Hope it helps.
You can do same using at Grid view Item Data Bound Event
protected void grdConsumers_ItemDataBound(object sender,DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// Get your consumerId here
((HyperLink)e.Item.FindControl("Edit")).NavigateUrl = "Vendor.aspx?id=" + consumerId
}
}