I have a GridView like this
<asp:GridView ID="gv_FilesList" runat="server" AutoGenerateColumns="false" onrowcommand="gv_FilesList_RowCommand">
<Columns>
<asp:BoundField DataField="f_Id" Visible="false" HeaderText="File Name" />
</Columns>
<Columns>
<asp:BoundField DataField="f_Name" HeaderText="File Name" />
</Columns>
<Columns>
<asp:ButtonField ButtonType="Link" Text="Download" CommandName="DownloadFile" HeaderText="Download" />
</Columns>
</asp:GridView>
Now when I click on the download Button, how can I get the corresponding f_Id in order to get the related data from Database.
This code should work, tested on my local.
First, add DataKeyNames to your GridView.
<asp:GridView ID="gv_FilesList" runat="server" AutoGenerateColumns="false" onrowcommand="gv_FilesList_RowCommand" DataKeyNames="f_Id">
<Columns>
<asp:BoundField DataField="f_Id" Visible="false" HeaderText="File Name" />
</Columns>
<Columns>
<asp:BoundField DataField="f_Name" HeaderText="File Name" />
</Columns>
<Columns>
<asp:ButtonField ButtonType="Link" Text="Download" CommandName="DownloadFile" HeaderText="Download" />
</Columns>
</asp:GridView>
Then, access DataKeys from codebehind.
protected void gv_FilesList_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DownloadFile")
{
//row index
int index = Convert.ToInt32(e.CommandArgument);
//retrieve f_Id
int f_Id = Convert.ToInt32(gv_FilesList.DataKeys[index].Value);
//download file with f_Id
DownloadFile(f_Id);
}
}
A couple of ways to skin it, but you could access it like below:
void gv_FilesList_RowCommand(Object sender, GridViewCommandEventArgs e) {
if(e.CommandName=="DownloadFile")
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gv_FilesList.Rows[index];
string fileDownloadId = row.Cells[1].Text;
//Pull from DB
}
And then add f_id, to the DataKeyNames attribute so it will store the hidden fields value.
<asp:GridView ID="gv_FilesList" runat="server" AutoGenerateColumns="false" onrowcommand="gv_FilesList_RowCommand" DataKeyNames="f_id">
DataKeyNames
A solution to your problem is described in this thread.
Basically you can access the row index in the event argument property called CommandArgument.
Related
I have this GridView that fills on the Page_Load:
protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
GridView1.DataSource = actBO.BuscarActividades();
GridView1.DataBind();
}
}
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:BoundField DataField="Id" HeaderText="ID" Visible="False" />
<asp:BoundField DataField="Class" HeaderText="Class" />
<asp:BoundField DataField="Day" HeaderText="Day" />
<asp:BoundField DataField="Time" HeaderText="Time" />
<asp:BoundField DataField="Vacants" HeaderText="Vacants" />
<asp:ButtonField ButtonType="Button" HeaderText="Book" Text="Book"/>
</Columns>
</asp:GridView>
Where column "Vacants" shows an int (it represents the amount of vacant booking spaces in a class).
Every row will have a button to book a specific class. I need to place a condition for when the field "Vacants" is zero, so the "Book" button will be disabled.
So far this is what it looks like: image.
As you can see, I need the button to be disabled when there are no more vacants. It shouldn't be able to be clicked.
To do so, you must register OnRowDataBound event. More explanations can be found in here.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:BoundField DataField="Id" HeaderText="ID" Visible="False" />
<asp:BoundField DataField="Class" HeaderText="Class" />
<asp:BoundField DataField="Day" HeaderText="Day" />
<asp:BoundField DataField="Time" HeaderText="Time" />
<asp:BoundField DataField="Vacants" HeaderText="Vacants" />
<asp:ButtonField ButtonType="Button" HeaderText="Book" Text="Book"/>
</Columns>
</asp:GridView>
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// get your button via the column index; ideally you could use template field and put your own button inside
var button = e.Row.Cell[5].Controls[0] as Button;
int vacant = 0;
var vacantVal = int.TryParse(e.Row.Cell[4].Text, out vacant);
if (button != null)
{
button.Enabled = vacant > 0;
}
}
}
Hope it helps.
I have a Gridview which also contains a button field. When this button on a particular row is clicked, I want it to update my database. For example, if a row contains (SN = 1) I want it to update the button to update the database with the row that contains "SN = 1". How do I get the SN of the row when the button on that same row is clicked?
This is my Gridview definition:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" Height="326px" OnPageIndexChanging="GridView1_PageIndexChanging" PageSize="5" style="text-align: left; margin-left: 169px" Width="1069px" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" OnRowDataBound="GridView1_RowDataBound" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:BoundField HeaderText="S/N" DataField="SN" />
<asp:BoundField HeaderText="First Name" DataField="FirstName" />
<asp:BoundField HeaderText="Address" DataField="Address" />
<asp:BoundField HeaderText="Phone Number" DataField="PhoneNumber" />
<asp:BoundField HeaderText="Sex" DataField="Sex" />
<asp:BoundField HeaderText="Reason" DataField="Reason" />
<asp:BoundField HeaderText="SignIn" DataField="SignIn_Time" />
<asp:BoundField HeaderText="SignOut" DataField="Signout_Time" />
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="out" runat="server" Text="Sign out" CommandName="SignOut"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerSettings FirstPageText="First" LastPageText="Last" Mode="NumericFirstLast" PageButtonCount="5" />
</asp:GridView>
Here, when the row button is clicked, I want to update my database with the signout time. I can't seem to get it to get the SN of the row and update.
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "SignOut")
{
}
}
If the value you seek is the comes from the same datasource, you can add the value as a CommandArgument:
<asp:TemplateField HeaderText="Action">
<ItemTemplate>
<asp:Button ID="out"
runat="server"
Text="Sign out"
CommandName="SignOut"
CommandArgument='<%# Eval("SN") %>'/>
</ItemTemplate>
</asp:TemplateField>
On your code behind:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "SignOut")
{
string sn = e.CommandArgument.ToString();
if (sn == "1")
{
/*DO STUFF....*/
}
}
}
I have a HiddenField in my GridView. A very small empty column appears, how can I get rid of the empty column?
<asp:GridView ID="GridView1" autogeneratecolumns="false" runat="server"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
autogenerateSelectButton="true">
<Columns>
<asp:BoundField datafield ="Song" headertext="Song"/>
<asp:BoundField datafield ="Album" headertext="Album"/>
<asp:BoundField datafield ="Artist" headertext="Artist"/>
<asp:BoundField datafield ="Genre" headertext="Genre"/>
<asp:BoundField datafield ="Price" headertext="Price"/>
<asp:BoundField datafield ="Explicit Lyrics" headertext="Explicit Lyrics"/>
<asp:TemplateField>
<ItemTemplate>
<asp:HiddenField ID="HiddenField" runat="server" Value='<%# Eval("SongID")%>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Here is the output
I think you added that hidden field to get id later. No need to add and hide a column. Use datakey .
TemplateField in GridView is meant to represent a field that displays custom content in a data-bound control and HiddenField used to store a non-displayed value.
You are creating a custom content column with a non-displayed value ,that leads to create a column with null as represented view for Front end. So If you want to fetch the value on selected index change of GridView then may use Following methods:
Method1: Use Datakey for grideview to store the datacolumn you want in your selecetedIndexchanged method:
<asp:GridView ID="GridView1" autogeneratecolumns="false" runat="server"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
autogenerateSelectButton="true" DataKeyNames="SongID">
<Columns>
<asp:BoundField datafield ="Song" headertext="Song"/>
<asp:BoundField datafield ="Album" headertext="Album"/>
<asp:BoundField datafield ="Artist" headertext="Artist"/>
<asp:BoundField datafield ="Genre" headertext="Genre"/>
<asp:BoundField datafield ="Price" headertext="Price"/>
<asp:BoundField datafield ="Explicit Lyrics" headertext="Explicit Lyrics"/>
</Columns>
</asp:GridView>
To access that key on SelectedIndexChanged Method :
int songId= Convert.ToInt32(GridView1.DataKeys[GridView1.SelectedIndex].Values);
Method2: Add hiddenfield within any column you have in your gridview not a special one for it.
<asp:GridView ID="GridView1" autogeneratecolumns="false" runat="server"
OnSelectedIndexChanged="GridView1_SelectedIndexChanged"
autogenerateSelectButton="true">
<Columns>
<asp:BoundField datafield ="Song" headertext="Song"/>
<asp:BoundField datafield ="Album" headertext="Album"/>
<asp:BoundField datafield ="Artist" headertext="Artist"/>
<asp:BoundField datafield ="Genre" headertext="Genre"/>
<asp:BoundField datafield ="Price" headertext="Price"/>
<asp:TemplateField headertext="Explicit Lyrics" >
<ItemTemplate>
<asp:Lable runat="server" ID="lblexp" Text='<%# Eval("Explicit Lyrics")%>'>
<asp:HiddenField ID="HiddenField" runat="server" Value='<%# Eval("SongID")%>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You could add this:
<style>
.hidden {display:none;}
</style>
And adding these properties to the asp:HiddenField or ItemTemplate element
ItemStyle-CssClass="hidden" and
HeaderStyle-CssClass="hidden :) let me know if it worked.
You can set the CellPadding and CellSpacing attributes of the GridView to zero:
<asp:GridView CellPadding="0" CellSpacing="0" ... >
If you still see the column you can set its width to zero:
<asp:TemplateField ItemStyle-Width="0" HeaderStyle-Width="0" ... >
On Gridview RowDataBound function add the below code to hide the columns you want.
Eg:
In the aspx,
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound">
In code behind,
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cells[cellno.].Visible = false;
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[cellno.].Visible = false;
}
}
I have a gridview,
When Button ADD is clicked the textboxs values will be added to gridview.
After adding values to gridview i want to select a row and click delete button but error occurs to me on deleting.
My GridView Code
<asp:GridView ClientIDMode="Static" ID="GridPesonal" runat="server" AutoGenerateColumns="False" Class="GrdSty" Width="100%" DataKeyNames="RowNumber">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="ردیف">
</asp:BoundField>
<asp:BoundField DataField="StartDate" HeaderText="از تاریخ">
</asp:BoundField>
<asp:BoundField DataField="EndDate" HeaderText="تا تاریخ">
</asp:BoundField>
<asp:BoundField DataField="SherkatName" HeaderText="نام شرکت،سازمان یا موسسه" >
</asp:BoundField>
<asp:BoundField DataField="WorkUnitName" HeaderText="واحد محل کار">
</asp:BoundField>
<asp:BoundField DataField="Sharh" HeaderText="شرح دقیق شغل/سمت/مسئولیت" >
</asp:BoundField>
<asp:BoundField DataField="WorkTime" HeaderText="زمان کار" >
</asp:BoundField>
<asp:BoundField DataField="Description" HeaderText="توضیحات">
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="SavabegSelect" runat="server" AutoPostBack="True" OnCheckedChanged="SavabegSelect_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
موردی ثبت نشده است.
</EmptyDataTemplate>
</asp:GridView>
Btn Delete Code
<asp:Button ClientIDMode="Static" ID="BtnDelete" CssClass="btnregister" runat="server" Text="حذف" OnClick="BtnDelete_Click" />
Code behind of btn Delete
protected void BtnDelete_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvrow in GridPesonal.Rows)
{
CheckBox chkdelete = (CheckBox)gvrow.FindControl("SavabegSelect");
if (chkdelete.Checked)
{
GridPesonal.DeleteRow(gvrow.RowIndex);
}
}
}
When execute above code this error show
The GridView 'GridPesonal' fired event RowDeleting which wasn't handled.
Have you used command-name as Delete on BtnDelete.
Remove that from Delete Button it will work.
If you have like this
<asp:GridView ID="gvRoute" DataKeyNames="Route" runat="server" AutoGenerateColumns="false"
AllowPaging="true" Width="30%"
onrowdeleting="gvRoute_RowDeleting">
Remove onrowdeleting="gvRoute_RowDeleting
or wirte event for
protected void gvRoute_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
\\
}
or Use the "CommandName" property "Delete"
Or Use OnClick
<asp:GridView ClientIDMode="Static" ID="GridPesonal" runat="server" AutoGenerateColumns="False" Class="GrdSty" Width="100%" DataKeyNames="RowNumber" OnClick="BtnDelete">
Using <asp:GridView></asp:GridView> I am trying to display columns of database table. I want to fetch primary key of table but obviously don't want to display it. How can I achieve this?
This is my GridView
<asp:GridView ID="MyGrid" runat="server" BorderColor="#0066FF" AllowPaging="false" PageSize="5" AllowSorting="true" AutoGenerateColumns="false"
AutoGenerateEditButton="true" OnRowEditing="MyGrid_RowEditing" AutoGenerateDeleteButton="true" OnRowDeleting="MyGrid_RowDeleting"
OnRowDataBound="MyGrid_RowDataBound" EmptyDataText="No Value" BorderWidth="0px" BorderStyle="Solid">
<Columns>
<asp:BoundField DataField="PrimaryKey" HeaderText="UserId"/>
<asp:BoundField DataField="Column1" HeaderText="Column1" />
<asp:BoundField DataField="Column2" HeaderText="Column2" />
<asp:BoundField DataField="Column3" HeaderText="Column3" />
</Columns>
</asp:GridView>
I also tried visible=false to hide primary key, it hides primary key from displaying but also don't fetch its value and I want this value.
Hope my question is clear.
You need to set Visible = false within the OnRowDataBound event, this will mean the data is still accessible to you, but won't display on the page.
<asp:GridView ID="MyGrid" runat="server" BorderColor="#0066FF"
AllowPaging="false" PageSize="5" AllowSorting="true"
AutoGenerateColumns="false" AutoGenerateEditButton="true"
OnRowEditing="MyGrid_RowEditing" AutoGenerateDeleteButton="true"
OnRowDeleting="MyGrid_RowDeleting"
OnRowDataBound="MyGrid_RowDataBound" EmptyDataText="No Value"
BorderWidth="0px" BorderStyle="Solid">
<Columns>
<asp:BoundField DataField="PrimaryKey" HeaderText="UserId"/>
<asp:BoundField DataField="Column1" HeaderText="Column1" />
<asp:BoundField DataField="Column2" HeaderText="Column2" />
<asp:BoundField DataField="Column3" HeaderText="Column3" />
</Columns>
</asp:GridView>
In Codebehind:
protected void MyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false;
}
<asp:GridView ... DataKeyNames="PrimaryKey" />
You can use this:
<asp:BoundField DataField="PrimaryKey" visible="false" HeaderText="PKId"/>
Also use this
<asp:BoundField DataField="PrimaryKey" visible="false" HeaderText="UserId"/>
To get Primary Key
<asp:GridView ID="MyGrid" runat="server" BorderColor="#0066FF" DataKeyNames="PrimaryKey"
MyGrid.DataKeys[e.NewEditIndex].Value
OR
MyGrid.Rows[e.NewEditIndex].DataBoundItem
If you want to hide a column by its name instead of its index in GridView. After creating DataTable or Dataset, you have to find the index of the column by its name then save index in global variable like ViewStae, Session and etc and then call it in RowDataBound, like the example:
string headerName = "Id";
DataTable dt = .... ;
for (int i=0;i<dt.Columns.Count;i++)
{
if (dt.Columns[i].ColumnName == headerName)
{
ViewState["CellIndex"] = i;
}
}
... GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header || e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Footer)
{
int index = Convert.ToInt32(ViewState["CellIndex"]);
e.Row.Cells[index].Visible = false;
}
}