User control events not getting to their handlers - c#

I am trying to create a user control to wrap around the Membership API (A set of custom Gridviews to display the data better) and, while the code and the controls worked fine in the page, when I moved them to an .ascx, the events stopped firing to it.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="CustomMembership.ascx.cs" Inherits="CCGlink.CustomMembership" %>
<asp:Panel ID="mainPnl" runat="server">
<asp:Label
id="lblError"
ForeColor="Red"
Font-Bold="true"
runat="server" />
<asp:GridView
id="grdUsers"
HeaderStyle-cssclass="<%# _headercss %>"
RowStyle-cssclass="<%# _rowcss %>"
AlternatingRowStyle-cssclass="<%# _alternatingcss %>"
OnRowUpdating="grdUsers_RowUpdating"
OnRowDeleting="grdUsers_RowDeleting"
OnRowCancelingEdit="grdUsers_cancelEdit"
autogeneratecolumns="false"
allowsorting="true"
AllowPaging="true"
EmptyDataText="No users..."
pagesize="<%# PageSizeForBoth %>"
runat="server">
<!-- ...columns... -->
</asp:GridView>
<asp:Button
id="btnAllDetails"
onclick="btnAllDetails_clicked"
text="Full Info"
runat="server" />
<asp:GridView
DataKeyNames="UserName"
HeaderStyle-cssclass="<%# _headercss %>"
RowStyle-cssclass="<%# _rowcss %>"
AlternatingRowStyle-cssclass="<%# _alternatingcss %>"
id="grdAllDetails"
visible="false"
allowsorting="true"
EmptyDataText="No users in DB."
pagesize="<%# PageSizeForBoth %>"
runat="server" />
<asp:Button
id="btnDoneAllDetails"
onclick="btnAllDetails_clicked"
text="Done."
Visible="false"
runat="server" />
</asp:Panel>
However, none of the events in the first two controls (the gridview grdUsers and the button btnAllDetails) simply do NOT occur, I have verified this in the debugger. If they occured just fine in the aspx page, why do they die on moving to the ascx?
My code in the aspx now is:
<div class="admin-right">
<asp:ScriptManager ID="sm1" runat="server" />
<h1>User Management</h1>
<div class="admin-right-users">
<asp:UpdatePanel ID="up1" runat="server">
<ContentTemplate>
<cm1:CustomMembership
id="showUsers"
PageSizeForBoth="9"
AlternatingRowStylecssclass="alternating"
RowStylecssclass="row"
DataSource="srcUsers"
HeaderStylecssclass="header"
runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
Thanks.

You've not said whether you're building a Web Site or a Web Application - if you're building a web application have you checked that the .designer file has updated properly when you moved the controls into the user control?

http://forums.asp.net/t/1102183.aspx
This explains that there is an issue with ButtonType="Image" in the CommandField. Changing the entry to "Link" fixes this problem.

Related

ASP.Net Trigger user control dropdownlist change from UpdatePanel

I need to trigger an update event in a user control from update panel, but so far I am having some issues. Here is my scenario:
UC1:
//uc1
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="FilterControlRow.ascx.cs" Inherits="FilterWebPart.FilterControlRow" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
// other controls
<div runat="server" id="inputFilters" class="inputFilters">
<asp:Button ID="btnOpenBracket" runat="server" CssClass="filterBracketButton" OnClick="btnOpenBracket_Click" />
<asp:DropDownList ID="ddlPropertyNames" runat="server" OnSelectedIndexChanged="ddlPropertyNames_SelectedIndexChanged"
ViewStateMode="Enabled" />
<div class="filterValidator">
<asp:DropDownList ID="ddlLookup" CssClass="filterTxtValue" runat="server" ViewStateMode="Enabled" />
</div>
</div>
when changed the ddlPropertyNames updates the ddlLookup.
UC2:
//uc2
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="FilterControlNew.ascx.cs"
Inherits="FilterWebPart.FilterControlNew" ViewStateMode="Disabled" %>
<%# Register Src="FilterWebPart.FilterControlRow.ascx" TagName="FilterControlRow" TagPrefix="uc2" %>
<asp:UpdatePanel ID="UpdatePanelFilter" runat="server" ChildrenAsTriggers="False" UpdateMode="Conditional" ViewStateMode="Enabled" OnInit="UpdatePanelFilter_OnInit">
<ContentTemplate>
//other controls
<asp:Repeater ID="Repeater1" runat="server" Visible="true" OnItemDataBound="Repeater1_ItemDataBound"
OnItemCommand="Repeater1_ItemCommand" ViewStateMode="Enabled">
<ItemTemplate>
<div class="filterRow">
<uc2:filtercontrolrow id="FilterControlRow1" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="btnFind" runat="server" OnClick="btnFind_Click" CssClass="filterButton" Text="Find"
ViewStateMode="Enabled" ValidationGroup="Filter" />
<asp:Button ID="btnAdd" runat="server" OnClick="btnAdd_Click" CssClass="filterButton" Text="Add" ViewStateMode="Enabled" />
</asp:Panel>
// more controls
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnFind" />
</Triggers>
</asp:UpdatePanel>
UC2 just contains the first user control in a repeater so I can have multiple filters. and then in the default page I have:
<uc1:filtercontrolnew id="WebPartFilter" runat="server" />
The main problem is that the first user control was doing a full page postback and I want to avoid that and limit it only to update the dropdown that is inside the usercontrol. I saw somewhere that the UpdatePanel is the way to go, but after many attempts either it does nothing or it is doing a full page postback again. Maybe I am wrapping the update panels wrong, but unfortunatelly I do not have much experience using them.
Any help would be appreciated:)
First Step use asynchronous postback trigger, and add the Event Name
//uc2
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="FilterControlNew.ascx.cs"
Inherits="FilterWebPart.FilterControlNew" ViewStateMode="Disabled" %>
<%# Register Src="FilterWebPart.FilterControlRow.ascx" TagName="FilterControlRow" TagPrefix="uc2" %>
<asp:UpdatePanel ID="UpdatePanelFilter" runat="server" ChildrenAsTriggers="False" UpdateMode="Conditional" ViewStateMode="Enabled" OnInit="UpdatePanelFilter_OnInit">
<ContentTemplate>
//other controls
<asp:Repeater ID="Repeater1" runat="server" Visible="true" OnItemDataBound="Repeater1_ItemDataBound"
OnItemCommand="Repeater1_ItemCommand" ViewStateMode="Enabled">
<ItemTemplate>
<div class="filterRow">
<uc2:filtercontrolrow id="FilterControlRow1" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="btnFind" runat="server" OnClick="btnFind_Click" CssClass="filterButton" Text="Find"
ViewStateMode="Enabled" ValidationGroup="Filter" />
<asp:Button ID="btnAdd" runat="server" OnClick="btnAdd_Click" CssClass="filterButton" Text="Add" ViewStateMode="Enabled" />
</asp:Panel>
// more controls
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnFind" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Second Step add if(! isPostback) in Page_Load and place in it all the code you want not to be refreshed on postback
Note you should add in the update panel triggers for each tool you are using as buttons repeaters, etc.. and make sure to add the events you're using

Panel not displayed in UpdatePanel

<form runat="server" id="from1">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<script src='https://www.google.com/recaptcha/api.js'></script>
<asp:Panel runat="server" ID="pnlSiteQuestions">
>>>>> CONTROLS removed for brevity <<<<<
<asp:Button ID="btnContinue" runat="server" Text="Continue" OnClick="btnContinue_Click" ValidationGroup="Questions" />
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="pnlNotRequired" runat="server" Visible="false">
Sorry you do not qualify.
</asp:Panel>
<asp:Panel runat="server" ID="pnlAdditionalDetails" Visible="false">
<asp:ValidationSummary runat="server" ID="ValidationSummary1" />
Name
<asp:RequiredFieldValidator runat="server" ID="ValidatorName" ControlToValidate="ContactFormNameTextBox" ErrorMessage="Name is required" CssClass="ErrorClass">Required</asp:RequiredFieldValidator>
<asp:TextBox runat="server" ID="txtName" />
<div class="g-recaptcha" data-sitekey="ABC123"></div>
<asp:Button runat="server" ID="button1" Text="Confirm" OnClick="button1_Click" />
</asp:Panel>
</form>
I have the above form and decided to add an update panel. When a user clicks Continue, it goes to a database and determines if the user qualifies. If not pnlNotRequired message is displayed otherwise pnlAdditionalDetails is displayed.
Everything is/was working until i added the update panel. So removing the UP has everything working.
I tried adding a trigger but i didnt fully understand how it should be configured as i dont completely understand why this is occurring?
No Javascript errors listed either. Anyway to overcome this issue?
Update panel should cover all panels. Add property to update panel "UpdateMode='Conditional'" than add trigger block

Nested update panel causing parent update panel to refresh

I think I've tried every combination possible with update panels and I just cant seem to get this to work. I've got an update panel like so:
<asp:UpdatePanel runat="server" ID="upParent" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
Some content...
<div style="width:100%;text-align:center;">
<asp:Label ID="lblMainMessage" runat="server"></asp:Label>
<asp:UpdateProgress AssociatedUpdatePanelID="upParent" ID="UpdateProgress7" runat="server" DisplayAfter="100" DynamicLayout="True" Visible="True">
<ProgressTemplate>
<div class="loader ui-widget-overlay">
Loading data, please wait...<br/><img style="border-style:none;" src="../../Images/ajax-loader.gif" alt="loading" />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
<div>
<asp:UpdatePanel runat="server" ID="upChild" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
<asp:Timer ID="timerChecklists" runat="server" OnTick="TimerChecklistsTick" Interval="10000"></asp:Timer>
<asp:GridView ID="gvChecklists" runat="server"
AutoGenerateColumns="False" >
<Columns>
<ItemTemplate>
<asp:TemplateField HeaderText="Ques. Ans. Yes">
<ItemTemplate>
<asp:Label ID="lblQuestionsAnsweredYes" runat="server" ForeColor="Green"
Text='<%# DataBinder.Eval(Container, "DataItem.QuestionYesAnswered") %>'
ToolTip="Questions answered Yes."></asp:Label>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center" />
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Ques. Ans. No">
<ItemTemplate>
<asp:Label ID="lblQuestionsAnsweredNo" runat="server" ForeColor="Red"
Text='<%# DataBinder.Eval(Container, "DataItem.QuestionNoAnswered") %>'
ToolTip="Questions answered No."></asp:Label>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center" />
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Ques. Ans. N/A">
<ItemTemplate>
<asp:Label ID="lblQuestionsAnsweredNA" runat="server" ForeColor="Gray"
Text='<%# DataBinder.Eval(Container, "DataItem.QuestionNAAnswered") %>'
ToolTip="Questions answered N/A."></asp:Label>
</ItemTemplate>
<FooterStyle HorizontalAlign="Center" />
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Image ID="imgLoader" runat="server" ImageUrl="/Images/ajax-loader.gif" />
</td>
</tr>
</table>
</div>
<div style="width:100%;text-align:center;">
<asp:Label ID="lblspChecklists2" runat="server"></asp:Label>
</div>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnChecklistExcel"/>
<asp:AsyncPostBackTrigger ControlID="timerChecklists" />
</Triggers>
</asp:UpdatePanel>
What I am trying to accomplish is to sort of lazy load some gridview data due to its size. So what I simply did is wrap the gridview inside an update panel. I then place a timer within this update panel and set it to 10000 (10 seconds) for the tick event. I set the event OnTick as shown:
protected void TimerChecklistsTick(object sender, EventArgs e)
{
LoadChecklistsSubPanel();
timerChecklists.Enabled = false;
imgLoader.Visible = false;
}
The LoadChecklistsSubPanel simply gets a dataset and assigns it to the grid views datasource and does a databind. This all works fine...however my issue is the following:
Note as mentioned a parent update panel and a child update panel. Within this I have an Update progress associated to the update panel upParent. But my issue is when the 10 seconds hits and the timer event is fired this updateprogress is shown (in effect causing my entire page to basically load). I would think that this would not happen given the updatemode is condition and children as triggers is false.
I have also tried ChildrenAsTriggers=true, I've tried to make the update panel mode always, I've tried just about everything but my issue still persists. Right when 10 seconds hits the UpdateProgress (which shows a loading data, please wait overlay is displayed.
Other than that my grid view is getting binded correctly, its getting its data after 10 seconds, etc. My only issue is I cannot seem to understand why the UpdateProgress shows up and overlays my entire screen if all that is happening is my nested sub panel should be updating only.
The fact is that upPanel not updated, you can check this by putting a Label in the upPanel with value="0" and add lblTest.text +=1 under TimerChecklistsTick in codebehind.
you can see that the value don't have any change.
In fact the problem is UpdateProgress control, UpdateProgress control is not a powerful tool and your expectations should not be very high.
if you want a powerful and customizable UpdateProgress you shoud make your own using JavaScript:
<script type="text/javascript">
var postBackElement;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
function InitializeRequest(sender, args) {
postBackElement = args.get_postBackElement();
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
} else {
//Put your progress UI here
//Check Trigger Id if needed.
//Show an image or Hide another div or ...
}
}
function EndRequest(sender, args) {
}
</script>
But Solution ...
But i was played a little with your code and found that if you remove your timer from inside UpdatePanels and put it outside them totally, your problem will be solved.
</ContentTemplate>
</asp:UpdatePanel>
//Outside the upParent
<asp:Timer ID="timerChecklists" runat="server" OnTick="TimerChecklistsTick" Interval="10000"></asp:Timer>
The problem is persist for any control that placed inside child updatepanels.
i don't know if there are a basis solution or not but as i say UpdateProgress is a simple and quick solution but not good in performance and flexibility totally.
Update
This is simulated code what work for me (ASP.NET 4.5, Chrome 36):
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="Default2.aspx.vb" Inherits="StackOverflowTests_WebVB.net.Default2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="upParent" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
<asp:Label ID="lbl1" runat="server" Text="0"></asp:Label>
<asp:UpdateProgress AssociatedUpdatePanelID="upParent" ID="UpdateProgress7" runat="server" DisplayAfter="100" DynamicLayout="True" Visible="True">
<ProgressTemplate>
<div class="loader ui-widget-overlay">
Loading data, please wait...<br />
<img style="border-style: none;" src="../Images/loading.gif" alt="loading" />
</div>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel runat="server" ID="upChild" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
<asp:Label ID="lbl2" runat="server" Text="0"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="timerChecklists" />
</Triggers>
</asp:UpdatePanel>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Timer ID="timerChecklists" runat="server" OnTick="TimerChecklistsTick" Interval="1000"></asp:Timer>
</div>
</form>
</body>
</html>
CodeBehind:
Protected Sub TimerChecklistsTick(sender As Object, e As EventArgs)
lbl1.Text += 1
lbl2.Text += 1
End Sub
In output, lbl2 start counting without full postback and without showing the content of UpdateProgress on every Tick.
If you move Timer inside the upChild, you can see that content of UpdateProgress will be shown on evey Tick, but still lbl1 show 0 without any change.

ASPX Form not calling codebehind on submit

I'm facing a rather odd behaviour that I can't explain myself. I have the following form on one of my ASP.net page:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="Codebehind.aspx.cs" Inherits="Myclass.Test" %>
<form name="application" id="application" method="post">
<asp:Table runat="server" width="840" border="0" align="center" cellspacing="0" cellpadding="0" id="tbl_test">
...
<asp:TableRow>
<asp:TableCell ColumnSpan="2" HorizontalAlign="Center" style="padding-top:10px">
<asp:Button onClick="Click" ID="btn" runat="server" Text="Submit!" Height="30" Width="150" />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
In the aspx.cs assembly I have a protected function "Click" that should get fired once the user clicks the button in the form. However, it does not. Nothing happens, I press the button and the function in my codebehind never gets to do its thing.
What am I missing here?
You need to add the runat="server" attribute on the form
Are you using a form with validations? If yes, use
<asp:Button ID="btn" runat="server" onClick="Click" Text="Submit" CausesValidation="false" />

BackgroundCssClass not being applied with ModalpopupExtender

I am trying to create this webpage that shows a database with a "Master-Detail" type view. To do this I am following this tutorial http://mattberseth.com/blog/2008/04/masterdetail_with_the_gridview.html.
The only difference is that I am not using ObjectDataSource, instead I am just using my SQL - DataBase.
Here's the problem: When I click on the link to show the modalPopup, the BackgroundCssClass is not being applied, and the popup just shows up in the corner of the screen without changing the background and opacity. Anyone know whats going on?
Here's the code:
CSS
<style type="text/css">
TR.updated TD
{
background-color:yellow;
}
.modalBackground
{
background-color:Gray;
filter:alpha(opacity=70);
opacity:0.7;
}
</style>
Modalpopup part (right above this is the gridview that shows the "Master" section of the Database, this works fine so I didn't include it.
<asp:UpdatePanel ID="updPnlReservationDetail" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button id="btnShowPopup" runat="server" style="display:none" />
<ajaxToolKit:ModalPopupExtender ID="mdlPopup" runat="server"
TargetControlID="btnShowPopup" PopupControlID="pnlPopup"
CancelControlID="btnClose"
BackgroundCssClass="modalBackground" />
<asp:DetailsView ID="dvReservationDetail" runat="server" DataSourceID="mainTable" CssClass="detailgrid"
GridLines="None" DefaultMode="Edit" AutoGenerateRows="false" Visible="false" Width="100%">
<Fields>
<asp:BoundField HeaderText="LabName" DataField="labName" ReadOnly="true" />
<asp:TemplateField HeaderText="Email">
<EditItemTemplate>
<asp:TextBox ID="txtEmail" runat="server" Text="Hello" />
</EditItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
<div class="footer">
<asp:LinkButton ID="btnSave" runat="server"
Text="Save" OnClick="BtnSave_Click" CausesValidation="true"
/>
<asp:LinkButton ID="btnClose" runat="server"
Text="Close" CausesValidation="false"
/>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
maybe you are using <asp:ScriptManager runat="server" /> instead of <ajaxToolKit:ToolkitScriptManager runat="server" />
here's a little example of "normal" usage, just in case
<asp:Button ID="btnShow_ClientSide" runat="server"
Text="show client side" OnClientClick="return false" />
<asp:Button ID="btnShow_ServerSide" runat="server"
Text="show server side" OnClick="btnShow_ServerSide_Click" />
<ajaxToolKit:ModalPopupExtender ID="mdlPopup" runat="server"
TargetControlID="btnShow_ClientSide"
PopupControlID="pnlPopup" CancelControlID="btnHide_ClientSide"
BackgroundCssClass="modalBackground" />
<asp:Panel ID="pnlPopup" runat="server"
BackColor="White" BorderColor="Black">
<asp:Button ID="btnHide_ClientSide" runat="server"
Text="hide client side" OnClientClick="return false" />
<asp:Button ID="btnHide_ServerSide" runat="server"
Text="hide server side" OnClick="btnHide_ServerSide_Click" />
</asp:Panel>
and in the code behind
protected void btnShow_ServerSide_Click(object sender, EventArgs e)
{
mdlPopup.Show();
}
protected void btnHide_ServerSide_Click(object sender, EventArgs e)
{
mdlPopup.Hide();
}
I had a completely different cause of this problem, and here's the solution, which I found on this very helpful walk-through page.
BackgroundCssClass: The name of the CSS class which needs to be applied to the background of the popup. One thing to note here is that if you don’t provide a CSS class then the modal popup will not function like a modal dialog i.e. One will be able to interact with the controls in the back of the popup control, so its imperative to provide a valid CSS class name value to the BackgroundCssClass property. In the above e.g. we have defined a CSS class called “backgroundColor” in the header section of the aspx page. Please note in the CSS class definition we have applied “filter” property to make the background transparent.
I had made a typo in the .css file, which prevented reading the background style. As soon as the CSS was working, the popup became modal and had its proper background.

Categories

Resources