I have a simple problem with my gridview. It is an editable gridview which allows inserting, updating and deleting rows. It is bound to a datatable. I store the datatable in the viewstate and bind the datatable on page_load for every postback. There is no column order or paging and I only have a few records on this gridview. When there is no data to display, I add an empty message text like "no data found" manually to grid. It is okey for the first page_load. But after postback, this text disappears, but the row is still there. And the main problem is the row has "edit" and "delete" command columns after postback. This row should not have edit or delete columns after postback. It works really fine before postback.
This problem never happens if there is at least one row in gridview.
If I have at least one row, then if I add more rows: No problem
If I have the empty grid, then I add a row (before any postback for example combobox value change): No problem
If I have the empty grid: then I do a postback by changing a value in a combobox, then "no rows found" message in the grid disappearing and there is an extra row in the grid which has no text and has edit and delete columns
If I have the grid with that unwanted row, then I add a row to that gridview: The unwanted row is going away and new row appearing on the grid. No problem
So the only problem is that extra row which is appearing after postback.
Code details are below. Please help me with this silly problem. I couldnt solve it for days.
ASPX:
<asp:GridView ID="grdTerminals" runat="server"
AutoGenerateColumns="False" DataKeyNames="TRM_ID"
OnRowCancelingEdit="grdTerminals_RowCancelingEdit"
OnRowDataBound="grdTerminals_RowDataBound"
OnRowEditing="grdTerminals_RowEditing"
OnRowUpdating="grdTerminals_RowUpdating" ShowFooter="True"
OnRowCommand="grdTerminals_RowCommand"
OnRowDeleting="grdTerminals_RowDeleting"
HeaderStyle-BackColor="#73be1e" HeaderStyle-ForeColor="Window" HeaderStyle-Font-Bold="true" Width="500px" HeaderStyle-Height="30">
<Columns>
<asp:TemplateField HeaderText="Terminal" HeaderStyle-HorizontalAlign="Left">
<EditItemTemplate>
<asp:DropDownList ID="ddlTerminal" runat="server" DataTextField="TRM_MNMC" DataValueField="TRM_ID">
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblTerminal" runat="server" Text='<%# Eval("TRM_MNMC") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlNewTerminal" runat="server" DataTextField="TRM_MNMC" DataValueField="TRM_ID">
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="TAS No" HeaderStyle-HorizontalAlign="Left">
<EditItemTemplate>
<asp:TextBox ID="txtTASNo" runat="server" Text='<%# Bind("TAS_NO") %>' Width="120"></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtNewTASNo" runat="server" Width="120"></asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="lblTASNo" runat="server" Text='<%# Bind("TAS_NO") %>' Width="120"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="" ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="lbkUpdate" runat="server" CausesValidation="True" CommandName="Update" Text="Kaydet"></asp:LinkButton>
<asp:LinkButton ID="lnkCancel" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="lnkAdd" runat="server" CausesValidation="False" CommandName="Insert" Text="Insert"></asp:LinkButton>
</FooterTemplate>
<ItemTemplate>
<asp:LinkButton ID="lnkEdit" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="" ShowDeleteButton="True" ShowHeader="True" DeleteText="Delete"/>
</Columns>
</asp:GridView>
C#
// I am storing the data in ViewState
DataTable dtTerminals
{
get
{
return ViewState["_dtVehicleTerminals"] as DataTable;
}
set
{
ViewState["_dtVehicleTerminals"] = value;
}
}
//Page Load
protected void Page_Load(object sender, EventArgs e)
{
if (dtTerminals == null)
{
dtTerminals = new DataTable();
dtTerminals.Columns.Add("TRM_ID");
dtTerminals.Columns.Add("TRM_MNMC");
dtTerminals.Columns.Add("TAS_NO");
}
if (!IsPostBack)
{
string VhcId = Request["vhc_id"];//Edit mode
if (!string.IsNullOrEmpty(VhcId))
{
BindTerminalInfo(VhcId);
}
else
{
//To show empty grid
BindTerminalGrid();
}
}
// Bind Terminal Info
void BindTerminalInfo(string VhcId)
{
dtTerminals = VehicleManager.GetVehicleTerminals(VhcId);
BindTerminalGrid();
}
//Bind Terminal Grid
public void BindTerminalGrid()
{
if (dtTerminals.Rows.Count > 0)
{
grdTerminals.DataSource = dtTerminals;
grdTerminals.DataBind();
}
else
{
//Show No Records Found
dtTerminals.Rows.Add(dtTerminals.NewRow());
grdTerminals.DataSource = dtTerminals;
grdTerminals.DataBind();
grdTerminals.Rows[0].Cells.Clear();
grdTerminals.Rows[0].Cells.Add(new TableCell());
grdTerminals.Rows[0].Cells[0].Text = "No Data found";
dtTerminals.Rows.Clear();
}
}
//Other methods related to grid functionality
protected void grdTerminals_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddlTerminal = (DropDownList)e.Row.FindControl("ddlTerminal");
if (ddlTerminal != null)
{
ddlTerminal.DataSource = VehicleManager.GetDefaultUserTerminalNames();
ddlTerminal.DataBind();
ddlTerminal.DataTextField = "TRM_MNMC";
ddlTerminal.DataValueField = "TRM_ID";
ddlTerminal.SelectedValue = grdTerminals.DataKeys[e.Row.RowIndex].Values[0].ToString();
}
}
if (e.Row.RowType == DataControlRowType.Footer)
{
DropDownList ddlNewTerminal = (DropDownList)e.Row.FindControl("ddlNewTerminal");
ddlNewTerminal.DataSource = VehicleManager.GetDefaultUserTerminalNames();
ddlNewTerminal.DataBind();
}
}
protected void grdTerminals_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
grdTerminals.EditIndex = -1;
BindTerminalGrid();
}
protected void grdTerminals_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
Label lblId = (Label)grdTerminals.Rows[e.RowIndex].FindControl("lblTrmUnqId");
DropDownList ddlTerminal = (DropDownList)grdTerminals.Rows[e.RowIndex].FindControl("ddlTerminal");
TextBox txtTASNo = (TextBox)grdTerminals.Rows[e.RowIndex].FindControl("txtTASNo");
dtTerminals.Rows[e.RowIndex]["TRM_ID"] = ddlTerminal.SelectedValue;
dtTerminals.Rows[e.RowIndex]["TRM_MNMC"] = ddlTerminal.SelectedItem;
dtTerminals.Rows[e.RowIndex]["TAS_NO"] = txtTASNo.Text;
grdTerminals.EditIndex = -1;
BindTerminalGrid();
}
protected void grdTerminals_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
string TrmId = Convert.ToString(grdTerminals.DataKeys[e.RowIndex].Values[0]);
dtTerminals.Rows.Remove(dtTerminals.Rows[e.RowIndex]);
BindTerminalGrid();
}
protected void grdTerminals_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("Insert"))
{
DropDownList ddlNewTerminal = (DropDownList)grdTerminals.FooterRow.FindControl("ddlNewTerminal");
TextBox txtTASNo = (TextBox)grdTerminals.FooterRow.FindControl("txtNewTASNo");
DataRow dr = dtTerminals.NewRow();
dr["TRM_ID"] = ddlNewTerminal.SelectedValue;
dr["TRM_MNMC"] = ddlNewTerminal.SelectedItem.Text;
dr["TAS_NO"] = txtTASNo.Text;
dtTerminals.Rows.Add(dr);
BindTerminalGrid();
}
}
protected void grdTerminals_RowEditing(object sender, GridViewEditEventArgs e)
{
grdTerminals.EditIndex = e.NewEditIndex;
BindTerminalGrid();
}
I am not sure it is the correct solution . But try adding Empty data text property of Gridview.
<asp:gridview id="CustomersGridView"
datasourceid="CustomersSqlDataSource"
autogeneratecolumns="true"
emptydatatext="No data in the data source."
runat="server">
<emptydatarowstyle backcolor="LightBlue"
forecolor="Red"/>
</asp:gridview>
Or try like this
<asp:TemplateField>
<EditItemTemplate>
<asp:ImageButton ID="imgBtnUpdate" runat="server" Height="32px"
ImageUrl="~/Images/Update.jpg" ToolTip="Update" Width="32px" CommandName="Update"/>
<asp:ImageButton ID="imgBtnDelete" runat="server" Height="32px"
ImageUrl="~/Images/delete.gif" style="margin-left: 0px" ToolTip="Delete"
Width="32px" CommandName="Delete"/>
<asp:ImageButton ID="imgBtnCancel" runat="server" Height="32px"
ImageUrl="~/Images/Cancel.png" ToolTip="Cancel" Width="32px" CommandName="Cancel"/>
</EditItemTemplate>
<FooterTemplate>
<asp:ImageButton ID="btnAdd" runat="server" ImageUrl="~/Images/AddNew.gif"
ToolTip="Add New Record" CommandName="Add"/>
</FooterTemplate>
<ItemTemplate>
<asp:ImageButton ID="imgBtnEdit" runat="server" Height="32px"
ImageUrl="~/Images/pencil.png" ToolTip="Edit" Width="32px" CommandName="Edit"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name">
<EditItemTemplate>
<asp:TextBox ID="txtName" runat="server" Text='<%# Eval("name") %>'></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtNameFooter" runat="server"></asp:TextBox>
</FooterTemplate>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("name") %>'></asp:Label>
</ItemTemplate>
Finally I have fixed this problem. The solution is adding
if (!Request.Form["__EVENTTARGET"].Split('$').Contains(grdTerminals.ID))
{
BindTerminalGrid();
}
code block to If(Postback) statement. I should rebind data for everypostback but only if the control which caused postback is not the "datagrid".
Related
I am having a gridview in asp.net, and in the table I have two columns.
Now I must show the column index value row by row on the button click in form of a alert for dllDesc and txtBoxDesc fields.
<asp:GridView ID="gvCar" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" DataKeyNames="LevelID" OnRowDataBound="gvCar_RowDataBound">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField HeaderText="Car">
<ItemTemplate>
<asp:Label ID="Car" runat="server" Width="150px" Height="30px" Font-Names="Georgia" MyCustomAttr="foo" margin-Left="100px" Text='<%# Bind("CharName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Description">
<ItemTemplate>
<asp:DropDownList ID="ddlDesc" Width="142px" Height="35px" Font-Names="Georgia" margin-Left="100px" runat="server">
</asp:DropDownList>
<asp:TextBox ID="txtBoxDesc" runat="server" Width="130px" Height="28px" Font-Names="Georgia" margin-Left="100px" Text=''></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
I managed to get the value for rows(code below) but i could not find a way to show it for columns.
protected void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRow gvr in gvCar.Rows)
{
string PrimaryKey = gvCar.DataKeys[gvr.RowIndex].Values[0].ToString();
MessageBox.Show(PrimaryKey);
}
}
Can someone help me please?
just bind it like this on grid view don't need to do anything else
<asp:TemplateField HeaderText="No.">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
EDIT UPDATE 2
just add on selected index Changed event
<asp:GridView ID="gvCar" runat="server" OnSelectedIndexChanged="gvCar_SelectedIndexChanged">
and in your cs file
protected void gvCar_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
string a = gvCar.SelectedRow.Cells[0].Text; //Write here that cell index of index no
}
catch (Exception ex)
{
}
}
if you want to do that by row command then open bellow link
Row command example
that will work for you
You just iterate over the columns and then you ask for the header text:`
for (int i = 0; i < gvCar.Columns.Count; i++)
{
string columnHeader = gvCar.Columns[i].HeaderText;
}
EDITED AFTER FEEDBACK:
For the datatables I think it works like this:
for (int i = 0; i < dt.Columns.Count; i++)
{
int colIndex = dt.Columns[i].Ordinal;
}
Hope this helps!
I have a nested gridview that I would like it to stay expanded after the user clicks one of the paging values. I found an example on the web but it is not working for me.
If anyone can see where I am going wrong, I would appreciate it.
This is my JavaScript function that expands/hides the nested grid. It works fine. This is also where I set my hidden value to identify the which grid is expanded.
function DivExpandCollapse(RecipientID) {
var div = document.getElementById(RecipientID);
var img = document.getElementById('img' + RecipientID);
if (div.style.display == "none") {
div.style.display = "inline";
img.src = "Images/minus.png";
$("#recdevgvIsExpanded").val("1");
} else {
div.style.display = "none";
img.src = "Images/plus.png";
$("#recdevgvIsExpanded").val("");
}
}
This function identifies the grid to expand and should expand it.
It gets into the if statement and the recipientID is correct.
I build the id of the div and img elements to set them.
$(document).ready(function () {
$("[id*=recdevgvIsExpanded]").each(function () {
if ($(this).val() == "1") {
var div = $(this).parent().closest("div");
$tds = div.find("td");
var recipientID = $tds.siblings(":first").text();
var div2 = document.getElementById('div' + recipientID);
var img = document.getElementById('imgdiv' + recipientID);
div2.style.display = "inline";
img.src = "Images/minus.png";
}
});
});
This is the code behind that goes thru the grid rows to set the Expanded value. It also sets the correct nested grid to be 'expanded'.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Get Recipient Info from Database
populateRecipientInfoGrid();
}//end if IsPostBack
//For Re expanding the expanded rows
foreach (GridViewRow row in RecipientInfoGridView.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
HiddenField IsExpanded = row.FindControl("recdevgvIsExpanded") as HiddenField;
IsExpanded.Value = Request.Form[IsExpanded.UniqueID];
}
}
}
This is the PageIndexChanging event. It correctly updates the data.
protected void RecipientDeviceGridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView tgvRecipientDevice = (GridView)sender;
tgvRecipientDevice.PageIndex = e.NewPageIndex;
int tiRecipientID = Convert.ToInt32((tgvRecipientDevice.Parent.FindControl("rigvLblRecipientID") as Label).Text);
populateDeviceGrid(tgvRecipientDevice, tiRecipientID);
}
This is the markup
<asp:GridView ID="RecipientInfoGridView" runat="server"
AllowPaging="True"
PageSize="10"
AutoGenerateColumns="False"
Caption="Recipient Information"
CaptionAlign="Top"
CssClass="grid"
HorizontalAlign="Left"
ShowFooter="True"
ShowHeaderWhenEmpty="True"
DataKeyNames="RecipientID"
OnPageIndexChanging="RecipientInfoGridView_PageIndexChanging">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<a href="javascript:DivExpandCollapse('div<%# Eval("RecipientID")%>');">
<img id="imgdiv<%# Eval("RecipientID")%>" alt=""
width="25px" border="0" src="Images/plus.png" />
</a>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="RecipientID">
<ItemTemplate>
<asp:Label ID="rigvLblRecipientID" runat="server"
Text='<%# Bind("RecipientID") %>'
ClientIDMode="Static">
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<tr>
<td colspan="100%">
<div id="div<%# Eval("RecipientID") %>" style="display: none">
<asp:GridView ID="RecipientDeviceGridView" runat="server"
AutoGenerateColumns="false"
CssClass="grid"
ShowFooter="true"
Caption="Device Information"
CaptionAlign="Top"
AllowPaging="true"
PageSize="1"
HorizontalAlign="Left"
OnPageIndexChanging="RecipientDeviceGridView_PageIndexChanging">
<Columns>
<asp:TemplateField HeaderText="DeviceID">
<ItemTemplate>
<asp:Label ID="recdevgvLblDeviceID" runat="server"
Text='<%# Bind("DeviceID") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Device" ItemStyle-Wrap="false">
<ItemTemplate>
<asp:Label ID="recdevgvLblDeviceName" runat="server"
Text='<%# Bind("DeviceName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Service Provider">
<ItemTemplate>
<asp:Label ID="recdevgvLblServiceName" runat="server"
Text='<%# Bind("ServiceName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Address">
<ItemTemplate>
<asp:Label ID="recdevgvLblAddress" runat="server"
Text='<%# Bind("Address") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Active">
<ItemTemplate>
<asp:Label ID="recdevgvLblActive" runat="server"
Text='<%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Action"
ShowHeader="False"
ItemStyle-Wrap="false"
ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="recdevgvEditButton" runat="server"
CausesValidation="True"
CommandName="Edit"
Text="Edit"
CssClass="gridActionbutton"
ValidationGroup="EditDeviceValidation">
</asp:Button>
<asp:Button ID="recdevgvDeleteButton" runat="server"
CausesValidation="False"
CommandName="Delete"
Text="Delete"
CssClass="gridActionbutton"
OnClientClick="return confirm('Are you sure you want to delete this Device Information?')">
</asp:Button>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<asp:HiddenField ID="recdevgvIsExpanded" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
If anyone can give me any guidance as to how to accomplish a nested grid to remain expanded after the PageIndexChanging event, I would appreciate it.
Thanks.
UPDATE
I have the nested grid staying open but it is always the first nested grid with opens after the PageIndexChanging regardless of which row I click. The problem is that the Hidden field has the same ID for each row. Using the 'alert' method and viewing the UniqueId in the code behind. The hidden field is always the first row.
Where should the Hidden field be? According to some code I found on the web it is after the 'div' and before the ItemTemplate at the end of the nested grid. Is there another place it should be?
UPDATE
I am not identifying the hidden field correctly. It is in the correct location, I believe.
This is my javascript function:
function DivExpandCollapse(RecipientID) {
var div = document.getElementById(RecipientID);
var img = document.getElementById('img' + RecipientID);
if (div.style.display == "none") {
div.style.display = "inline";
img.src = "Images/minus.png";
$("#recdevgvIsExpanded").val("1");
var hiddenName = $("#recdevgvIsExpanded").attr("name");
alert(hiddenName + " expanded");
}
else {
div.style.display = "none";
img.src = "Images/plus.png";
$("#recdevgvIsExpanded").val("");
}
I need to ID the hidden field associated with the 'div' and 'img'. How do I do that?
Your grid is not inside an UpdatePanel, so every time you change the index is generating a full post, that means the entire page is re created, you need to put the grid inside an update panel, also add a ScriptManager, after that you need to write a JS function that expands the grid when the script manager request is finished (Sounds like a lot of work, but is actually not)
//example
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function()
{
//here you'll expand the grid
});
Some documentation regarding the update panel control:
https://msdn.microsoft.com/en-us/library/bb399001(v=vs.140).aspx
https://msdn.microsoft.com/en-us/library/bb386452(v=vs.140).aspx
Update Panel did not work for me. I used PlaceHolder with literals which helped me but caused css issues.
But following code fixed my issue.
Hope this might help anyone facing the issue where update panels doesnt work.
$(function () {
$("[src*=minus]").each(function () {
$(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>");
$(this).next().remove()
});
});
Aspx code:
<asp:GridView ID="gv_Parent" AutoGenerateColumns="False"
DataKeyNames="Id" Font-Size="12px" Width="100%" runat="server"
AllowPaging="true" PageSize="10" OnPageIndexChanging="OnPageIndexChanging">
<Columns>
<asp:ImageButton ID="imgShow" runat="server" OnClick="Show_Hide_ChildGrid"
ImageUrl="../../../assets/img/plus.png" CommandArgument="Show" />
<asp:Panel ID="pnlOrders" runat="server" Visible="false" Style="position:
relative">
<div id="divgvTargetInfo" runat="server" class="table-responsive">
<asp:GridView ID="gvChild" AutoGenerateColumns="False"
DataKeyNames="Id" runat="server"
OnPageIndexChanging="OnTargetPageIndexChanging" AllowPaging="true"
pagesize="10">
<Columns>
</columns>
</asp:GridView> --closing Child Grid
</asp:Panel>
</columns>
</asp:GridView> --closing Parent Grid
Code Behind:
protected void Show_Hide_ChildGrid(object sender, EventArgs e)
{
ImageButton imgShowHide = (sender as ImageButton);
GridViewRow row = (imgShowHide.NamingContainer as GridViewRow);
if (imgShowHide.CommandArgument == "Show")
{
row.FindControl("pnlOrders").Visible = true;
mgShowHide.CommandArgument = "Hide";
imgShowHide.ImageUrl = "../../../assets/img/minus.png";
GridView gvwChild = row.FindControl("gvChild") as GridView;
BindChildGrid(Convert.ToInt32(gv_Parent.DataKeys[row.RowIndex].Value),
gvwChild);
}
else
{
row.FindControl("pnlOrders").Visible = true;
imgShowHide.CommandArgument = "Hide";
imgShowHide.ImageUrl = "../../../assets/img/minus.png";
GridView gvwChild = row.FindControl("gvChild") as GridView;
BindchildGrid(Convert.ToInt32(gv_Parent.DataKeys[row.RowIndex].Value),
gvwChild);
}
}
else
{
row.FindControl("pnlOrders").Visible = false;
mgShowHide.CommandArgument = "Show";
mgShowHide.ImageUrl = "../../../assets/img/plus.png";
}
}
protected void OnPageIndexChanging(object sender, GridViewPageEventArgs e)
{
gv_Parent.PageIndex = e.NewPageIndex;
this.BindGVTSPBA();
}
protected void OnTargetPageIndexChanging(object sender,
GridViewPageEventArgs e)
{
GridViewRow gvRowParent = (((GridView)sender)).DataItemContainer as
GridViewRow;
GridView gvwChild = ((GridView)sender);
gvwChild.PageIndex = e.NewPageIndex;
BindChildGrid
(Convert.ToInt32(gv_Parent.DataKeys[gvRowParent.RowIndex].Value),
gvwChild);
}
I have a gridview which have some columns. I have made name column as a hyperlink.
I have a table named- 'tblAdd'. On Page load event I made it invisible. I want that when I click column hyperlink, table display.
How can I do this using asp.net ?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="Name"
DataSourceID="SqlDataSource1" OnCheckedChanged="sellectAll"
>
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="cbSelectAll" runat="server" AutoPostBack="true" OnCheckedChanged="sellectAll" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chk" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name"
SortExpression="Name" >
<ItemTemplate>
<asp:HyperLink ID="linkName" runat="server" Text='<%#Bind("Name") %>' OnClick="displayTutorial_Click" NavigateUrl='#'>
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
My Default.aspx.cs-
protected void Page_Load(object sender, EventArgs e)
{
Label1.Visible = false;
GridView1.Columns[2].Visible = false;
//GridView1.DataBind();
if (!Page.IsPostBack)
{
fillLanguageGrid();
tblAdd.Visible = false;
}
}
Do it using Grid View row command event.
Do something like this-
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
//To get the Selected link text field on textbox
if (e.CommandName == "displayLink")
{
txtEditName.Text=((LinkButton)e.CommandSource).Text;
}
}
On default.aspx-
<asp:TemplateField HeaderText="Name" SortExpression="Name" >
<ItemTemplate>
<asp:LinkButton ID="linkName" runat="server" Text='<%#Bind("Name")%>' OnClick="linkBtn_Click" CommandName="displayLink"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Button btnAddrecord = (Button)sender;
GridViewRow gvr =(GridViewRow)btnAddrecord.NamingContainer;
if (btnAddrecord.CommandName == "onAddMaterial")
Define the button in your grid view markup and assign a CommandName value to the button, like this:
<asp:GridView ID="GridView1" AutoGenerateColumns="False" runat="server"
OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Add Record">
<ItemTemplate>
<asp:Button ID="btnAddRecord"
CommandArgument="<%# ((GridViewRow)Container).RowIndex %>"
CommandName="AddRecord" runat="server" Text="Add" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Now in your code-behind, you can handle the OnRowCommand event and AddRecord command, like this:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "AddRecord")
{
// Get index of row passed as command argument
int index = Convert.ToInt32(e.CommandArgument.ToString());
// Your logic here
}
}
1.Give a command name for button..
2.Then inside gridview
if e.commandname="yourcommandname"
{
//your code..
}
<!--We use onrowcommand for getting the selected row -->
<asp:GridView runat="server" ID="gvTest" AutoGenerateColumns="False" OnRowCommand="gvTest_OnRowCommand" >
<Columns>
<asp:TemplateField HeaderText="BookId" >
<ItemTemplate>
<asp:Label runat="server" ID="lblBookId" Text='<%# Bind("[BookId]") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtBookId" Text='<%# Bind("[BookId]") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:TemplateField>
<asp:TemplateField HeaderText="Options">
<ItemTemplate>
<asp:Button runat="server" ID="btnDelete" CommandArgument="<%# Container.DisplayIndex %>" CommandName="IsDelete" Text="Delete"></asp:Button>
</ItemTemplate>
</asp:TemplateField>
//Code Behind
protected void gvTest_OnRowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
//getting rowindex which we have selected by using CommandArgument
int rowindex = Convert.ToInt32(e.CommandArgument);
if (e.CommandName == "IsDelete")
{
int bkid = gvTest.Rows[rowindex].Cells[0].FindControl("BookId");
//call a method to delete book using the bkid
}
}
catch (Exception ex)
{
Response.Write(ex);
}
}
I am totally confused with the way ASP.NET GridView binding works.
I have a GridView. Now, on the page load (using !IsPostBack) I am binding the GridView.
My gridview has an edit button. When I click on it, the GridView becomes blank. Behaviour could be expected, because when I click on the edit button, a postback happens and, because I have binded the GridView inside the !IsPostback condition, it won't bind the GridView.
Now, if I remove the GridView binding, and place it outside the !IsPostback condition, the edit button works. But, I am unable to get the edited value from the TextBox. In this case, too, the behaviour could be expected, as when the update button is clicked, the GridView is re-binded, because the binding this time has been done outside the !IsPostback condition.
So, I want to know what could be the proper code for the edit button to work, and at the same time, the edited values from the TextBox could be retrieved.
Question Updated with Code:
<asp:GridView ID="grdExternalLinkSection1" ShowFooter="true" runat="server" Width="100%" AutoGenerateColumns="false" CellPadding="5" EnableViewState="true">
<EmptyDataTemplate>
External Link Title
<asp:TextBox ID="txtExternalLinkTitleEmptySection1" runat="server"></asp:TextBox>
External Link Url
<asp:TextBox ID="txtExternalLinkUrlEmptySection1" runat="server"></asp:TextBox>
<asp:Button ID="btnExternalLinkEmptySection1" OnCommand="grdExternalLinkSection_Button_Clicks" runat="server" Text="Add" CommandName="headernew,1" style="padding:3px; width:56px;" />
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="Title">
<ItemTemplate>
<asp:Label ID="lblExternalLinkTitleSection1" runat="server"><%# Eval("Title") %></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtExternalLinkTitleEditSection1" runat="server" Text='<%# Bind("Title") %>'></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtExternalLinkTitleFooterSection1" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Url">
<ItemTemplate>
<asp:Label ID="lblExternalLinkUrlSection1" runat="server"><%# Eval("Url")%></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtExternalLinkUrlEditSection1" runat="server" Text='<%# Bind("Url") %>'></asp:TextBox>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtExternalLinkUrlFooterSection1" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Manage">
<ItemTemplate>
<asp:Button ID="btnExternalLinkEditSection1" OnCommand="grdExternalLinkSection_Button_Clicks" runat="server" CommandName="Editing,1" CommandArgument='<%# Container.DataItemIndex %>' Text="Edit" />
<asp:Button ID="btnExternalLinkDeleteSection1" OnCommand="grdExternalLinkSection_Button_Clicks" runat="server" CommandName="Deleting,1" CommandArgument='<%# Container.DataItemIndex %>' Text="Delete" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="btnExternalLinkUpdateSection1" OnCommand="grdExternalLinkSection_Button_Clicks" runat="server" CommandName="Updating,1" CommandArgument='<%# Container.DataItemIndex %>' Text="Update" />
<asp:Button ID="btnExternalLinkCancelSection1" OnCommand="grdExternalLinkSection_Button_Clicks" runat="server" CommandName="Canceling,1" CommandArgument='<%# Container.DataItemIndex %>' Text="Cancel" />
</EditItemTemplate>
<FooterTemplate>
<asp:Button ID="btnExternalLinkAddFooterSection1" OnCommand="grdExternalLinkSection_Button_Clicks" runat="server" CommandName="Footer,1" Text="Add" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
below is the function which does the binding work:
GridView grid;
protected void BindExternalLinks(int SectionID, string ControlName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlDataAdapter adapter = new SqlDataAdapter("user_Newsletter_GetExternalLinks", connection))
{
adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
adapter.SelectCommand.Parameters.Add("#SectionID", SqlDbType.Int).Value = SectionID;
adapter.SelectCommand.Parameters.Add("#PortalID", SqlDbType.Int).Value = PortalID;
DataTable dt = new DataTable();
adapter.Fill(dt);
grid = (GridView)this.FindControl(ControlName);
grid.DataSource = dt;
}
}
}
protected void BindAllExternalLinks()
{
for (int i = 1; i <= NewsLetterSectionCount; i++)
{
BindExternalLinks(i, "grdExternalLinkSection" + i);
grid.DataBind();
}
}
below is my PageLoad:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindAllExternalLinks();
}
}
and below is my command buttons event: i have kept the handler common for all command buttons:
protected void grdExternalLinkSection_Button_Clicks(object sender, CommandEventArgs e)
{
int rowIndex = (e.CommandArgument != "") ? Convert.ToInt32(e.CommandArgument) : -1;
string[] commandNames = e.CommandName.ToString().Split(',');
string command = commandNames[0].ToString().ToLower();
int sectionID = Convert.ToInt32(commandNames[1]);
GridView grid = (GridView)this.FindControl("grdExternalLinkSection" + sectionID);
try
{
if (command == "headernew")
{
TextBox title = grid.Controls[0].Controls[0].FindControl("txtExternalLinkTitleEmptySection" + sectionID) as TextBox;
TextBox url = grid.Controls[0].Controls[0].FindControl("txtExternalLinkUrlEmptySection" + sectionID) as TextBox;
UpdateExternalLinks(ModifyExternalLinks.Insert, sectionID, title.Text, url.Text);
MessageShow("External Link Added Successfully");
}
else if (command == "editing")
{
//grid.EditIndex = rowIndex;
}
else if (command == "canceling")
{
grid.EditIndex = -1;
}
else if (command == "footer")
{
Response.Write("Inside Footer");
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
BindExternalLinks(sectionID, "grdExternalLinkSection" + sectionID);
grid.DataBind(); //here i am binding once the records are modified.
}
You are almost there. BindAllExternalLinks() should be inside the if (!IsPostback) block, correct.
The additional thing you should do is to rebind the grid after you have done your editing:
else if (command == "editing")
{
// do your update stuff here
BindAllExternalLinks();
}
Just rebind the gridview under each postback event(). Even if you bind it to an object datasource or SQL DataSource, you have to call the databind method after every postback request like
MyGridview.DataBind();
UpdatePanel1.Update();