Greetings fellow developers. I am new to ASP.NET C# so pardon me if there are areas that I missed out/
Current in my project, I have this Gridview - where I used "TemplateField" for almost every data field. My issue is, I do not know how can I pass the value in to another page. I tried using SESSION but unfortunately, it is not working. I also tried using BOUNDFIELD, it works but it does not fulfil my project requirement as the default setting for BOUNDFIELD is textbox, I want it to be a DROPDOWN LIST control instead. Any kind advice would be much appreciated. Attached below is my codes.
WebForm1.aspx
<asp:GridView ID="Gridview1" runat="server" AutoGenerateColumns="False" OnPageIndexChanging="Gridview1_PageIndexChanging" OnRowCancelingEdit="Gridview1_RowCancelingEdit" OnRowCommand="Gridview1_RowCommand" OnRowDeleting="Gridview1_RowDeleting" OnRowEditing="Gridview1_RowEditing" OnRowUpdating="Gridview1_RowUpdating" ShowFooter="True" BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2" ShowHeaderWhenEmpty="True" Width="100%" CssClass="table table-responsive table-bordered" OnSelectedIndexChanged="Gridview1_SelectedIndexChanged" DataKeyNames="CID">
<Columns>
<asp:TemplateField HeaderText="Transaction ID">
<EditItemTemplate>
<asp:Label ID="lbleditid" runat="server" Text='<%# Bind("CID") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblid" runat="server" Text='<%# Bind("CID") %>'></asp:Label>
</ItemTemplate>
<HeaderStyle CssClass="hidden-xs" />
<ItemStyle CssClass="hidden-xs" />
</asp:TemplateField>
<asp:TemplateField HeaderText="CCID">
<EditItemTemplate>
<asp:Label ID="lblccid2" runat="server"></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblccid" runat="server" Text='<%# Bind("CCID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category" SortExpression="Category">
<EditItemTemplate>
<%--<asp:TextBox ID="txtBox_Cat" runat="server" Text='<%# Bind("Category") %>'></asp:TextBox>--%>
<asp:DropDownList ID="ddlCategory" runat="server" >
<asp:ListItem Value="--Select--">--Select--</asp:ListItem>
<asp:ListItem Value="Transportation">Transportation</asp:ListItem>
<asp:ListItem Value="Children">Children </asp:ListItem>
<asp:ListItem Value="Food">Food</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlCategory1" runat="server">
<asp:ListItem>--Select--</asp:ListItem>
<asp:ListItem>Transportation</asp:ListItem>
<asp:ListItem>Children </asp:ListItem>
<asp:ListItem>Food </asp:ListItem>
</asp:DropDownList>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Category") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Last Edited">
<EditItemTemplate>
<asp:TextBox ID="txtDateTime1" runat="server" Text='<%# Bind("Last_Edited") %>'></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtDateTime" runat="server" ToolTip="DD/MM/YYYY"></asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="lblDateTime" runat="server" Text='<%# Bind("Last_Edited") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Edit" ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="true" CommandName="AddNew" Text="Add New"></asp:LinkButton>
</FooterTemplate>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" ShowHeader="True" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton3" runat="server" OnClick="PassData">Select</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
WebForm1.aspx.cs
protected void PassData(object sender, EventArgs e)
{
GridViewRow gr = ((sender as LinkButton).NamingContainer as GridViewRow);
Session["Category"] = gr.Cells[1].Text.Trim();
Response.Redirect("AfterUserMthlyExpenses.aspx");
}
WebForm2.aspx
<asp:Label ID="lblPassCategory" runat="server" ></asp:Label>
WebForm2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Passing "Category" from previous page
lblPassCategory.Text = Session["Category"].ToString();
}
}
Well, really one should hold off on the passing of the value to the next page until such time you have a working simple answer to select/get the given row that you clicked on right?
Be it a repeater, grid view, list view (details view) etc.?
In asp.net they ALL FOLLOW the same process. You want to have that button click set/move/change to the correct given row that you clicked on. Until you have that “movement” or selection of the row occur, then you will fail at attempting to grab values from that row.
So, looking at this, you have a link button (it could be a asp.net button if want – don’t matter), you need that button to trigger/set/move/cause the row you are working on to change FIRST and BEFORE you attempt to grab data/values from that given row.
The WAY you do this is to add a special command. As noted, this works for list view/grivdview/repeater and MANY more data bound controls.
so what you learn here can apply to just about ANY data aware control (that repeats data).
So, add this to the one link button in the item template:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton3" runat="server"
CommandName = "MyJump"
CommandArgument = '<%# Eval("Category") %>'
>Select</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
So, the INSTANT you add CommandName="Select", then this will cause TWO events of the grid to fire.
OnRowComand:
The row command event will fire. But the row HAS NOT YET changed!
However, since we use CommandArgument and pass "Catagory", then we of course can use the rowcomamnd event, and pick up the CommandArgument value.
So, you can have this code in row command event:
Protected Sub GridView1_RowCommand(sender As Object, e As GridViewCommandEventArgs) Handles GridView1.RowCommand
Debug.Print("row command = " & e.CommandName)
Debug.Print("row arg = " & e.CommandArgument)
If e.CommandName = "MySelect" Then
' do whatever
End If
End Sub
Note how we don't need (you can remove) the on-click event for that button - you use the rowcommand event stub, and pick up the custom command name you passed (MySelect).
You can ALSO trigger the selected row event to fire. This would allow you to use/keep/have your EXISTING code click stub for your button.
However you now MUST change the CommandName from "your custom" name to either;
Select (move the grid pointer)
Edit - trigger edit event
Delete - trigger delete event
However, in your button click (as you have now).
You could try this:
Dim btn As Button = sender
Dim gvRow As GridViewRow = btn.Parent.Parent
Debug.Print("btn row sel = " & gvRow.RowIndex)
Debug.Print("btn argument = " & btn.CommandArgument)
So you can try btn.Parent (that will be the grid cell, and parent again will return the ONE row as you have. From that, you can grab any value out of that row.
eg:
dim myLable as label
myLabel = gvRow.FindControl("Label1")
debug.print myLabel.Text (should return catagory).
Probably most easy to just add a CommandArgument, and pick it up from sender.
Now that you first and foremost verify that you have the correct value, then you can shove that value into session. in fact you can even shove in the whole gvRow into session, and thus pass all of the values of that row to the page you jump to.
Related
I have a gridview that gets the data from a database.
Here is the .NET code. There's a lot of columns, and here the template: Choice is the one I'm talking about.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" AllowPaging="True" CellPadding="4" DataKeyNames="EmpID" ForeColor="#333333" GridLines="None" style="margin-right: 81px" Width="1174px" >
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:TemplateField HeaderText="Choice" SortExpression="Choice">
<EditItemTemplate>
<asp:DropDownList ID="DropDownChoice" Text='<%# Bind("Choice") %>' runat="server" Width="60px">
<asp:ListItem Text="No" Value="0"></asp:ListItem>
<asp:ListItem Text="Yes" Value="1"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblChoice" runat="server" Text='<%# Bind("Choice") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Here on the EditItemTemplate, the user may edit the said data on the database. Where I can use a drop down list and show the text as No or Yes but the value that will be saved on the database is still 0 and 1.
<EditItemTemplate>
<asp:DropDownList ID="DropDownChoice" Text='<%# Bind("Choice") %>' runat="server" Width="60px">
<asp:ListItem Text="No" Value="0"></asp:ListItem>
<asp:ListItem Text="Yes" Value="1"></asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
I'm having trouble of showing the text No and Yes on the Gridview once it runs. As you can see here is the ItemTemplate code:
<ItemTemplate>
<asp:Label ID="lblChoice" runat="server" Text='<%# Bind("Choice") %>'></asp:Label>
</ItemTemplate>
Please suggest a way/method to show No/Yes on the ItemTemplate/Gridview section once executed. Thanks (let me know if you might need the C# code to bind data on the gridview)
NOTE:
I have tried the RowDataBound event that was answered in this question.
here is the code:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
System.Data.DataRow dr = ((System.Data.DataRowView)e.Row.DataItem).Row;
if (dr["Choice"].ToString() == "0")
{
((Label)e.Row.FindControl("lblChoice")).Text = "No";
}
else if (dr["Choice"].ToString() == "1")
{
((Label)e.Row.FindControl("lblChoice")).Text = "Yes";
}
}
}
But it doesn't work. Am I missing something? Do I have to include something in the <ItemTemplate> tag ?
As far as I understood, you can either use Render Property function or row data bound event.
RenderProperty Function
RowDataBound Event
Both answers are from this question
Edit: As you asked how to call the RowDataBound event, it's added to the GridView tag like this:
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound"></asp:GridView>
Without using RowBound event you can do this
<ItemTemplate>
<asp:Label ID="lblChoice" runat="server"
Text='<%# Bind("Choice").Equals("1")? "Yes" : "No" %>'></asp:Label>
</ItemTemplate>
I have an example from this gridview:
<asp:GridView ID="GridView3" runat="server">
<Columns>
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("id") %>'></asp:Label>
</ItemTemplate>
<ItemStyle></ItemStyle>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("name") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("nome")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And I would like to add a button for ordering the data in each column.
Somebody can help me find the best way to do this?
Sorting is built into the GridView control. There is a control Property called AllowSorting, set this to True and you can sort columns by clicking on the header row titles.
There is no need to add extra buttons, even if you want to do some type of special sorting, you'd still Handle the Sorting event and implement your own methods
I have a problem with adding a new row with several controls like textBoxes into Header of GridView. When I add them into Header in GridView_RowCreated method with ...
if (e.Row.RowType == DataControlRowType.Header)
{
GridViewRow r = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal);
TableCell tc = new TableCell();
.. they always are put into first row, not second. How can I change it? I want my created row put in second Header Row. I tried to do it by myself, Firstly, I modified ShowHeader into false and add both first and second rows programmatically, but it is wrong way, aspecially when grid has no data to show but it is necessary to show header. I found this discussion similar discussion, but intellisence doesn't know about override PrepareControlHierarchy. I tried to search it with Object browser, and found that this is method of GridView, but I couldn't plug it and test. Maybe somebody knows easier solution for this prob.
I need some assist.
UPDATED!!!
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
CellPadding="4" DataKeyNames="username" DataSourceID="SqlDataSource1"
ForeColor="#333333" GridLines="None" onrowcreated="GridView1_RowCreated">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField HeaderText="username" SortExpression="username">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("username") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Surname" SortExpression="Surname">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Surname") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
UPDATED!!!!
Yes, profs you are right, in my case it is the easiest way to put controls in HeaderTemplate. I forgot about it. But I have a little question, how can I add names of columns without adding additional Labels? Here is my code:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
CellPadding="4" DataKeyNames="username" DataSourceID="SqlDataSource1"
ForeColor="#333333" GridLines="None" onrowcreated="GridView1_RowCreated">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField **HeaderText="username"** SortExpression="username">
<HeaderTemplate>
**<asp:Label ID="Label4" runat="server" Text="username"></asp:Label>**<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("username") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name" SortExpression="Name">
<HeaderTemplate>
<asp:Label ID="Label4" runat="server" Text="Name"></asp:Label><br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Surname" SortExpression="Surname">
<HeaderTemplate>
<asp:Label ID="Label4" runat="server" Text="Surname"></asp:Label><br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Surname") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
I marked bold strings. If I leave without Label (just with HeaderText="username") it isn't show me any name in header column. Only if I add Labels it shows my names. What is wrong with it?
Dynamically you would have to add a second header row after every has been databound
Example in VB but you should be able to convert it easily enough.
Private Sub GridView1_DataBound(sender As Object, e As EventArgs) Handles GridView1.DataBound
// Add checks for row count.
// create a new row
Dim gvr As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal)
Dim gvc As TableCell
// Create a new empty cell
gvc = New TableCell()
//add a new TextBox to the cell
gvc.Controls.Add(New TextBox())
// Add the cell to the row
gvr.Cells.Add(gvc)
// repeat above as necessary
// Add row to Gridview at index 1 (0 is bound header)
// GridView1.Controls(0) is the Gridview table
GridView1.Controls(0).Controls.AddAt(1, gvr)
End Sub
The simplest solution is to not attempt to do it in the code behind. Instead utilize the HeaderTemplate for your TemplateFields.
Here is one as an example:
<asp:TemplateField HeaderText="username" SortExpression="username">
<HeaderTemplate>
username
<br />
<asp:TextBox ID="username" runat="server" />
</HeaderTemplate>
<ItemTemplate...
</asp:TemplateField>
I need some help again.
I have a GridView with CheckBoxes in first column. If a user checks multiple CheckBoxes and clicks a button I need to display selected rows in edit mode. How do I do that? Any tips?
Some sample code, how I imagine it.
Here is my Gridview MyGV:
<asp:GridView ID="MyGV" runat="server" AutoGenerateColumns="False" DataKeyNames="ID">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="ChkBox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:TemplateField HeaderText="Column1">
<EditItemTemplate>
<asp:TextBox ID="tbColumn1" runat="server" Text='<%# Bind("column1") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="labColumn1" runat="server" Text='<%# Bind("column1") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column2">
<EditItemTemplate>
<asp:TextBox ID="tbColumn2" runat="server" Text='<%# Bind("column2") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="labColumn2" runat="server" Text='<%# Bind("column2") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnEdit" runat="server" Text="EDIT" OnClick="btnEdit_Click" />
In code behind I bind that GridView to display data from SQL table (no problem there). Now I need it to enter selected rows into edit mode (ONLY selected rows) when I click the EDIT button.
protected void btnEdit_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in MyGV.Rows)
{
CheckBox checkbox = (CheckBox)row.FindControl("ChkBox");
if (checkbox.Checked)
{
// ENTER EDIT MODE - Help needed here!! :)
}
}
BindGridView();
}
In a GridView only one row can be in true edit mode at the same time. See question below for a possible workaround:
Put multiple rows of a gridview into edit mode
I want to get the value of a hidden field in a grid view from code-behind, but not to be used in the _RowDataBound or any other similar method. Here is my present code (it is a shopping cart scenario):
<asp:GridView ID="gvShoppingCart"
runat="server"
AutoGenerateColumns="False"
AllowPaging="True"
DataKeyNames="ID"
ShowFooter="true">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="lblProductID" runat="server" Text='<%# Eval("ProductID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Product">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl='<%# Eval("ProductID", "product_details.aspx?id={0}") %>'
Text='<%# GetProduct(Eval("ProductID")) %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:TextBox ID="txtQuantity" runat="server" Width="35" CssClass="input" onkeypress="return isNumberKey(event)" AutoPostBack="true" ontextchanged="txtQuantity_TextChanged"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
For the sake of brevity I removed certain fields since they are there only for the display. The Quantity field is there for the user to input a number to add a number of products to his cart. I wish to access the lblProductID label in the _TextChanged event. In this same event, I tried
Label lblProductID = (Label)gvShoppingCart.FindControl("lblProductID");
but it didn't work and returns only a null value. What is the solution?
For each row in your GridView there is a HiddenField for the ProductID.
You can access the HiddenField of a row (in the example below the first row) by using the following code (assuming your HiddenField is in the first cell):
HiddenField hiddenFieldProductID =
(HiddenField)gvShoppingCart.Rows[0].Cells[0].FindControl("lblProductID");
string productID = hiddenFieldProductID.Value
// Do something with the value
Hope, this helps.
Try to replace the HiddenField to a label or a textbox and set the visible attribute to false.
I had tried this before and it works.