Can I update a gridview column's content after databind? The SQL column is a full name, and I need to display it as last name, first name, not first name last name, as it is now. I know that i can do this in sql, but it seems as though it is going to be kind of a pain (SQL: parse the first, middle and last name from a fullname field). I was just wondering if there is an easier way to do this.
Thanks
Ok, I figured it out... sorry. In the event someone else needs this, I added a OnRowDataBound="MailingList_RowDataBound" event, and within that event handler, I have am going to use the following code (modified to parse the name):
public void MailingList_RowDataBound(object sender, GridViewRowEventArgs e)
{
// Required to ignore the header/footer.
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Get the Person's Name
string name = e.Row.Cells[0].Text;
//Add your JavaScript onClick event link.
e.Row.Attributes.Add("onClick", "LookupEmail('" + name + "')");
e.Row.Cells[0].Text = "Test";
}
}
Changing the "Test" to the correct values.
use itemtemplate
<asp:GridView ID="tset" runat="server">
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="label1" runat="server" Text='<%#GetFormattedName(Eval("full_name")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and write GetFormattedName method in code behind to return a string however you want,
protected string GetFormattedName(string fullName)
{
// you can split full name here and swap first name, last name
// depending on how you store it in DB
}
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<span>
<%# Eval("FullName").Split(' ')[0]%>
</span>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Surname">
<ItemTemplate>
<span>
<%# Eval("FullName").Split(' ')[1]%>
</span>
</ItemTemplate>
</asp:TemplateField>
This should solve your problem. Assuming the column name is FullName in your database and the first name and surname are seperated with space, you can split those and bind each value to different columns in GridView.
Related
I want to select Particular Cell value and will use to Bind Controls But i am Not able to select Cell Value
Its not retrieving data
ASPX Code
<asp:GridView ID="grdLogedUserDetails" OnRowDeleting="grdLogedUserDetails_RowDeleting" OnRowDataBound="grdLogedUserDetails_RowDataBound"
runat="server" Style="width: 100%; text-align: center" OnRowCommand="grdLogedUserDetails_RowCommand"
class="table table-striped table-bordered" AutoGenerateColumns="false" datakeynames="Ref_ID">
<Columns>
<asp:TemplateField HeaderText="Process No">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("Ref_ID") %>' ID="lblRef_ID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Company">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("CompanyName") %>' ID="lblCompanyName"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Division">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("DivisionName") %>' ID="lblDivisionName"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton ID="imgDel" runat="server" ImageUrl="~/Images/delete.png" AlternateText="Delete" CommandName="Delete" />
</ItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:ImageButton ID="imgSel" runat="server" ImageUrl="~/Images/edit-icon.png" AlternateText="Select" CommandName="Select" />
</ItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>
C#
protected void grdLogedUserDetails_RowCommand(object sender, GridViewCommandEventArgs e)
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
//Reference the GridView Row.
GridViewRow row = grdLogedUserDetails.Rows[rowIndex];
//Access Cell values.
int RefID= int.Parse(row.Cells[0].Text);
string Company= row.Cells[1].Text;
string Division= row.Cells[2].Text;
}
protected void grdLogedUserDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Access Cell values.
var RefId = int.Parse(e.Row.Cells[0].Text); // Error Input string is not in correct Formate
string Comany= e.Row.Cells[1].Text;
string Division= e.Row.Cells[2].Text;
}
}
While Debugging I can see Error Like :
"Input string is not in correct Format" Where i am doing wrong
My Table Structure
________________________________________
Ref_ID| CompanyName | DivisionName |
______|_______________|_________________|
6 | Company | Sales |
8 | Company | Sales |
14 | Company | Sales |
______|_______________|_________________|
RefID i have taken as "int" and CompanyName and DivisionName "string" so where i my input string is in wrong format,
Where i am doing wrong Please suggest me on same
The rowcommand event does not trigger rowindexed change unless you have Command="Select" but you DO HAVE Command="Select". However, you don't have a CommandArugment.
However, since you do have command=Select, then move your code to SelectedIndexChanged. The issue is you can't get/grab the row from the "row" command event since the row has not changed. The rowcommand event fires before SelectedIndexChanged. And as noted, unless you use a special command (delete or select) then SelectedIndexChanged does NOT fire.
So rowindex will NOT have been set in the row command event. However, this will mean that for your select button (and delete) your code will be (can be) in rowindexchanged "if" you use say select (or "delete") for the command. if you use a custom command name, then rowindexedchanged does NOT fire.
You can continue to use rowcommand, but you need the CommandArugment to pass either the PK of the row, or the index of the row.
So you have two choices here. (actually 3).
You can set the value of CommandArugment of that button.
Either to the PK, or you can use this
CommandArgument ='<%# Container.DataItemIndex%>'
I note that in your command settings, you are NOT setting the CommandArugment - you have to set it in your markup. The above expression will return the index into the grid.
You can move your code to rowindexchanged.
However, there is a 3rd choice. You CAN GET the rowindex in rowcommand. So from the depths of hell, you can use this stunning whopper insane of a statement:
If e.CommandName = "MySelect" Then
' now get row.
Dim gvRow As GridViewRow = CType(CType(e.CommandSource, Control).NamingContainer, GridViewRow)
Debug.Print("row index = " & gvRow.DataItemIndex)
Dim MyLabel As Label = gvRow.FindControl("HotelName")
Debug.Print("Value ref id = " & MyLabel.Text)
End If
Note VERY careful:
For the templated fields - we use find control. For non tempalted fields, then you can reference by cell.
Now that super award winning ugly way to get the row in row command?
In C# it will look like this:
{
GridViewRow gvRow = (GridViewRow)(Control)e.CommandSource.NamingContainer;
}
So, you have to use above, or as noted, move your code to SelectedIndexChanged.
Since you only have a select and delete button, then I would suggest SelectedIndexChanged. But if you were to say introduce another button - then you would not want to use Select or Delete, but a custom command name of your choosing (say CommandName="MyViewer"). In that case, then SelectedIndexChanged will not fire. But then you would have a means to determine which button was clicked upon (beyond the need of select and delete commands).
So in summary:
You have about 3+ ways to do this.
Keep in mind that in row command, the selected index event has NOT yet fired.
Keep in mind that if you use a custom row command name, then selected index WILL NOT fire.
Keep in mind that you can pick up the selected row with that award winning ugly line of code.
Keep in mind that you can't use cells() collection for your custom templated columns - so use find control.
Keep in mind that selectedindex in row command event has NOT changed nor fired yet.
Since you ARE using select, then you have a choice of row command event, or selectedindex changed event - they will both fire in your case.
The problem is that the cell does not contain any text, but a Label lblRef_ID. So you need to access the label, not the cell value.
var label = e.Row.FindControl("lblRef_ID") as Label;
var RefId = int.Parse(label.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.
Hi and thanks in advance.
I have a gridview that has four columns. The fourth column is hidden or displayed based on a set of criteria which is working correctly. But when the table displays, the very first cell in that last column is not showing any text, even though on databound it clearly shows that it has the text. So the gridview winds up showing data like this:
Name Address Zip Code
X H. Smith 123 Raton Ave.
X A. Rally 345 6th St 98453
X B. Holcomb 876 Harrison Blvd 56321
The OnRowDataBound looks like this:
protected void gvAddresses_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//This test evaluation string showed the correct data for every row
//string myvalue = DataBinder.Eval(e.Row.DataItem, "ZipCode").ToString();
if (user.State == (int)States.California)
gvAddresses.Columns[3].Visible = true;
}
}
There doesn't seem to be any problem with the binding and when I debug through the gridview each row is processed as I would expect. Here is the gridview:
<asp:GridView runat="server" ID="gvAddresses" CssClass="TableFormat gvMargin" Width="100%" AutoGenerateColumns="false"
OnRowCommand="gvAddresses_OnRowCommand" OnRowDeleting="gvAddresses_OnRowDeleting" OnRowDataBound="gvAddresses_OnRowDataBound">
<EmptyDataTemplate>
<div style="text-align: center;">No addresses available.</div>
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:LinkButton ID="lnkRemoveAddress" runat="server" OnClientClick="if(!confirm('Are you sure you want to delete this record?')) return ;" style="color: maroon; font-weight: bold;" Text="X" CommandName="Delete" CommandArgument='<%# Eval("AddressCode") %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Address" HeaderText="Address" />
<asp:BoundField DataField="ZipCode" HeaderText="Zip Code" Visible="False"/>
</Columns>
</asp:GridView>
How else can I discover what is happening to this first cell?
First problem is this: you are checking every individual row and setting the entire column to visible or not over and again. You should check for State before you databind, since it is the user object I would suggest doing it on preinit.
I suggest you remove the visible=false from your markup. When you set visible to false then the control/object isn't rendered into the HTML. Your problem will most likely be fixed if you remove the visibility attribute from the markup and assign that value at the proper time in codebehind.
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (!postback)
{
gvAddresses.Columns[3].Visible = User.State == (int)States.California;
}
}
I have a standard ASP.NET GridView and I'd like the first column (a emplateField) to be rendered as <th>, or in ASP.NET terms, I'd like to set it to the GridView RowHeaderColumn property. But that property is looking for the name of a DataItem (from a BoundColumn).
How can I render my TemplateField with <th> tags?
Finally found a workaround for this. I am not sure if this code has anything to do with good ASP.NET practices, but it does the trick:
public class FirstColumnHeaderGridView : GridView
{
protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
{
DataControlFieldCell cell = new DataControlFieldHeaderCell(fields[0]);
DataControlCellType header = DataControlCellType.DataCell;
fields[0].InitializeCell(cell, header, row.RowState, row.RowIndex);
row.Cells.Add(cell);
DataControlField[] newFields = new DataControlField[fields.Length - 1];
for (int i = 1; i < fields.Length; i++)
{
newFields[i - 1] = fields[i];
}
base.InitializeRow(row, newFields);
}
}
Let me explain what is going on here. We are creating a special type of GridView, that will render its first column using <th> tags no matter how this column is created. For this we are overriding the InitializeRow method. This method basically configures cells for the row. We are handling the first cell, and let standard GridView take care of the rest.
The configuration we are applying to the cell is fully taken from the GridView implementation and is enough for the cell to be rendered with <th> tag instead of <td>.
After that workaround the usage is absolutely standard - register our class as a server control and use it as usual GridView:
<%# Register Assembly="WebApplication1" Namespace="WebApplication1" TagPrefix="wa1" %>
...
<wa1:FirstColumnHeaderGridView ID="Grid1" runat="server" ...>
<Columns>
<asp:TemplateField>
<ItemTemplate>
Will be inside th
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
Will be inside td
</ItemTemplate>
</asp:TemplateField>
</Columns>
</wa1:FirstColumnHeaderGridView>
Is this what you mean?
<Columns>
<asp:TemplateField HeaderText="Código" ItemStyle-Width="9%">
<HeaderTemplate>
<asp:Label runat="server" Text="CodigoSAP"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat="server" ID="lblCodigoSAP" Text='<%# Bind("CodigoSAP") %>'> </asp:Label>
</ItemTemplate>
</asp:TemplateField>
I'm almost sure I'm getting the wrong idea, what do you say?
Late to the game, but we needed to set scope="row" in a middle column, not the first. To make it generic, in a derived GridView class I added the following property (similar to the GridView's built-in RowHeaderColumn property):
public int? RowHeaderColumnIndex
{
get { return (int?)ViewState["RowHeaderColumnIndex"]; }
set { ViewState["RowHeaderColumnIndex"] = value; }
}
Then set the scope:
protected override void OnRowCreated(GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && RowHeaderColumnIndex.HasValue)
{
e.Row.Cells[RowHeaderColumnIndex.Value].Attributes["scope"] = "row";
}
}
When you place your custom grid just set RowHeaderColumnIndex="0" for the first column, "1" for the 2nd column and so on.
I've searched around and haven't found a solution yet.
I have a Gridview populated by a Stored Procedure that is called by a DropdownList. The query works fine and gives me a table with values. You'll see that I programmed text in the first column to be converted to Hyperlinks.
Everything works fine with the exception that the first row (that's not the Header row) doesn't have a link. In fact, the hyperlink address is applied to the next row instead. And so it bumps the rest of the links down one row.
I did find that when debugging, it seems that the cell in what's supposed to be the first hyperlink comes up with a null ("") value. When I traverse in the IntelliSense, I do find that the row does show the correct properties (there is a text value in the DataItem > Row > ItemArray).
Client Side
<asp:TableCell>
<asp:Label ID="ddlLabel" runat="server" Text="Choose a Group Folder: " />
<asp:DropDownList ID="ddlFolders" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="ddlFolders_SelectedIndexChanged">
</asp:DropDownList>
</asp:TableCell>
<asp:TableCell ColumnSpan="2">
<asp:GridView ID="gvReportList" runat="server" AutoGenerateColumns="false"
CellPadding="5" OnRowDataBound="gvReportList_RowDataBound" Width="98%">
<Columns>
<asp:HyperLinkField HeaderText="Name" DataTextField="Name" Target="_blank" />
<asp:BoundField HeaderText="Description" DataField="Description" />
</Columns>
</asp:GridView>
</asp:TableCell>
Server Side C#
// hyperlink binding by row for first column in gridview
protected void gvReportList_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Changes text in the first column into HyperLinks
HyperLinkField nameLink = gvReportList.Columns[0] as HyperLinkField;
string linkPath = "http://inserted-address-here";
if (e.Row.RowType == DataControlRowType.DataRow)
{
//applies a unique suffix to the address depending on the link name
HyperLink nameHl = (HyperLink)e.Row.Cells[0].Controls[0];
string nameText = nameHl.Text;
string linkSuffix = nameText.Replace(" ", "+");
nameLink.NavigateUrl = linkPath + linkSuffix;
}
}
I can only assume it has something to do with the order in which I'm binding the hyperlinks to the gridview. OR that it has something to do with the first row coming up with a null value even though there's data there.
string linkSuffix = Datainder.Eval(e.DataItem, "Name").ToString().Replace(" ", "+");
nameLink.NavigateUrl = linkPath + linkSuffix;