I have a GridRow that looks like the following:
item_id name age
1 bob 13 (button)
2 tom 4 (button)
5 jim 24 (button)
In my grid view the button was added like so:
<Columns>
<asp:BoundField DataField="item_id" HeaderText="item_id"
InsertVisible="False" ReadOnly="True" SortExpression=item_id" />
<asp:BoundField DataField="name" HeaderText="name"
SortExpression="name" />
<asp:BoundField DataField="age" HeaderText="age"
SortExpression="age" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="button" runat="server" OnClick="RegisterClick" DataField="button" HeaderText="button" SortExpression="button"
CommandName="button"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Text="Register" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
How can I get the item_id value by simply clicking on the button in the row?
I would like to access the item_id value in the OnClick method. Any ideas how to make this happen?
As the other comment mentioned, bind the "item_id" instead of using the row index. Instead of:
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
Try (use single quotations instead of double):
CommandArgument='<%# Eval("item_id") %>'
In the code behind use the following to get the id:
int id = Convert.ToInt32(((Button)sender).CommandArgument);
In the CommandArgument of text box, bind the item_id instead of the row index. That's probably the fastest.
<asp:Button ID="button" runat="server" OnClick="RegisterClick" DataField="button" HeaderText="button" SortExpression="button"
CommandName="button"
CommandArgument='<%# Eval("item_id") %>'
Text="Register" />
In the button click event,
protected void RegisterClick(object sender, EventArgs e)
{
var itemId = (sender as Button).CommandArgument;
}
Related
I have following code in html
<asp:GridView ID="grdFiles" runat="server" AutoGenerateColumns="false" Width="100%" OnRowDataBound="grdFiles_RowDataBound" >
<Columns>
<asp:BoundField DataField="BatchNo" HeaderText="Batch No" />
<asp:BoundField DataField="totalspnumber" HeaderText="Total SP Number" />
<asp:BoundField DataField="VendorName" HeaderText="Vendor Name" />
<asp:BoundField DataField="Location" HeaderText="Location" />
<asp:BoundField DataField="prefix" HeaderText="Prefix" />
<asp:BoundField DataField="dateofexport" HeaderText="Date Of Export" />
<asp:BoundField DataField="ExpiryDate" HeaderText="Expiry Date" />
<asp:TemplateField>
<ItemTemplate>
<input id="downloadButton" fileid="<%# Eval("id") %>" filename="<%# Eval("exportedFileName") %>" type="button" tee="<%# Eval("isexported") %>" value="<%# Eval("isexported").ToString()=="2"?"Download again?":"Download" %>" onclick="SetFileUploaded(this)" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and I am trying to find the downloadButton in gridview OnRowDataBound event but its shows null,
here is my c# code
protected void grdFiles_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataControlFieldCell cell = (DataControlFieldCell)e.Row.Controls[7];
// Access the button
HtmlInputButton downloadButton = (HtmlInputButton)cell.FindControl("downloadButton");
// Check the condition
if (true)
{
// Hide the button
downloadButton.Visible = false;
}
}
}
Why use a "input" html button?
why not just drop in a plain jane asp.net button, and use that?
And don't bother with the gridview event model, you don't care, and don't need it. (not worth the trouble).
So, say we have this grid:
<asp:GridView ID="GridFiles" runat="server"
AutoGenerateColumns="False" ShowHeaderWhenEmpty="true" CssClass="table">
<Columns>
<asp:BoundField DataField="FileName" HeaderText="FileName" />
<asp:BoundField DataField="UpLoadTime" HeaderText="UpLoaded" />
<asp:TemplateField HeaderText="Preview">
<ItemTemplate>
<asp:Image ID="Image1" runat="server" Width="140px"
ImageUrl='<%# "UpLoadFiles/" + Eval("FileName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Download" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="cmdDownLoad"
runat="server" Text="Download" CssClass="btn"
OnClick="cmdDownLoad_Click"
CommandArgument='<%# Eval("FileName") %>' />
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code to load:
GridFiles.DataSource = MyRst("SELECT * FROM MyUpLoadFiles");
GridFiles.DataBind();
Ok, so when we click the download button in that gv?
Then this code:
protected void cmdDownLoad_Click(object sender, EventArgs e)
{
Button myBut = sender as Button;
GridViewRow gRow = myBut.NamingContainer as GridViewRow;
string strFileOnly = gRow.Cells[0].Text;
string strFile = "";
strFile = Server.MapPath(#"~/UpLoadFiles/" + strFileOnly);
string sMineType = MimeMapping.GetMimeMapping(strFileOnly);
Response.ContentType = sMineType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + strFileOnly);
Response.TransmitFile(strFile);
Response.End();
}
So, you are "always" free to pick up/get/use/enjoy the current row click with above.
And note how I did use the cell's colleciton, but since I setup the command arugment of a plain jane button with this:
CommandArgument='<%# Eval("FileName") %>'
Then code behind becomes this:
Button myBut = sender as Button;
string strFileOnly = myBut.CommandArgument;
string strFile = "";
strFile = Server.MapPath(#"~/UpLoadFiles/" + strFileOnly);
So, just use a standard everyday button, and pick up the grid view row as per above. Or use a expression for the button command argument, and you may well not even have to mess with, or worry about the grid row, but use that simple button command argument.
So, above grid when displayed looks like this:
I have a table which contains recipe for each item. Actually I wanted to update my specific column in the table. This table contains Item ID,Stock Code,Stock Name,Stock Group Name,Stock Unit Name,Amount Needed indexes. First of all ı could update and it is working, but when I want to update only my Amount column but when I press edit button, the TextBox opens for each columns. I want only amount row for the TextBox open.
This is the code:
<asp:GridView ID="grdItems" runat="server" DataKeyNames="_IdItemHam" CssClass="table" AutoGenerateColumns="False" ShowHeaderWhenEmpty="False" BorderWidth="0px" GridLines="Horizontal" OnRowDeleting="grdItems_RowDeleting" OnRowEditing="grdItems_RowEdit" meta:resourcekey="GridView5Resource1" >
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="btnSelect" runat="server" CausesValidation="false" CommandName="Delete" Text="Delete" BackColor="DarkRed" style="color: White" />
<%-- <asp:Button ID="btnUpdate" runat="server" CausesValidation="false" CommandName="Update" Text="Update" BackColor="Green" style="color: White" />
--%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button Text="Edit" runat="server" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button Text="Update" runat="server" OnClick="OnUpdate" BackColor="Green" style="color: White" />
<asp:Button Text="Cancel" runat="server" OnClick="OnCancel" BackColor="DarkRed" style="color: White"/>
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="_IdItemHam" HeaderText="Item ID" SortExpression="_IdItemHam" meta:resourcekey="BoundFieldResource9" />
<asp:BoundField DataField="item_code" HeaderText="Item Code" SortExpression="item_code" meta:resourcekey="BoundFieldResource1" />
<asp:BoundField DataField="item_name" HeaderText="Item Name" SortExpression="item_name" meta:resourcekey="BoundFieldResource2" />
<asp:BoundField DataField="item_group_name" HeaderText="Item Group Name" SortExpression="item_group_name" meta:resourcekey="BoundFieldResource3" />
<asp:BoundField DataField="item_unit_name" HeaderText="Item Unit" SortExpression="item_unit_name" meta:resourcekey="BoundFieldResource4" />
<asp:BoundField DataField="_Amount" HeaderText="Amount Needed" SortExpression="_Amount" ReadOnly="false" meta:resourcekey="BoundFieldResource6" />
<%--<asp:BoundField DataField="PROC" HeaderText="PROC" SortExpression="PROC" meta:resourcekey="BoundFieldResource8" />--%>
</Columns>
<SelectedRowStyle BackColor="#CCCCFF" />
</asp:GridView>
And here is my .cs code:
protected void OnUpdate(object sender, EventArgs e)
{
GridViewRow row = (sender as Button).NamingContainer as GridViewRow;
string amount = (row.Cells[6].Controls[0] as TextBox).Text;
//DataTable dt = ViewState["dt"] as DataTable;
//dt.Rows[row.RowIndex]["Amount Needed"] = amount;
//ViewState["dt"] = dt;
((StockRecipe.StockRecipeItemSet)ViewState["StockRecipeItemSet"]).RawMaterials.ElementAt(grdItems.EditIndex)._Amount = Double.Parse(amount);
grdItems.EditIndex = -1;
grdItems.DataSource = ((StockRecipe.StockRecipeItemSet)ViewState["StockRecipeItemSet"]).RawMaterials;
grdItems.DataBind();
CalculateProductCost();
}
Can you please help me about how to make that event. Thanks from now!
I would suggest you use the event OnRowUpdating, implemented in the GridView.
After that you can get the values and keys in the event, do your save statement and bind the grid.
<asp:GridView ID="grdItems" runat="server" DataKeyNames="_IdItemHam" CssClass="table" AutoGenerateColumns="False" ShowHeaderWhenEmpty="False" BorderWidth="0px" GridLines="Horizontal"
OnRowUpdating="grdItems_RowUpdating">
.cs code:
protected void grdItems_RowUpdating(object sender, GridViewUpdateEventArgs e){
object id = e.Keys["_IdItemHam"];
int amount = Convert.ToInt32(e.NewValues["_Amount"]);
//Do your update statment
//After that bind the grid
grdItems.DataBind();
}
use GridView_RowCommand to implement edit action
protected void GridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = 0;
GridViewRow row;
GridView grid = sender as GridView;
switch (e.CommandName)
{
case "Edit":
index = Convert.ToInt32(e.CommandArgument);
row = grid.Rows[index];
//use row to find the selected controls you need for edit, update, delete here
break;
}
}
I have a Gridview that fetches Description text from the database and once it's over some text limit, I want the Gridview to let users click "Read more" from where they can see the full text without having to navigate to a new url. Thank you in advance.
My Gridview Columns are as follows:
<asp:BoundField DataField="Id" HeaderText="Id" SortExpression="Id" InsertVisible="False" ReadOnly="True" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email" />
<asp:BoundField DataField="Source" HeaderText="Source" SortExpression="Source" />
<asp:BoundField DataField="Message" HeaderText="Message" SortExpression="Message" />
<asp:BoundField DataField="Date" HeaderText="Date" DataFormatString="{0:dd/MM/yyyy}" SortExpression ="Date" />
Add ItemTemplate with a Lable Control and LinkButton as read more in Gridview Like:
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="Label20" runat="server" Text='<%#((string)Eval("ColumnName")).Length<20?Eval("ColumnName"):((string)Eval("ColumnName")).Substring(0,20)+"..." %>' ToolTip='<%#Eval("question") %>' Width="100"></asp:Label>
<asp:LinkButton ID="LinkButton1" runat="server" Visible='<%#SetVisibility(Eval("ColumnName"),20) %>' OnClick="LinkButton1_Click">Read More...</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Here Lable text it will contain only 20 char and link button will show Read More but Lable tooltip contain all characters of that column. On Link Button click we fire an event to show all data in that Label.
protected void LinkButton1_Click(object sender, EventArgs e)
{
//Read More Link Button from Gridview on Click
LinkButton lb = (LinkButton)sender;
GridViewRow row = lb.NamingContainer as GridViewRow;
//Finding the description Text Lable
Label qst = row.FindControl("Label20") as Label;
// Setting Link Button Text
lb.Text = (lb.Text == "Read More...") ? "Hide..." : "Read More...";
//Swaping tooltip value to text and vices versa as Tooltip has all charecters
string temp = qst.Text;
qst.Text = qst.ToolTip;
qst.ToolTip = temp;
}
protected bool SetVisibility(object Desc, int length)
{
return Desc.ToString().Length > length;
}
Hope this will help you to find out your solution.
Updates:
It seems Your Column has null value to handle this you can check for null and then convert :
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="Label20" runat="server" Text='<%#Eval("ColumnName")==DBNull.Value ? string.Empty :(((string)Eval("ColumnName")).Length<20?Eval("ColumnName"):((string)Eval("ColumnName")).Substring(0,20)+"...") %>' ToolTip='<%#Eval("question") %>' Width="100"></asp:Label>
<asp:LinkButton ID="LinkButton1" runat="server" Visible='<%# Eval("ColumnName")==DBNull.Value ? false :SetVisibility(Eval("ColumnName"),20) %>' OnClick="LinkButton1_Click">Read More...</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
I would suggest using a linkbutton and binding the message in the ItemTemplate:
<asp:TemplateField HeaderText="Message">
<ItemTemplate>
<%# Bind("Message") %> - <asp:linkbutton id="btnReadMore" runat="server" causesvalidation="false" commandname="readmore" commandargument="<%# Bind("MessageId") %>" />
</ItemTemplate>
</asp:TemplateField>
The logic for the link button can then popup a
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "readmore")
{
Session["messageid"] = e.CommandArgument.ToString();
Response.Redirect("popuppage.aspx?id=" + Session["messageid"].ToString() + "");
}
}
In the popuppage.aspx will be logic to fetch the complete message using the messageid from the Query string.
I have a grid and I want to make the values in the first column "clickable" so that they fire a click event. The values in this first column are populated from a sql server query.
What would be the best way to accomplish this?
Below is my grid:
<asp:GridView runat="server" ID="HSMGrid"
AutoGenerateColumns="false"
DataKeyNames="Status"
OnRowCommand="grdvwSearchDepositTransaction_RowCommand" OnRowDataBound="grdSearch_RowDataBound" ShowHeaderWhenEmpty="true"
CssClass="grid" Width="550">
<Columns>
<asp:BoundField DataField="TransactionGroupsEntry.groupID" HeaderText="BatchID" ItemStyle-CssClass="mediumColumn columnCenter" />
<asp:BoundField DataField="TransactionGroupsEntry.bankNumber" HeaderText="Bank" ItemStyle-CssClass="mediumColumn columnCenter" />
<asp:BoundField DataField="TransactionGroupsEntry.branchNumber" HeaderText="Branch" ItemStyle-CssClass="mediumColumn columnCenter" />
<asp:BoundField DataField="TransactionGroupsEntry.cashInTicketAmount" HeaderText="Cash-In Ticket Amount" ItemStyle-CssClass="mediumColumn columnCenter" />
<asp:BoundField DataField="TransactionGroupsEntry.createdBy" HeaderText="Created By" ItemStyle-CssClass="mediumColumn columnCenter" />
<asp:BoundField DataField="TransactionGroupsEntry.dateCreated" HeaderText="Date Created" ItemStyle-CssClass="mediumColumn columnCenter" />
</Columns>
<EmptyDataTemplate>
<span style="font-weight: bold;">No Transactions have been entered</span>
</EmptyDataTemplate>
</asp:GridView>
Edit::
This is what I currently have following the advise of the first answer:
You would need to convert the first column into a template field. The template field's ItemTemplate would then contain a server side control (i.e LinkButton). This control could then have a server side OnClick event attached to it that would handle the server side logic. Below is an example:
<asp:TemplateField HeaderText="BatchID">
<ItemTemplate>
<asp:LinkButton runat="server" ID="btnBatchId" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "TransactionGroupsEntry.groupID") %>' OnClick="btnBatchId_Click" Text='<%# DataBinder.Eval(Container.DataItem, "TransactionGroupsEntry.groupID") %>' />
</ItemTemplate>
</asp:TemplateField>
In your code behind file your click event could look like the below example. I have added the ability to parse out/get at the id that is associated to the LinkButton:
protected void btnBatchId_Click(object sender, EventArgs e) {
var linkButton = sender as LinkButton;
if (linkButton != null) {
var batchId = 0;
if (int.TryParse(linkButton.CommandArgument, out batchId)) {
// batchId variable should contain a valid integer value
}
}
}
I have a gridview in my .NET web app:-
<asp:GridView ID="gvwQueues" runat="server" AutoGenerateColumns="false" OnPageIndexChanging="gvwQueues_PageIndexChanging"
PageSize="5" Width="577px">
<Columns>
<asp:BoundField DataField="Text" HeaderText="Text">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="ItemNumber" HeaderText="Item Number">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Directory" HeaderText="Directory">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:TemplateField HeaderText="IsActive">
<ItemTemplate>
<asp:CheckBox ID="Yes" runat="server" Text = "Yes" />
<asp:CheckBox ID="No" runat="server" Text = "No"/>
<%-- <asp:CheckBoxList ID="IsActive" runat="server">
<asp:ListItem>Yes.</asp:ListItem>
<asp:ListItem>No.</asp:ListItem>
</asp:CheckBoxList>--%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now I want to use the checkboxes:- "yes" or "no" to call appropriate functions on the server side that would make each item on the gridview row "Active" or "inactive".
Active means the item shows up for all users, Inactive means the item doesnt show up for any users, except for the admin.
Two modifications might me needed to make your logic work.
a. Try using Radiobutton in the place of using Check Boxes so that the user will be able to select ONLY ONE OPTION either 'Yes' or 'No'. Also note you need group these radio buttons like below to let only one of these radio buttons selectable. So replace your 'IsActive' template field with below:
<asp:TemplateField HeaderText="IsActive">
<ItemTemplate>
<asp:RadioButton ID="yesRadioButton" runat="server" Text="Yes" GroupName="IsActiveGroup" OnCheckedChanged="RadioButtonIsActive_CheckedChanged" />
<asp:RadioButton ID="noRadioButton" runat="server" Text="No" GroupName="IsActiveGroup" OnCheckedChanged="RadioButtonIsActive_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
And assign both of its CheckChanged event to RadioButtonIsActive_CheckedChanged method.
b. Below is the code for the Code behind mehtod RadioButtonIsActive_CheckedChanged
protected void RadioButtonIsActive_CheckedChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvwQueues.Rows)
{
RadioButton yesRadioButton = (RadioButton)row.FindControl("yesRadioButton");
if (yesRadioButton.Checked)
{
//Make Items Active
}
else
{
//Make Items Inactive
}
}
}
Let me know in case of any queries.
Do you want the check box to call a function when it changes?
Then all you need to do is add OnCheckedChanged
<asp:CheckBox ID="chkStatus" runat="server" Text = "Yes"
OnCheckedChanged="chkStatus_OnCheckedChanged"/>
Serverside you write the function you want it to do
public void chkStatus_OnCheckedChanged(object sender, EventArgs e)
{
//Make active inactive
}
Out side of this are you asking about roles, or binding to a grid?
you can use DataKeyNames for the grid view.
try this once.
<asp:GridView ID="gvwQueues" runat="server" AutoGenerateColumns="false" OnPageIndexChanging="gvwQueues_PageIndexChanging"
PageSize="5" Width="577px" DataKeyNames="ItemNumber">
<Columns>
<asp:BoundField DataField="Text" HeaderText="Text">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="ItemNumber" HeaderText="Item Number">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Directory" HeaderText="Directory">
<ItemStyle Width="150px"></ItemStyle>
</asp:BoundField>
<asp:TemplateField HeaderText="IsActive">
<ItemTemplate>
<asp:CheckBox ID="chkYes" runat="server" Text="Yes" OnCheckedChanged="YesOrNo_OnCheckedChanged"
AutoPostBack="true" />
<asp:CheckBox ID="chkNo" runat="server" Text="No" OnCheckedChanged="YesOrNo_OnCheckedChanged"
AutoPostBack="true" />
<%-- <asp:CheckBoxList ID="IsActive" runat="server">
<asp:ListItem>Yes.</asp:ListItem>
<asp:ListItem>No.</asp:ListItem>
</asp:CheckBoxList>--%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And you can catch the Item Number using ClientID of sender argument
protected void YesOrNo_OnCheckedChanged(object sender, EventArgs e)
{
CheckBox chkSender = (CheckBox)sender;
foreach (GridViewRow gvRow in gvwQueues.Rows)
{
if (gvRow.RowType == DataControlRowType.DataRow)
{
CheckBox chkYes = (CheckBox)gvRow.FindControl("chkYes");
CheckBox chkNo = (CheckBox)gvRow.FindControl("chkNo");
if (chkSender.ClientID == chkYes.ClientID || chkSender.ClientID == chkNo.ClientID)
{
int ItemId = Convert.ToInt32(gvwQueues.DataKeys[gvRow.RowIndex].Value);//here is the item number
if (chkNo.Checked)
{
chkYes.Checked = false;
//code to inactive
}
else if (chkYes.Checked)
{
chkNo.Checked = false;
//code to activate
}
}
}
}
}
One more suggestion is better to use Radiobuttons instead of Checkboxes.
You need to handle many conditions by using Checkboxes in your case.