I have a GridView which is showing some data:
Entity_ID (PK)
Name
Description
Now I am enabling Select in my GridView. I need to pass Entity_ID to another page and in this page I am showing more contents for this Entity_ID.
How should I pick the Entity_ID value and pass it in as Query String? I have this code:
ProductsDataGridView.SelectedRows(0).Cells(1).Value.ToString()
Any responses will be appreciated! Thank you.
Add a new item template column in you grid and add the select link as below.
<asp:TemplateField HeaderText="View Details">
<ItemTemplate>
<asp:HyperLink ID="lnkSelect" runat='server' NavigateUrl='<%# String.Format("~/detailspagename.aspx?ID={0}", Eval("Entity_ID")) %>'>Select</asp:HyperLink>
</ItemTemplate>
This is what I did:
protected void gvAgentList_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = gvAgentList.SelectedRow;
Response.Redirect("~/FrontEnd/Registration.aspx? EntityID=" + row.Cells[0].Text);
}
Use the OnRowSelected event. Once it calls that you can get the selected row and then the entity id. Next you can build a string with the entity id in the query string and response.redirect to that page.
You can also use DataKeys
set DataKeys='Entity_ID'
In the code behind you can access the same as selectedrow.DataKeys[rowindex]["Entity_ID"]
here selected row is the one you selected , rowindex the index and you get the corresponding Entity_ID
#GSGuy:
<asp:GridView runat ="server" ID = "gvAgentList"
AllowPaging = "True"
AutoGenerateSelectButton="True" AllowSorting="True" BackColor="#E8E8E8"
BorderColor="#003399" BorderStyle="Solid" BorderWidth="1px" Height="375px"
Width="823px" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="SqlDataSource1" onselectedindexchanged="gvAgentList_SelectedIndexChanged">
<AlternatingRowStyle ForeColor="#0066CC" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
<asp:TemplateField HeaderText="View Details">
<ItemTemplate>
<asp:HyperLink ID="lnkSelect" runat='server' NavigateUrl='<%# String.Format("~/detailspagename.aspx?ID={0}", Eval("Entity_ID")) %>'>Select</asp:HyperLink>
</ItemTemplate>
</Columns>
<HeaderStyle ForeColor="#3366FF" />
</asp:GridView>
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
string fname, lname;
fname = GridView1.Rows[e.NewEditIndex].Cells[0].Text;
Session["fname"] = fname;
lname = GridView1.Rows[e.NewEditIndex].Cells[1].Text;
Session["lname"] = lname;
Response.Redirect("gridpass.aspx");
}
On gridpass.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
TextBox1.Text = Session["fname"].ToString();
TextBox2.Text = Session["lname"].ToString();
}
there are several approaches how to pass data between pages:
http://msdn.microsoft.com/en-us/library/6c3yckfw.aspx
the query string is ok if you don't mind the url will contain the ID
you can also consider Page.PreviousPage from the options above, which seems reasonable in your case
Related
I'm trying to conditionally hide a template column within the Gridview, I've tried the following, but this doesn't work. Is there a way to do this within the .aspx?
<asp:TemplateField HeaderText="Grade" SortExpression="grade" Visible='<%# Convert.ToDouble(Eval("grade")) == 0 ? true : false %>'>
<ItemTemplate>
<%# string.Format("{0:0.#}", Convert.ToDouble(Eval("grade"))) %>
</ItemTemplate>
</asp:TemplateField>
you can do all of your conditional formatting (colors, hide etc.) by using the itemDataBound event. However, your sample markup does not seem to have a control - and you want to have a control for that information. And that control should have some kind of "id" or name that you can refernce in code.
However, since you did not provide much of the markup? Then I give a example for both the cells collection, and the controls that you might have.
So, say we have this simple grid view. Note how the last two fields are both City, one is a bound field (often common), and the other is a label (but could be a text box or just about any asp.net control).
<asp:GridView ID="GridView1" runat="server" CssClass="table-hover" AutoGenerateColumns="False" DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:TemplateField HeaderText ="City2">
<ItemTemplate>
<asp:Label ID="lblCity" runat="server" Text = '<%# Eval("City") %>' >'<"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Ok, on page load, we load up the above grid with this code:
protected void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack == false)
LoadGrid();
}
public void LoadGrid()
{
using (SqlCommand cmdSQL = new SqlCommand("SELECT ID, FirstName, LastName, HotelName, City from tblHotels", new SqlConnection(My.Settings.TEST3)))
{
cmdSQL.Connection.Open();
GridView1.DataSource = cmdSQL.ExecuteReader;
GridView1.DataBind();
}
}
Ok, we get this output:
Now, lets hide a column, based on say city. We say City = "Edmonton", we hide the control.
So, you use the itemData bound event.
I have in this sample both the bound fields (cells) collection hide example, and also for how do you do this with templated controls (find control).
So, the code is this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow gvRow = e.Row;
// hide a Bound field
TableCell f = gvRow.Cells(4);
if (f.Text == "Edmonton")
f.Style("Display") = "none";
// hide a templated control
Label lbl = gvRow.FindControl("lblCity");
if (lbl.Text == "Edmonton")
lbl.Style("Display") = "none";
}
}
And now the output is this:
I am passing values from a gridview to next page. The gridview is connected to a database.The gridview shows the data as I want but when I try to pass the row data of gridview to next page it throws an error 'Object reference not set to an instance of an object'.
The gridview is as follows:
<asp:GridView ID="GridView1" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White"
RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AlternatingRowStyle-ForeColor="#000"
runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" AllowPaging="True">
<AlternatingRowStyle BackColor="White" ForeColor="#000000"></AlternatingRowStyle>
<Columns>
<asp:BoundField DataField="TaskId" HeaderText="TaskId" ItemStyle-Width="30" InsertVisible="False" ReadOnly="True" SortExpression="TaskId" />
<asp:BoundField DataField="Title" HeaderText="Title" ItemStyle-Width="150" SortExpression="Title" />
<asp:BoundField DataField="Body" HeaderText="Body" SortExpression="Body" />
<asp:BoundField DataField="Reward" HeaderText="Reward" SortExpression="Reward" />
<asp:BoundField DataField="TimeAllotted" HeaderText="TimeAllotted" SortExpression="TimeAllotted" />
<asp:BoundField DataField="PosterName" HeaderText="PosterName" SortExpression="PosterName" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="Send Details" PostBackUrl='<%# "~/test/Tasks.aspx?RowIndex=" + Container.DataItemIndex %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#3AC0F2" ForeColor="White"></HeaderStyle>
<RowStyle BackColor="#A1DCF2"></RowStyle>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ABCD %>" SelectCommand="SELECT * FROM [Task]"></asp:SqlDataSource>
The code for 'Tasks.aspx.cs' is as below:
protected void Page_Load(object sender, EventArgs e)
{
if (this.Page.PreviousPage != null)
{
int rowIndex = int.Parse(Request.QueryString["RowIndex"]);
GridView GridView1 = (GridView)this.Page.PreviousPage.FindControl("GridView1");
GridViewRow row = GridView1.Rows[rowIndex];
lblTaskId.Text = row.Cells[0].Text;
lblTitle.Text = row.Cells[1].Text;
lblBody.Text = row.Cells[2].Text;
lblReward.Text = row.Cells[3].Text;
lblTimeAllotted.Text = row.Cells[4].Text;
lblPosterName.Text = row.Cells[5].Text;
}
}
I get an error message on the line below:
GridViewRow row = GridView1.Rows[rowIndex];
It would seem that FindControl method isn't actually finding the control, making your GridView1 variable null. Ensure the control is well inside the page and that the name is right.
EDIT:
If you are using master pages, there's indeed some issues with FindControl. Rick Strahls explains it in his blog:
*The problem is that when you use MasterPages the page hierarchy drastically changes.
Where a simple this.FindControl() used to give you a control instance you now have to
drill into the container hierarchy pretty deeply just to get to the content container.*
He also has an example on how to make it work. Basically, you must find your content control from the master page (using page.Master.FindControl). Then from that point you should be able to reach to your grid control.
In your scenario, since you want a control from the previous page:
var GridView1 = page.PreviousPage.Master.FindControl("ContentContainer").FindControl("GridView1") as GridView;
It looks to me like your gridview does not have any bound data when "this.Page.PreviousPage != null" is true. That is, unless you bind your data in some other initialization handler.
Because there is no data, there are no Rows which means that GridView1.Rows[rowIndex] would be null.
I'm trying to populate multiple text boxes with data from a gridview when I click the link button (which is in fact the name of one of the fields in each row) but it isn't going through. I'm new to this - literally my first time. Any help would be most appreciated.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow selectedRow = GridView1.Rows[index];
AccountNumber.Text = selectedRow.Cells[1].Text;
Name.Text = selectedRow.Cells[1].Text;
Address1.Text = selectedRow.Cells[1].Text;
Address2.Text = selectedRow.Cells[2].Text;
Address3.Text = selectedRow.Cells[3].Text;
PhoneNumber.Text = selectedRow.Cells[4].Text;
FaxNumber.Text= selectedRow.Cells[5].Text;
CurrencyID.Text = selectedRow.Cells[6].Text;
}
}
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
DataKeyNames="Agent_Account_No"
DataSourceID="SqlDataSource1"
AlternatingRowStyle-BackColor ="Lavender"
HeaderStyle-BackColor="#9966FF"
AllowSorting="True" HeaderStyle-BorderColor="Black"
HorizontalAlign="Center"
RowStyle-BorderColor="Black"
EmptyDataText="There are no data records to display."
onrowcommand ="GridView1_RowCommand">
<AlternatingRowStyle BackColor="#CCFFCC" />
<Columns>
<asp:BoundField datafield="Agent_Account_No" HeaderText="Account No"
ItemStyle-HorizontalAlign="Center"
ItemStyle-VerticalAlign="Middle"
ItemStyle-Width="50"
SortExpression="Agent_Account_No"
ReadOnly="true">
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle"
Width="50px" />
</asp:BoundField>
<asp:TemplateField HeaderText="Name" SortExpression="Agent_Name">
<ItemTemplate>
<asp:LinkButton ID="AgentName" runat="server"
Text='<%# Eval("Agent_Name") %>'
CommandName="Select"
CommandArgument='<%#Bind("Agent_Name") %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
I got it to work this way - using help from this site:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = GridView1.SelectedRow;
AccountNumber.Text = GridView1.DataKeys[row.RowIndex]["Agent_Account_No"].ToString();
......
}
I don't know if this declaration is right, but it works. However now that it works I see a problem that I didn't see before - see my profile and thanks a lot!
I would highly recommend using TemplateFields for all of your columns, like this:
Markup:
<Columns>
<asp:TemplateField HeaderText="Account No" SortExpression="Agent_Account_No">
<ItemTemplate>
<asp:Label ID="LabelAccountNumber" runat="server"
Text='<%# Eval("Agent_Account_No") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
...
<asp:TemplateField HeaderText="Name" SortExpression="Agent_Name">
<ItemTemplate>
<asp:LinkButton ID="AgentName" runat="server"
Text='<%# Eval("Agent_Name") %>'
CommandName="Select"
CommandArgument='<%#Bind("Agent_Name") %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
Now in the RowCommand method, you can use the FindControl() method of the grid view row to get to the text you are interested in, like this:
Code-behind:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow selectedRow = GridView1.Rows[index];
// Find the account number label to get the text value for the text box
Label theAccountNumberLabel = selectedRow.FindControl("LabelAccountNumber") as Label;
// Make sure we found the label before we try to use it
if(theAccountNumberLabel != null)
{
AccountNumber.Text = theAccountNumberLabel.Text;
}
// Follow the same pattern for the other labels to get other text values
}
}
I have seen similar questions but none of the answers helped me to workout this problem.
I have GridView with a ReadOnly field as follow.
GridView:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateColumns="False" DataKeyNames="projectID"
DataSourceID="SqlDataSource1"
EmptyDataText="There are no data records to display."
PageSize="5" OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True"/>
<asp:BoundField DataField="prID" HeaderText="prID" SortExpression="prID"/>
<asp:BoundField DataField="projectName" HeaderText="projectName"
SortExpression="projectName" />
<asp:BoundField DataField="projectType" HeaderText="projectType"
SortExpression="projectType" />
</Columns>
<EditRowStyle CssClass="GridViewEditRow"/>
</asp:GridView>
as you can see the prID BoundField has Readonly=True attribute.
I'm trying to get the value of the prID in code-behind when user is updating the other fields in the row.
code-behind:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = GridView1.Rows[e.RowIndex];
String d1 = ((TextBox)(row.Cells[2].Controls[0])).Text;
String d2 = ((TextBox)(row.Cells[3].Controls[0])).Text;
// this only works while the field is not readonly
string prIDUpdate = ((TextBox)(row.Cells[1].Controls[0])).Text;
}
Note: I have tried using GridView1.DataKeys[e.RowIndex] and also onRowDataBound an d setting the BoundField ready only in code-behind but I haven't been able to get results
Thanks in advance!
I saw that your DataKeyNames setting in GridView control is like this
DataKeyNames="projectID"
Then I guess that your key name is projectID not prID, isn't it?
If so, you could get data for the selected row as this line:
string id = GridView1.DataKeys[e.RowIndex]["projectID"].ToString();
And you should also add this column:
<asp:BoundField DataField="projectID" HeaderText="prID" SortExpression="projectID"/>
Did you try that?
In other way, you could try to use TemplateField instead
<Columns>
<asp:TemplateField HeaderText="prID" SortExpression="prID">
<ItemTemplate>
<asp:Label ID="lblPrId" runat="server" Text='<%# Bind("prID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="projectName" HeaderText="projectName"
SortExpression="projectName" />
<asp:BoundField DataField="projectType" HeaderText="projectType"
SortExpression="projectType" />
</Columns>
And this code to get data from prID column in GridView1_RowUpdating event handler:
Label lblPrId = row.FindControl("lblPrId") as Label;
string prId = lblPrId .Text;
Sorry if this doesn't help.
I have a GridView. I'm displaying all the users in the system in this GV and I have a button to Delete the user by updating the deleted column in the table to 1.
<asp:GridView ID="GridView1" AllowPaging="True" OnPageIndexChanging="GridView1_PageIndexChanging"
PageSize="20" runat="server" OnRowCommand="GridView1_OnRowCommand"
DataKeyNames="Id, Email" EnableViewState="false" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="buttonDelete" runat="server" CommandName="Remove" Text="Delete"
CommandArgument='<%# Eval("Id") + ";" +Eval("Email")%>'
OnClientClick='return confirm("Are you sure you want to delete this user?");' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:BoundField DataField="Status" HeaderText="Status" />
<asp:BoundField DataField="Location" HeaderText="Location" />
</Columns>
</asp:GridView>
protected void GridView1_OnRowCommand(object sender, GridViewCommandEventArgs e)
{
string cmdName = e.CommandName;
string[] commandArgs = e.CommandArgument.ToString().Split(new char[] { ';' });
string UserRowID = commandArgs[0];
string Email = commandArgs[1];
string sql = "UPDATE USERS " +
"SET [Deleted]= 1" +
"WHERE ROWID= " + UserRowID;
DataTable table = PublicClass.ExeSql_Table(sql, "Utility");
GridView1.DataBind();
}
When I click on Delete, it updates the database but it does not delete the row from the GV. I need to refresh the page or click twice to delete the row. How can I do it with one click?
You just have to load the DataSource again and bind it to the GridView:
DataTable table = PublicClass.ExeSql_Table(sql, "Utility");
GridView1.DataSource = table; // <-- you've forgotten this
GridView1.DataBind();
When you delete the row , rebind your grid with data.
Specify OnCommand Field in your linkbutton "buttonDelete"
Example :
OnCommand = "Delete_Record"
And write following code in aspx.cs
protected void Delete_Record(object sender, CommandEventArgs e)
{
GridView1.DataSource = table;
GridView1.DataBind();
}