I'm updating the row in a grid view as well as the DataTable using the Rowcommand event but an exception occurs while assigning the values to the row in the DataTable.
protected void grduser_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Update")
{
DataTable dt = (DataTable)ViewState["dtable"];
Int32 index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = grduser.Rows[index];
// after this statement the exception occurs!
dt.Rows[row.DataItemIndex]["userid"] = ((TextBox)(row.Cells[0].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["username"] = ((TextBox)(row.Cells[1].FindControl("txtuname"))).Text;
dt.Rows[row.DataItemIndex]["usertype"] = ((TextBox)(row.Cells[2].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["email"] = ((TextBox)(row.Cells[3].Controls[0])).Text;
dt.Rows[row.DataItemIndex]["salary"] = ((TextBox)(row.Cells[4].FindControl("txtsalary"))).Text;
grduser.EditIndex = -1;
ViewState["dtable"]=dt;
grduser.DataSource = (DataTable)(ViewState["dtable"]);
grduser.DataBind();
}
}
// The grid view source below.
<asp:GridView ID="grduser" runat="server" AutoGenerateColumns="False"
onrowediting="grduser_RowEditing" onrowupdating="grduser_updateRow"
>
<Columns>
<asp:BoundField HeaderText="Id" DataField="userid"/>
<asp:TemplateField HeaderText="Name">
<EditItemTemplate>
<asp:TextBox ID="txtuname" runat="server" Text='<%# Bind("username") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("username") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="User Type" DataField="usertype" />
<asp:BoundField HeaderText="Email" DataField="email" />
<asp:TemplateField HeaderText="Salary">
<EditItemTemplate>
<asp:TextBox ID="txtsalary" runat="server" Text='<%# Bind("salary") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("salary") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Could you try this.
protected void grduser_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Update")
{
DataTable dt = (DataTable)ViewState["dtable"];
Int32 index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = grduser.Rows[index];
dt.Rows[row.DataItemIndex]["userid"] = row.Cells[0].Text;
dt.Rows[row.DataItemIndex]["username"] = ((TextBox)(row.FindControl("txtuname"))).Text;
dt.Rows[row.DataItemIndex]["usertype"] = row.Cells[2].Text;
dt.Rows[row.DataItemIndex]["email"] = row.Cells[3].Text;
dt.Rows[row.DataItemIndex]["salary"] = ((TextBox)(row.FindControl("txtsalary"))).Text;
grduser.EditIndex = -1;
ViewState["dtable"]=dt;
grduser.DataSource = (DataTable)(ViewState["dtable"]);
grduser.DataBind();
}
}
You are getting that error because your e.CommandArgument is not a valid row number from your GridView. For instance, your grduser has 3 rows and your e.CommandArgument is set to 3. This will throw a System.ArgumentOutOfRangeException because the grduser.Rows is 0-based and you are most likely setting it starting with 1.
Related
I want to read the gridview column data in c#.
I am using C# as a backend and ASP.Net as backend.
front end: asp grid view
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" onrowcommand="GridView2_RowCommand" DataKeyNames="ID" >
<Columns>
<asp:BoundField DataField="NAME" HeaderText="EVENT NAME" />
<asp:BoundField DataField="TYPE" HeaderText="TYPE OF EVENT" />
<asp:BoundField DataField="desc" HeaderText="DESCRIPTI0ON OF EVENT" />
<asp:TemplateField HeaderText="Poster">
<EditItemTemplate>
<asp:FileUpload ID="FileUpload" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Image ID="Image1" runat="server" ImageUrl='<%# Eval("poster") %>' Height="100px" Width="150px" />
</ItemTemplate>
</asp:TemplateField>
**<asp:TemplateField HeaderText="Team Name">
<EditItemTemplate>
<asp:TextBox ID="TextBox" runat="server" ></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:TextBox ID="TextBox" runat="server" ></asp:TextBox>
</ItemTemplate>**
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:ButtonField ButtonType="Button" Text="participate" CommandName="participate" HeaderText="participation" />
</Columns>
</asp:GridView>
c# protected void GridView2_RowCommand
protected void GridView2_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
con = new SqlConnection(ConfigurationManager.ConnectionStrings["Event_ManagementConnectionString"].ConnectionString);
SqlCommand cmd;
int rowindex = Convert.ToInt32(e.CommandArgument);
GridViewRow SelectedRow = GridView2.Rows[rowindex];
string id = Convert.ToString(GridView2.DataKeys[rowindex].Values[0]);
string team_name = SelectedRow.Cells[4].Text;
//= Convert.ToString(GridView2.Rows[rowindex].Values[4]);
Response.Write(team_name+"what the hell it is"+ SelectedRow.Cells[0].Text+SelectedRow.Cells[1].Text+ SelectedRow.Cells[2].Text+ SelectedRow.Cells[3].**Text+ SelectedRow.Cells[4].Text**);
if (e.CommandName == "participate")
{
if (team_name == "null")
{
Label3.Text = "Team name cant be blank";
Label3.Visible = true;
}
}
}
}
How to get the team name from the gridview?
I am unable to get data from column 4: SelectedRow.Cells[4].Text;
Team name holds in a textbox control of column 4. so, select team text control and you should get team name as text property of text box. Change code like this:
int rowindex = Convert.ToInt32(e.CommandArgument);
GridViewRow SelectedRow = GridView2.Rows[rowindex];
string id = Convert.ToString(GridView2.DataKeys[rowindex].Values[0]);
TextBox txtteam= (TextBox)SelectedRow.Cells[4].FindControl("TextBox");
string team_name = txtteam.Text;
//= Convert.ToString(GridView2.Rows[rowindex].Values[4]);
Response.Write(team_name + "what the hell it is" + SelectedRow.Cells[0].Text + SelectedRow.Cells[1].Text + SelectedRow.Cells[2].Text + SelectedRow.Cells[3].Text + txtteam.Text);
if (e.CommandName == "participate")
{
if (team_name == "null")
{
Label3.Text = "Team name cant be blank";
Label3.Visible = true;
}
}
I have a Editable GridView that I'm attempting to add sorting functionalty to specified columns. Though I receive no errors, My sorting method does not work. Could I please get some help on what I'm missing here?
The Design:
<asp:GridView ID="gvLogNotice"
runat="server"
AutoGenerateColumns="false"
ShowFooter="false"
OnRowCancelingEdit="gvLogNotice_RowCancelingEdit"
OnRowEditing="gvLogNotice_RowEditing"
OnRowUpdating="gvLogNotice_RowUpdating"
EmptyDataText="There are no data records to display."
DataKeyNames="LogNoticeID"
AllowPaging="true"
AllowSorting="true"
OnSorting="gvLogNotice_sorting"
Width="700px">
<Columns>
<asp:TemplateField HeaderText="Log No." Visible="false">
<ItemTemplate>
<%#Eval("LogNoticeID")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtLogNoticeID" runat="server" Enabled="false" Text=' <%#Eval("LogNoticeID") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Log Date" SortExpression="DateLogged">
<ItemTemplate>
<%#Eval("DateLogged")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtDateLogged" runat="server" Text=' <%#Eval("DateLogged") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Log Description" HeaderStyle-Width="50px" sortexpression="LogNoticeDescript">
<ItemTemplate>
<%#Eval("LogNoticeDescript")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtLogNoticeDescript" runat="server" Text=' <%#Eval("LogNoticeDescript") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Responsible Party" sortexpression="ResponsibleParty">
<ItemTemplate>
<%#Eval("ResponsibleParty")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtResponsibleParty" runat="server" Text=' <%#Eval("ResponsibleParty") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Planned Date" SortExpression="PlannedDate" >
<ItemTemplate>
<%#Eval("PlannedDate")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtPlannedDate" runat="server" Text=' <%#Eval("PlannedDate") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Case Number" SortExpression="CaseNumber">
<ItemTemplate>
<%#Eval("CaseNumber")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtCaseNumber" runat="server" Text=' <%#Eval("CaseNumber") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Log Status" SortExpression="LogStatus">
<ItemTemplate>
<%#Eval("LogStatus")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtLogStatus" runat="server" Text=' <%#Eval("LogStatus") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Edit">
<ItemTemplate>
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="images/edit.png" Width="25"
Height="25" CommandName="Edit" />
<%-- <asp:ImageButton ID="ImageButton2" runat="server" ImageUrl="~/img/delete.png" CommandName="Delete"
OnClientClick="return confirm('Are you sure want to delete record?')" />--%>
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Update">Update</asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CommandName="Cancel">Cancel</asp:LinkButton>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
//Page Load Event:
protected void Page_Load(object sender, EventArgs e)
{
lblmsg.Text = "";
if (!Page.IsPostBack)
{
gvLogNotice.ShowFooter = false;
//Load grid data using common method
LoadGrid();
}
}
//bind data to GV and Load
void LoadGrid()
{
sqlcmd = new SqlCommand("selectActiveLogs", sqlcon);
sqlcmd.CommandType = CommandType.StoredProcedure;
try
{
sqlcon.Open();
da = new SqlDataAdapter(sqlcmd);
dt.Clear();
da.Fill(dt);
gvLogNotice.DataSource = dt;
gvLogNotice.DataBind();
}
catch (Exception ex)
{
}
finally
{
sqlcon.Close();
}
}
//sorting event
protected void gvLogNotice_sorting(object sender, GridViewSortEventArgs e)
{
switch (e.SortExpression)
{
case "DateLogged":
if (e.SortDirection == SortDirection.Ascending)
{
LoadGrid();
}
else
{
LoadGrid();
}
break;
}
}
The SortDirection property on the GridView is changed only when the GridView is bound to a DataSource control using the DataSourceID property. Otherwise, sort direction needs to be managed manually.
In this case when we provide Data to gridView using its DataSource property , e.SortDirection will always return Ascending. And therefore only your IF statement will always get executed.
Second Point:: You need to optimize actually is just make sure you define a function to return the Data only. e.g say LoadGrid() only returns the DataTable. This way you don't need to define overloads of your LoadGrid() method. Morover, with a proper way of implementation, overloading is really not needed at all.
Third point:: is that you aren't applying sorting at all, but just loading the GridView.When you databind manually by setting the DataSource property and calling DataBind(), you need to handle the sort operation manually.
So, start by storing your sortDirection in ViewState. Simply define a public property to Get/Set the same. [ NOTE we need to store the sortDirection value according to point 1 above ]
public SortDirection SortDirection
{
get {
if (ViewState["SortDirection"] == null)
{
ViewState["SortDirection"] = SortDirection.Ascending;
}
return (SortDirection)ViewState["SortDirection"];
}
set
{
ViewState["SortDirection"] = value;
}
}
In your OnSorting event, Set the sortDirection as well as firstly sort the table and then load it into gridView.
protected void SortRecords(object sender, GridViewSortEventArgs e)
{
string sortExpression = e.SortExpression;
string direction = string.Empty;
if (SortDirection == SortDirection.Ascending)
{
SortDirection = SortDirection.Descending;
direction = " DESC";
}
else
{
SortDirection = SortDirection.Ascending;
direction = " ASC";
}
DataTable table = this.LoadGrid(); // or this.GetDataTable(), to get only the DataTable
// Now apply Sorting to your source of Data
table.DefaultView.Sort = sortExpression + direction;
// Bind the GridView
gvLogNotice.DataSource = table;
gvLogNotice.DataBind();
}
And last, your LoadGrid is fine, only thing that just fill the table and return it
private DataTable LoadGrid()
{
DataTable dt = new DataTable();
sqlcmd = new SqlCommand("selectActiveLogs", sqlcon);
sqlcmd.CommandType = CommandType.StoredProcedure;
try
{
sqlcon.Open();
da = new SqlDataAdapter(sqlcmd);
dt.Clear();
da.Fill(dt);
return dt;
}
catch (Exception ex)
{}
}
I have 4 values in List I want to bind that values in gridview row of first column
I tried with the below code but it is overwriting with the last value of list in every row
Code .aspx
<asp:GridView ID="gridActivity" runat="server" AllowSorting="true" AutoGenerateColumns="false"
CellPadding="5" CellSpacing="2" BorderStyle="None"
BorderColor="#DEBA84" Height="171px" style="margin-left: 0px; margin-right: 0px" Width="780px">
<FooterStyle ForeColor="#8C4510"
BackColor="#F7DFB5"></FooterStyle>
<PagerStyle ForeColor="#8C4510"
HorizontalAlign="Center"></PagerStyle>
<HeaderStyle Width="10px" Wrap="false" ForeColor="White" Font-Bold="True"
BackColor="SteelBlue"></HeaderStyle>
<Columns>
<asp:TemplateField HeaderText="Activities">
<ItemTemplate>
<asp:Label ID="lblActivity" runat="server" Text='<%#Eval("ActivityName") %>' CssClass="columnStyle"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Monday">
<ItemTemplate>
<asp:TextBox ID="txtMon" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Tuesday">
<ItemTemplate>
<asp:TextBox ID="txtTue" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Wednesday">
<ItemTemplate>
<asp:TextBox ID="txtWed" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Thursday">
<ItemTemplate>
<asp:TextBox ID="txtThu" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Friday">
<ItemTemplate>
<asp:TextBox ID="txtFri" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Saturday">
<ItemTemplate>
<asp:TextBox ID="txtSat" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sunday">
<ItemTemplate>
<asp:TextBox ID="txtSun" runat="server" Width ="100%"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label ID="lblTotal" runat="server" Width ="100%"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code .cs:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DbConnection.Open();
gridActivity.DataSource = Application["listActivity"];
gridActivity.DataBind();
DbConnection.Close();
}
if (Application["mondayValues"] != null)
{
//Here I can get all the values
foreach (string mon in Application["mondayValues"] as List<string>)
{
//Here is the problem
foreach (GridViewRow row in gridActivity.Rows)
{
TextBox txtMon = (TextBox)row.FindControl("txtMon");
txtMon.Text = mon;
}
}
}
}
In the below code I can get all the Monday row values and stored into Application["monday"]
protected void btnSubmit_Click(object sender, EventArgs e)
{
foreach(GridViewRow row in gridActivity.Rows)
{
TextBox txtMon = (TextBox)row.FindControl("txtMon");
Application["mondayValues"] = txtMon.Text;
mondayData = new MondayData { MondayValue = txtMon.Text };
listMonday.Add(txtMon.Text);
}
Application["mondayValues"] = listMonday;
}
Any ideas? Thanks in advance.
Try this and see what happens
if (Application["mondayValues"] != null)
{
List<string> monValues = Application["mondayValues"] as List<string>;
for (int i = 0; i <= gridActivity.Rows.Count-1; i++)
{
GridViewRow row = gridActivity.Rows[i];
TextBox txtMon = (TextBox)row.FindControl("txtMon");
txtMon.Text = monValues[i];
}
}
foreach (string mon in Application["mondayValues"] as List<string>)
{
//Here is the problem
foreach (GridViewRow row in gridActivity.Rows)
{
TextBox txtMon = (TextBox)row.FindControl("txtMon");
txtMon.Text = mon;
}
}
In the above code you last value in the list Application["mondayValues"], is being assigned to all the text boxes txtMon because you are iterating all the rows and assigning them value, any change made in earlier iteration is being lost.
This code to me is not making much of sense, can you include more details of what you are trying to to, so that we can look into the same.
I am trying to update the value of ajaxrating control and comments in the database`
` <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" DataKeyNames="id"
onrowdatabound="GridView1_RowDataBound" >
<Columns>
<asp:BoundField HeaderText="PurchasedPID" DataField="PurchasedPID"/>
<asp:BoundField HeaderText="DatetimePurchased" DataField="orderdate" />
<asp:BoundField HeaderText="MMBName" DataField="MMBName" />
<asp:TemplateField HeaderText="Rating">
<ItemTemplate>
<asp:Rating RatingDirection="LeftToRightTopToBottom" Visible="true" AutoPostBack="true"
ID="Rating2" runat="server" MaxRating="5"
StarCssClass="star_rating" EmptyStarCssClass="star_empty"
FilledStarCssClass="star_filled" WaitingStarCssClass="star_saved" CurrentRating='<%# Bind("Rating") %>'
OnChanged="Rating2_Changed" >
</asp:Rating>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Comments">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text= '<%# Bind("Comments") %>' multiline="true">
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server">Submit</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
So I added the following rowcommand event on of the members suggestion.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Submit")
{
GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
Int32 Id = Convert.ToInt32(e.CommandArgument);
int ratingScore = ((AjaxControlToolkit.Rating)row.FindControl("Rating2")).CurrentRating;
TextBox TextComments = row.FindControl("TextBox1") as TextBox;
string comments = TextComments.Text;
objBLL.UpdateRating(ratingScore, Id,comments);
}
But here instead of getting the new rating, it is inserting the CurrentRating in the table.
int ratingScore = ((AjaxControlToolkit.Rating)row.FindControl("Rating2")).CurrentRating;
I think its because of this CurrentRating here.
Any idea how to get the value of updated rating? Or should i use an additional Rating_changed event to update the rate, and then a row command event to update the comments
Thanks
Sun
The easiest way to bind the your DataKey/ItemID to the Tag attribute of the Rating control
<asp:Rating RatingDirection="LeftToRightTopToBottom" Visible="true"
AutoPostBack="true"
ID="Rating2" runat="server" MaxRating="5" **Tag='<%# Bind("id")%>'**
StarCssClass="star_rating" EmptyStarCssClass="star_empty"
FilledStarCssClass="star_filled" WaitingStarCssClass="star_saved"
CurrentRating='<%# Bind("Rating") %>'
OnChanged="Rating2_Changed" >
</asp:Rating>
Event Handler
protected void Rating2_Changed(object sender, AjaxControlToolkit.RatingEventArgs e)
{
Rating r = sender as Rating;
int id = Convert.ToInt32(r.Tag);
objBLL.UpdateRating(Convert.ToInt32(e.Value),id)
}
You can use GridView1_RowCommand to update rating score in the DB. e.g.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Rating")
{
GridViewRow row = (GridViewRow)(((ImageButton)e.CommandSource).NamingContainer);
Int32 Id = Convert.ToInt32(e.CommandArgument);
ratingScore = ((AjaxControlToolkit.Rating)row.FindControl("Rating2")).CurrentRating;
}
}
Set CommandName="Rating" to your linkbutton
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Rating">Submit</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
I have a GridView with an anonymous type. I need to check the value in a cell and highlight that cell if a condition is met. The problem is, I always get an empty string when I try to pull data out of the row's cells. I have successfully highlighted all the cells and I have checked in the Visual Studio 2010 debugger and confirmed that the Row has data (the row's DataItem has the values I need). This is happening on a PostBack, I'm not sure if that's a problem or not.
Here is the code and solutions I've tried:
protected void grvValidCourses_RowDataBound(Object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
String str = e.Row.Cells[6].Text.ToString(); // empty string
Label lbl = (Label) grvValidCourses.FindControl("lblEndDate"); // null
DataRowView rowView = (DataRowView)e.Row.DataItem; // exception about casting anonymous type
What's going on here? Why can't I get data from the cells?
Markup for GridView:
<asp:GridView ID="grvValidCourses" runat="server" Width="790px" OnRowCancelingEdit="grvValidCourses_RowCancelingEdit"
OnRowEditing="grvValidCourses_RowEditing" OnRowUpdating="grvValidCourses_RowUpdating" OnRowDeleting="grvValidCourses_RowDeleting"
AutoGenerateColumns="False" OnSelectedIndexChanged="grvValidCourses_SelectedIndexChanged"
OnRowDataBound="grvValidCourses_RowDataBound" >
<Columns>
<asp:CommandField ShowEditButton="True" EditText="Edit" UpdateText="Update |" />
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lbnDelete" runat="server" CausesValidation="False" CommandName="Delete"
Text='<%# (Eval("active") == null ? "Delete" : ((Eval("active").ToString() == "0" ? "Restore" : "Delete"))) %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowSelectButton="True" SelectText="Details" />
<asp:TemplateField HeaderText="Training Name" SortExpression="coursename">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("coursename") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("coursename") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ttNo" HeaderText="#" SortExpression="ttNo" ReadOnly="True" />
<asp:TemplateField HeaderText="Course Date" SortExpression="startDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("startdate", "{0:M/d/yyyy}") %>'></asp:TextBox>
<asp:CalendarExtender ID="TextBox3_CalendarExtender" runat="server" Enabled="True"
TargetControlID="TextBox3" Format="M/d/yyyy">
</asp:CalendarExtender>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("startdate", "{0:M/d/yyyy}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Expiry Date" SortExpression="endDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("enddate", "{0:M/d/yyy}") %>'></asp:TextBox>
<asp:CalendarExtender ID="TextBox1_CalendarExtender" runat="server" Enabled="True"
TargetControlID="TextBox1" Format="M/d/yyyy">
</asp:CalendarExtender>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblEndDate" runat="server" Text='<%# Bind("enddate", "{0:M/d/yyyy}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>No valid courses found.</EmptyDataTemplate>
</asp:GridView>
UPDATE: I've been trying all your suggestions, but I get exceptions or nulls or empty strings. I've even re-created the problem in a simpler example and still can't figure it out! I'll keep trying though, and I appreciate any new suggestions.
Part 1 - Missing Text
You are probably getting blank values in the first part due to a need to access a child control:
String str = ((DataBoundLiteralControl)e.Row.Cells[6].Controls[0]).Text;
To see if your cells have any values in debug mode (check text in debug output window):
void grvValidCourses_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
System.Diagnostics.Trace.WriteLine(e.Row.Cells.Count);
foreach (TableCell c in e.Row.Cells)
{
System.Diagnostics.Trace.WriteLine(c.Text);
}
}
}
Part 2 - Missing Control
This is wrong:
Label lbl = (Label) grvValidCourses.FindControl("lblEndDate"); // null
You can't search the gridview for a row's control. You need to search the row.
Label lblProductOptionGrpName = (Label)e.Row.FindControl("lblProductOptionGrpName");
Part 3 - Accessing DataItem
DataBinder.Eval(e.Row.DataItem, "ColumnName")
Finally, I'm not sure what you're doing with your anonymous types, but you may need to check the contents before accessing properties:
if(MyControl.GetType() == typeof(HyperLink))
{
HyperLink TestLink = (HyperLink)MyControl;
TestLink .Visible = false;
}
Okay I finally figured out what is going on! I can only access the bound field through the row (e.g. e.Row.Cells[index].Text). So I used the bound field to get the ID of my item, then found the item in the database, got the date, compared it, and highlighted the row's cells. Not the most efficient way, but it works.
Code from simple sample:
Grid View Front End
<asp:GridView ID="gdv" runat="server" AutoGenerateColumns="True" OnSelectedIndexChanged="gdv_SelectedIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" SelectText="Select" />
<asp:BoundField DataField="id" HeaderText="#" ReadOnly="True" />
<asp:TemplateField HeaderText="CategoryName" >
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description" >
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("desc") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Label ID="lblSelected" runat="server" Text="No row selected"></asp:Label>
Code Behind Page
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
var qry = ctx.Categories
.Select(c => new {
id = c.CategoryID,
name = c.CategoryName,
desc = c.Description,
});
gdv.DataSource = qry;
gdv.DataBind();
}
}
protected void gdv_SelectedIndexChanged(object sender, EventArgs e) {
selectRow();
}
private void selectRow() {
GridViewRow row = gdv.SelectedRow;
String strId = row.Cells[1].Text; // Bound Field column
lblSelected.Text = strId;
// use ID to get object from database...
}
If you can post markup, then it will be possible to figure out your issue.
You are doing this in wrong way,
this DataRowView rowView = (DataRowView)e.Row.DataItem;
should be DataRow rowView = ((DataRowView)e.Row.DataItem).Row;
protected void gridPanne_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType==DataControlRowType.DataRow)
{
Label label = (Label)e.Row.FindControl("Label4");
lbl.Text += " ** / ** "+label.Text;
}
}