I have written a user control that raises an event based on certain criteria. I have placed an UpdatePanel around a grid that needs to be updated when that event fires. So I placed a asp:AsyncPostBackTrigger in the Triggers section. I have set the EventName equal to the event from the user control. In my user control, I throw an exception if something is wrong with some of the data. If the exception is thrown, the event does not get called. I would expect a full postback to occur if the event is not triggered (not a partial render from AJAX); however, even if the event is not thrown and the button is clicked, a partial postback occurs anyways. I need to show that the exception happened in the user control, but I cannot wrap the user control in an UpdatePanel since the data is huge and would take awhile to partial postback.
Any suggestions?
hello.
i think this is an old know issue:
http://msmvps.com/blogs/luisabreu/archive/2006/09/26/Quick-tip_3A00_-using-UserControl-events-as-triggers.aspx
Hmmm.. I have tried implementing your solution, but I cannot seem to get it to work. Here is a code snippet what I am doing.
public delegate void PassengerEmployeeSubmittedEventHandler(object sender, PassengerEmployeeSubmittedEventArgs e);
public class PassengerEmployeeSubmittedEventArgs : EventArgs
{
// properties go here
}
UserControlCode
{
public event PassengerEmployeeSubmittedEventHandler PassengerEmployeeSubmitted;
protected virtual void OnPassengerEmployeeSubmitted(PassengerEmployeeSubmittedEventArgs e)
{
if (this.PassengerEmployeeSubmitted != null)
PassengerEmployeeSubmitted(this, e);
}
}
protected void ibtnSubmitEmployee_Click(object sender, ImageClickEventArgs e)
{
If(verified)
OnPassengerEmployeeSubmitted(new PassengerEmployeeSubmittedEventArgs());
else
this.litError.Text = "Error";
}
} // end user control
Web Page Containing Control Code {
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanelPassengers" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ucAddPassengerEmployee" EventName="PassengerEmployeeSubmitted" />
</Triggers>
<ContentTemplate>
// gridview code only
</ContentTemplate>
</UpdatePanel>
<uc1:AddPassengerEmployee ID="ucAddPassengerEmployee" runat="server" />
}
I have tried registering the ImageButton with the RegisterAsyncPostBackControl, but here's what's happening. The UpdatePanel only refreshes when that event is fired, that works, but it still does a Partial Page Update; therefore, if I catch that exception, the literal is never refreshed since it's only doing a partial postback. I would expect it to do a regular postback all the time unless that event is triggered. Any suggestions?
hello again.
it was an old sample, so i've just updated it for the current release:
A.ASCX
<%@. Control Language="C#" ClassName="A" %>
<script runat="server">
private object aux = new object();
public event EventHandler BtClicked
{
add
{
this.Events.AddHandler(aux, value);
}
remove
{
this.Events.RemoveHandler(aux, value);
}
}
void h(object s, EventArgs e)
{
OnBtClicked(e);
}
protected void OnBtClicked(EventArgs a)
{
if (this.Events[aux] != null)
{
((EventHandler)(this.Events[aux]))(this, a);
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ScriptManager manager = ScriptManager.GetCurrent(this.Page);
if (manager != null)
{
manager.RegisterAsyncPostBackControl(bt);
}
}
</script>
<asp:Button runat="server" ID="bt" Text="Submit" OnClick="h" UseSubmitBehavior="false" />
PAGE.ASPX
<%@. Page Language="C#" %>
<%@. Register src="http://pics.10026.com/?src=A.ascx" tagname="A" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
<asp:ScriptManager runat="server" ID="manager"></asp:ScriptManager>
<asp:UpdatePanel runat="server" id="panel">
<ContentTemplate>
<%=DateTime.Now %>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="A1" EventName="BtClicked" />
</Triggers>
</asp:UpdatePanel>
<uc1:A ID="A1" runat="server" />
</form>
</body>
</html>
the important thing is the call to the RegisterAsyncPostbackControl method
Hello Luis,
I tried using that code and it still doesn't seem to work. I even took your code and made one modification to it. As it is, it works as expected, but if I comment out the call to raise the event in the protected void OnBtClicked(EventArgs a), a partial post back still occurs, and that is the problem I am experiencing. I would expect that if this event is not raised, then a partial postback should NOT occur regardless if the button was clicked; however, please correct me if I am wrong. Thank you very much for your help. What do you think?
hello.
the registerXXX method is responsible for configuring the client page so that it always starts a partial postback operation. the trigger thing is only used on the server side and if you call the method, you'll always get a partial postback.
i'm still not sure on what you're looking for...if you get an exception during a partial postback the only thing you need is to handle the client endRequest event (raised by the pagerequestmanager) and use some js to show the exception on that label...
Guys while were are at this User control juncture, I would need help with a silly question that I havent been able to find an answer to yet. User Control inheritance. How would you go about changing the property of something from an inherited user control or override a base control from a inherited user control.
I have all the code, if you need it to help me but I am unable to get it so far. Rest all works fine except this bit. Any help appreciated
Thread hijacker ;) Kidding. I guess what I was hoping for was a partial postback to only occur when the specified event happens. Here's an example I have posted that does not use a usercontrol.
<%@. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %
<%@. Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void h(object sender, EventArgs e)
{
this.TextBox1.Text = this.ListBox1.SelectedValue;
}
protected void btn(object sender, EventArgs e)
{
this.ListBox1.DataSource = new System.Data.DataTable();
this.ListBox1.DataBind();
}
protected void Page_Load(object sender, EventArgs e)
{
this.ListBox1.Items.Add(new ListItem("TEST", "TEST"));
this.ListBox1.Items.Add(new ListItem("TEST2", "TEST2"));
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ListBox1" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="btn" />
<asp:ListBox ID="ListBox1" runat="server" OnSelectedIndexChanged="h" AutoPostBack="true" EnableViewState="true" ></asp:ListBox>
</div>
</form>
</body>
</html
What you see is that the SelectdIndexChanged causes the partial postback, while the button click causes a full postback. I guess the big problem I have in my usercontrol is that I have a button that causes a postback, but I do not want it to cause the partial postback. I run some validation AFTER the button has been clicked, and then it will send an Event to the calling page which contains the AJAX. If this event is fired, then it should initialize the partial postback; however, it is causing a partial postback for ANY postback event raised by the usercontrol. This behavior seems really out of place to me since it is not in the updatepanel. Otherwise, there's no point at all in using the EventName with any usercontrol since it will cause the partial postback regardless of what happenes inside of it.
The solution you have posted will work, but perhaps my view on how a usercontrol behaves is miscued. In order for your solution to work, I will need to take into consideration other pages that consume this control that do not use it in AJAX. I would have to let the exception bubble up to the calling page in AJAX, otherwise, I would need to catch it via server side and display it in the literal. What do you think?
As another example, I added a second button in the usercontrol "A" in your example. What I would expect, is that since it is not part of the Trigger, it should not fire a partial postback, but it does. I have tried adding it to the RegisterAsyncPostBackControl... taking it away, etc... but I can't get it to work. Perhaps my thinking is off?
hello again.
due to the way the algorythm is built on the client side, you need to call the registerpostbackcontrol for that 2nd button (just add the line below the registerasyncpostnack cotnrol method on the user control)
That did the trick. Thanks a lot. I guess since I have a button that triggers an event in a user control, it's impossible to do a full postback when the button is pressed, but a partial postback when button is pressed and the event is raised. I ended up using client side validation in the user control (and keeping the server validation) for AJAX. THanks.
hello.
well, the important thing to keep in mind is that on the client side, there really isn't any user control. what you have are several html controls! I've been away for a long time (ie, haven't really been using asp.net ajax since it was onut some moths ago), so i can't really be specific about it. However, i recall that hte pagerequestmanager object will try to make some "smart" tests until it is able to get an element responsible for the postback. if it gets anything different from null, it'll perform a partial postback. that's why your second button still kept giving you a partial postback. btw, i think i've talked about those things in my blog (though I'm not sure)...
Thanks a lot for the clarification. That definitely makes more sense to me. Thank you. I'll check out your blog next time just to make sure I'm not asking redundant questions.
No comments:
Post a Comment