I have a gridview which displays product information on the index page of my site for a user. I want to extend this to allow the user to tick a checkbox if they have reviewed a product.
However, after adding the check box column into my gridview template, when i try to search multiple times the Page_Load event of my index page stops firing, this causes an issue as some of the events further down the execution tree require the object that is initialised at page load.
The problem seems to be that placing any asp input control inside the gridview is somehow preventing Page_Load from firing before the DataSources OnSelecting and OnSelected and the Grids OnRowDataBound events but i can't see why.
Here is my sample code, I can't see what I'm doing wrong here.
Index.aspx.cs
private ProductSearch productSearch
protected void Page_Load(object sender, EventArgs e)
{
productSearch = new ProductSearch(GetSearchParameters());
productSearch.PageLoad()
}
protected void ProductsSelecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters["searchParams"] = productSearch.GetSearchParams();
}
protected void ProductsSelected(object sender, ObjectDataSourceStatusEventArgs e)
{
productSearch.SetExportToCsvButton();
}
protected void ProductsPageIndexChanging(object sender, GridViewPageEventArgs e)
{
dgProducts.PageIndex = e.NewPageIndex;
}
protected void ProductsOnRowDataBound(object sender, GridViewRowEventArgs e)
{
productSearch.ProductsRowDataBound(e.Row);
}
Index.aspx
<%# Page Language="C#" MasterPageFile="~/Admin/AdminMaster.master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Web.Admin.Index" %>
<asp:Content ContentPlaceHolderID="DataFrame" runat="server">
<asp:GridView ID="dgProducts" runat="server" AllowPaging="True" AllowSorting="True" EnableViewState="False"
AutoGenerateColumns="False" DataSourceID="dsProducts" PagerSettings-Position="TopAndBottom" DataKeyNames="ProductNo, KitID"
OnPageIndexChanging="ProductsPageIndexChanging" OnRowDataBound="ProductsOnRowDataBound"
EmptyDataText="There are no products matching your search." meta:resourcekey="dgProducts" onrowcreated="ProductsRowCreated">
<HeaderStyle Font-Size="Small" />
<Columns>
<asp:TemplateField HeaderText="Reviewed">
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkReviewed" class="reviewedCheckbox" Checked="False" />
</ItemTemplate>
</asp:TemplateField>
</Columns
</asp:GridView>
<asp:ObjectDataSource ID="dsProducts" runat="server" EnablePaging="True" SelectMethod="ProductAndKitSearchByParams"
TypeName="ProductSearchController.ProductSearch" onselecting="ProductsSelecting" SortParameterName="SortParameter"
SelectCountMethod="SelectVirtualCount" OnSelected="ProductsSelected">
<SelectParameters>
<asp:Parameter ConvertEmptyStringToNull="true" DefaultValue="" Name="searchParams" Type="Object" />
</SelectParameters>
</asp:ObjectDataSource>
</asp:Content>
Check you master page contentplaceholderid and provide it in content page like this:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"></asp:Content>
and also check your content page codebehind file name should be same as mention in page directives.
Related
I have below link button and I need to show it only if grid has records.
<asp:LinkButton ID="linkButton1" runat="server" ToolTip="Delete file" Visible='<%# (Convert.ToInt32(Eval("gridViewFileInformation.Rows.Count"))>0) %>' >Delete</asp:LinkButton>
But it shows always.
In your code behind file after databind of "gridViewFileInformation" you can set the Visible property of linkButton1. Similar question
Something like:
ASPX File:
<asp:GridView
runat="server"
ID="gridViewFileInformation"
OnDataBound="gridViewFileInformation_DataBound">
</asp:GridView>
CS File:
protected void gridViewFileInformation_DataBound(object sender, EventArgs e)
{
linkButton1.Visible = (gridViewFileInformation.Rows.Count > 0);
}
I faced with funny situation. I created a page which is having some value, I set these value and control my post back event also. The problem is happening when I change a component index(ex reselect a combobox which is not inside my datagrid) then I dont know why without my page call the Page_Load it goes to create a new row in grid function and all of my parameter are null! I am just receiving null exception.
So in other word I try to explain the situation:
when I load my page I am initializing some parameter. then everything is working fine. in my page when I change selected item of my combo box, page suppose to go and run function related to that combo box, and call page_load, but it is not going there and it goes to rowcreated function.
I am trying to illustrate part of my page.
Please help me because I am not receiving any error except null exception and it triger wrong even which seems so complicated for me.
public partial class W_CM_FRM_02 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack && !loginFail)
return;
InitializeItems();
}
}
private void InitializeItems()
{
cols = new string[] { "v_classification_code", "v_classification_name" };
arrlstCMMM_CLASSIFICATION = (ArrayList)db.Select(cols, "CMMM_CLASSIFICATION", "v_classification_code <> 'N'", " ORDER BY v_classification_name");
}
}
protected void DGV_RFA_DETAILS_RowCreated(object sender, GridViewRowEventArgs e)
{
//db = (Database)Session["oCon"];
foreach (DataRow dr in arrlstCMMM_CLASSIFICATION)
((DropDownList)DGV_RFA_DETAILS.Rows[index].Cells[4].FindControl("OV_RFA_CLASSIFICATION")).Items.Add(new ListItem(dr["v_classification_name"].ToString(), dr["v_classification_code"].ToString()));
}
protected void V_CUSTOMER_SelectedIndexChanged(object sender, EventArgs e)
{
if (V_CUSTOMER.SelectedValue == "xxx" || V_CUSTOMER.SelectedValue == "ddd")
V_IMPACTED_FUNCTIONS.Enabled = true;
}
}
my form:
<%# Page Language="C#" MasterPageFile="~/MasterPage.master"
AutoEventWireup="true" CodeFile="W_CM_FRM_02.aspx.cs"
Inherits="W_CM_FRM_02" Title="W_CM_FRM_02" enableeventvalidation="false" EnableViewState="true"%>
<td>Project name*</td>
<td><asp:DropDownList ID="V_CUSTOMER" runat="server" AutoPostBack="True"
onselectedindexchanged="V_CUSTOMER_SelectedIndexChanged" /></td>
<td colspan = "8">
<asp:GridView ID="DGV_RFA_DETAILS" runat="server" ShowFooter="True" AutoGenerateColumns="False"
CellPadding="1" ForeColor="#333333" GridLines="None" OnRowDeleting="grvRFADetails_RowDeleting"
Width="100%" Style="text-align: left"
onrowcreated="DGV_RFA_DETAILS_RowCreated">
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<Columns>
<asp:BoundField DataField="ON_RowNumber" HeaderText="SNo" />
<asp:TemplateField HeaderText="RFA/RAD/Ticket No*">
<ItemTemplate>
<asp:TextBox ID="OV_RFA_NO" runat="server" Width="120"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
Hi remove enableeventvalidation="false" EnableViewState="true" from your page directive.
I have a user control that contains a radio list that on SelectIndexChanged it updates a drop down.
I put together a basic page and add the user control to the page it works fine but when I move the control to inside a radgrid it doesn't work, it will post back but never call the SelectIndexChanged event.
I've pulled up 2 previous questions on this Q. 1 and Q. 2 which say that OnSelectedIndexChanged needed to be set in the aspx page. My issue is that the control doesn't exist in the aspx page and is created later so that solution does not work for me.
Working code
working.aspx
<TT:ToolTipControl ID="ToolTipEdit" runat="server" />
working.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
ToolTipEdit.getEditToolTip("POL_TERM_CD", "DataPolTermDropDownlistEdit");
}
User Control
userControl.ascx.cs
public void getEditToolTip(string fieldName, string ddlName)
{
DataPolTermRadioListBox ccPolTermRadioListBox = new DataPolTermRadioListBox(); //custom radio list
ccPolTermRadioListBox.ID = "PolTermRadioListBox";
ccPolTermRadioListBox.AutoPostBack = true;
ccPolTermRadioListBox.SelectedIndexChanged += new System.EventHandler(updateParent);
ToolTip.Controls.Add(ccPolTermRadioListBox);
}
Broken Code
brokenPage.aspx
<telerik:RadGrid ID="rgState" Skin="WebBlue" runat="server" OnNeedDataSource="rgState_NeedDataSource"
AutoGenerateColumns="False" OnPreRender="rgState_PreRender">
<MasterTableView DataKeyNames="wrtnStPolId" AllowAutomaticUpdates="false" AllowAutomaticDeletes="true"
AllowAutomaticInserts="false" CommandItemDisplay="Top" AllowMultiColumnSorting="True"
EditMode="InPlace" GroupLoadMode="Server" Caption="State(s) and Exposure(s)">
<Columns>
<telerik:GridTemplateColumn AllowFiltering="false" HeaderText="Pol Type Nstd" SortExpression="nonStdPolTypeCd"
UniqueName="nonStdPolTypeCd">
<ItemTemplate>
<asp:Label ID="lblNonStdPolTypeCd" runat="server" align="center" Text='<%#DataBinder.Eval(Container.DataItem, "nonStdPolTypeCd")%>' />
</ItemTemplate>
<EditItemTemplate>
<cc1:DataNonStdTypeCdDropDownList ID="ddlNonStdTypeCd" runat="server" ClientIDMode="Predictable">
</cc1:DataNonStdTypeCdDropDownList>
<TT:ToolTipControl ID="ttcNonStdPolTypeCdEdit" runat="server" />
</EditItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
brokenPage.aspx.cs
protected void rgState_PreRender(object sender, EventArgs e)
{
RadGrid rgExpMod = (RadGrid)sender;
foreach (GridDataItem row in rgExpMod.Items)
{
GridDataItem gdiItem = (GridDataItem)row;
if (row.FindControl("ttcNonStdPolTypeCdEdit") != null)
{
DropDownList ddl = (DropDownList)row.FindControl("ddlNonStdTypeCd");
ddl.ID += row.RowIndex;
ddl.SelectedIndex = 2;
NCCI.PDC.Web.Controls.ucToolTip ttcNonStdPolTypeCdEdit = (NCCI.PDC.Web.Controls.ucToolTip)row.FindControl("ttcNonStdPolTypeCdEdit");
ttcNonStdPolTypeCdEdit.getEditToolTip("non_std_pol_type_cd", ddl.ID);
}
}
}
I want load two user controls on demand.
asp:UpdatePanel ID="UpdatePanel1" runat="server"
ContentTemplate
asp:Button ID="Button1" runat="server" Text="Button" UseSubmitBehavior="false"
OnClick="Button1_Click" /
div id='Div_UserControlPlace' enableviewstate="true" runat="server"
/div
/ContentTemplate
Triggers
asp:PostBackTrigger ControlID="Button1" /
/Triggers
/asp:UpdatePanel
asp:UpdatePanel ID="UpdatePanel2" runat="server"
ContentTemplate
asp:Button ID="Button2" runat="server" Text="Button" UseSubmitBehavior="false"
OnClick="Button2_Click" /
div id='Div_UserControlPlace2' enableviewstate="true" runat="server"
/div
/ContentTemplate
aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Control FeaturedProductUserControl = new Control();
FeaturedProductUserControl = LoadControl("WebUserControl1.ascx");
FeaturedProductUserControl.EnableViewState = true;
Div_UserControlPlace.Controls.Add(FeaturedProductUserControl);
}
protected void Button2_Click(object sender, EventArgs e)
{
Control FeaturedProductUserControl2 = new Control();
FeaturedProductUserControl2 = LoadControl("WebUserControl2.ascx");
FeaturedProductUserControl2.EnableViewState = true;
Div_UserControlPlace2.Controls.Add(FeaturedProductUserControl2);
}
I load the first user control by clicking on the first button - this works properly but when I click on the other button to load the second UserControl, the first UserControl disappears and the second UserControl loads.
Thanks
IFA_User
You should use the Placeholder control to dynamically add your controls to the form.
Take a look at my last responses about dynamic controls:
OnClick event of dynamically created LinkButtons is not working
Dynamically Added DropDownlists Are Not Firing SelectedIndexChanged Event
Dynamically create an ImageButton
Now I already have some code working for demo purpose, each dynamic user controls keeps its state across post backs
This is the output:
ASPX
<asp:PlaceHolder runat="server" ID="addresses" /><br />
<asp:Button Text="Add Address" runat="server" ID="addAddress" OnClick="addAddress_Click" />
ASPX Code behind
protected void Page_PreLoad(object sender, EventArgs e)
{
for (int i = 0; i < this.DynamicControlsCount; i++)
{
var c = this.LoadControl("~/AddressControl.ascx");
this.addresses.Controls.Add(c);
}
}
protected void addAddress_Click(object sender, EventArgs e)
{
this.DynamicControlsCount++;
var c = this.LoadControl("~/AddressControl.ascx");
this.addresses.Controls.Add(c);
}
protected int DynamicControlsCount
{
get
{
if (this.ViewState["ac"] == null)
{
return 0;
}
return (int)this.ViewState["ac"];
}
set
{
this.ViewState["ac"] = value;
}
}
ASCX
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="AddressControl.ascx.cs" Inherits="WebApplication1.AddressControl" %>
<asp:Panel ID="Panel1" runat="server" GroupingText="Address" DefaultButton="btnSave">
Street: <asp:TextBox runat="server" ID="txtStreet" /><br />
City: <asp:TextBox runat="server" ID="txtCity" /><br />
<asp:Button Text="Save" runat="server" ID="btnSave" OnClick="btnSave_Click" />
</asp:Panel>
<asp:Panel runat="server" GroupingText="Address Summary" Visible="false" ID="summary">
<asp:Label ID="lblStreet" runat="server" /><br />
<asp:Label ID="lblCity" runat="server" />
</asp:Panel>
ASCX Code behind
protected void btnSave_Click(object sender, EventArgs e)
{
this.summary.Visible = true;
this.lblCity.Text = "Selected city: " + this.txtCity.Text;
this.lblStreet.Text = "Selected street: " + this.txtStreet.Text;
}
When a user control is created in the HTML, asp.net will persist across postbacks without any user interaction. But if you are loading them programatically (dynamically), they will not persist accross postbacks. So if you load them programmatically, you have the added task of persisting them programmatically as well. Use the ViewState (or Session I suppose) to store what has been loaded and perhaps any other necessary information that needs to be loaded between postbacks. Every single postback will require you to reload every control or else they will disappear.
There are couple of ways of doing it:
U can load the UserControls using Ajax. Benefit of using Ajax, is ur page does not get post back, thus for example, on click event of Button1, call a ajax(traditional/Jquery) to load UserControl1, and on button click of Button2 User control2.
Put the two button in two different updated panel, by doing this the click event will only refresh a part of ur page.
U have to save somewhere (ViewState/Session),which buttons are clicked, and upon clicking of any button check the value of that variable, and explicit load the control.
Points to note - If u want to get ur data back when ur page made a complete postback, then u have to add the controls keeping in mind the Page load event cycle.
I have a very simple GridView on one of my pages with the following markup on my .aspx page:
<asp:GridView ID="gvNews" runat="server" AutoGenerateColumns="false" AllowPaging="true"
AllowSorting="true" DataKeyNames="NewsID,VersionStamp" OnPageIndexChanging="gvNews_PageIndexChanging"
OnRowCreated="gvNews_RowCreated">
<Columns>
<asp:BoundField HeaderText="News Title" DataField="NewsTitle"
SortExpression="NewsTitle" ReadOnly="true" />
<asp:BoundField HeaderText="News Content" DataField="NewsContent"
SortExpression="NewsContent" ReadOnly="true" />
<asp:BoundField HeaderText="Posted Date" DataField="InsertedDate"
SortExpression="InsertedDate" ReadOnly="True" />
<asp:BoundField HeaderText="InsertedBy" DataField="InsertedBy" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lbEdit" runat="server" Text="Edit" CommandName="Select" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Below is the code on my .cs page:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadGrid();
}
}
private void LoadGrid()
{
gvNews.DataSource = GetNews();
gvNews.DataBind();
}
protected void gvNews_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
}
protected void gvNews_RowCreated(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[3].Visible = false;
}
On the RowCreated event I am trying to hide the InsertedBy column in the gridview. This code works fine when AllowPaging is set to flase. But when the AllowPaging is set to true I get the following error in the RowCreated event handler:
Specified argument was out of the range of valid values.
Parameter name: index
What could be the reasons for this behavior?
You need to write your code like this:
protected void gvNews_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[3].Visible = false;
}
}
With a GridView there are different types of rows that might get created and they will have different numbers of cells, but the RowCreated event will fire for all rows, so you need to limit your logic to only data rows in this case.
From what you have posted your hard coded value of 3 in the RowCreated event seems like the problem. Enable tracing on the page and see what you get. BTW the pager next->prev links also cause postback and in PageLoad u are only loading grid if its not a postback which it is when u try to go for next page and the row created is fired.