I have a custom web part that I am trying to call the RenderContents method on, but the results only contains the surrounding div for the web part, and not any child controls.
Take for example this simple web part:
namespace MyWebParts
{
public class MyTestWebPart : WebPart
{
public MyTestWebPart()
{
this.CssClass = "myTestWebPart";
}
protected override void CreateChildControls()
{
base.CreateChildControls();
this.Controls.Add(new LiteralControl("Nothing here yet."));
}
}
}
Then, in an http handler, I'm trying to instantiate this web part and call its RenderControl method. The result is <div class="myTestWebPart"></div>.
Does anyone know why I am not getting my controls from CreateChildControls also added to the output?
It's because when you're only instantiating a control and calling RenderControl on it, without it being added to a Controls collection, then it's not part of the Page lifecycle which causes all the events to fire.
In particular the PreRendering which calls EnsureChildControl isn't called.
The easy solution is to override Render like this:
protected override void Render(HtmlTextWriter writer)
{
EnsureChildControls();
base.Render(writer);
}
i would suggest to write your code in render method rather than writing in createchild control
Related
I'm creating a container using Panel control as follows:
public class CustomContainer : Panel
{
public override void RenderBeginTag(HtmlTextWriter writer)
{
var control this.Page.LoadControl("web user control path.ascx");
control.ID = "userControlId";
control.RenderControl(writer);
base.RenderBeginTag(writer);
}
public void ShowMessage(string message)
{
var control = this.FindControl("userControlId"); // control here is null!!
var custom = control as CustomControl;
custom.Message = message;
}
}
when I try to find the control with id userControlId which I rendered, it always retuns null!
Does anyone know what's happening? How can I solve this issue?
BTW: I can't add the CustomControl in CreateChildControls method because if the CustomContainer has code block I got an exception!
The Controls collection cannot be modified because the control
contains code blocks (i.e. <% ... %>).
You're probably calling ShowMessage before the control is rendered. Try calling ShowMessage during OnPreLoad or OnLoad. Basically, anywhere after the Render.
Ok, so I have an existing application to which I have added a custom HttpModule. I'm registering two events in the Init() method (PreRequestHandlerExecute and PostRequestHandlerExecute). The HttpModule gets called for every 'normal' request. But not I have created an .aspx containing a few WebMethods that are being called for ajaxifying some UI components. The WebMethod gets called nicely, but the trouble is that my HttpModule does NOT get called at all (no events, no init, even no constructor) when accessing the WebMethod. The module gets called nicely when accessing the .aspx in question as a 'normal' request. But it refuses to be called when calling the WebMethod.
My .aspx looks like this:
public partial class SelectionListService : System.Web.UI.Page
{
[WebMethod]
[ScriptMethod]
public static RadComboBoxData GetItemsAsRadComboBoxData(RadComboBoxContext context)
{
...
}
}
My HttpModule look like this:
public class MyModule : IHttpModule, IRequiresSessionState
{
public MyModule ()
{
}
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(Application_PreRequestHandlerExecute);
context.PostRequestHandlerExecute += new EventHandler(Application_PostRequestHandlerExecute);
}
private void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
...
}
private void Application_PostRequestHandlerExecute(object sender, EventArgs e)
{
...
}
}
I have been digging into this for quite some time now, but I just can't get it to work. Any ideas?
PS1: the BeginRequest, etc in global.asax.cs do get called when accessing the WebMethod.
PS2: I'm running IIS7 on Windows7.
since PageMethods must be static, an instance of the Page class with all it's events and the ASP.NET pipeline never happens. You simply get the result of your PageMethod call, and that is all.
I have a project that had the same problem. We found that the first event in the pipeline that we could get to fire for the WebMethods was the AcquireRequestState event. We hooked into that with our HttpModule in order to do the authorization checking required for the application.
I don't know what your pre and post request handlers do, but maybe you could shift some of the logic into the AcquireRequestState event handler.
I have C# Web Application that has an aspx page hosting a user control (Review.ascx). Inside that user control there are 5 more user controls, one of which has a public event (Review_Summary.ascx). The problem is no matter what i do I cannot get the event wired up in the parent ascx control (Review.ascx).
Here is what I have in the child control (Review_Summary.ascx)
public event EventHandler forwardStatusChanged;
#region methods
protected void btnForward_Click(object sender, EventArgs e)
{
if (btnForward.Text == "Return")
{
if (forwardStatusChanged != null)
{
forwardStatusChanged(sender, e);
}
removeForward();
}
}
In the parent control (Review.ascx) I have this
public void initReview(string EmployeeNumber)
{
RevSummary.forwardStatusChanged += new EventHandler(RevSummary_forwardStatusChanged);
<more code here>
}
protected void RevSummary_forwardStatusChanged(object sender, EventArgs e)
{
lblReadOnly.Visible = false;
}
RevSummary is the ID of the child control in the parent control. InitReveiw is a method that is called by the aspx page in its Page_Load event.
I get no errors on compile or at runtime. But when I click the button the forwardStatusChanged event is null. The "removeForward()" method that is called after that executes properly. So that fact that the event is always null leads me to believe that the wire up in the parent control is not working. However, I am sure it is executing becasue all of the code after that executes.
How can I figure out why this event is not wiring up?
Where is initReview being called from? Are you sure it's being called because the only reason this happens is that the event handler wasn't truly setup. I've never found a reason other than this, the several times I did this myself.
HTH.
I need the following functionality in my method: if the method is called before OnLoad event of ASP.NET life cycle throw an exception else continue execution of the method.
I was thinking of something like this:
if (Page.LifeCycleState < LifeCycleState.OnLoad) {
throw new InvalidPageStateException();
}
Is it possible to retrieve the state of ASP.NET page life cycle?
One approach would be to use a Basepage that you always use in your site. This would contain a variable called PageLoadComplete, which you would set at the end of your PageLoad event. Then you could check the state of this variable from within your method.
public abstract class BasePage : System.Web.UI.Page
{
public bool PageLoadComplete { get; private set; }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
PageLoadComplete = true;
}
}
If you want to access the variable from code external to your page such as a UserControl, you would have to make it public and cast your page as BasePage.
public partial class MyUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
BasePage basePage = this.Page as BasePage;
if (basePage != null && !basePage.PageLoadComplete)
{
throw new InvalidPageStateException();
}
}
}
There is property in a realization of System.Web.UI.Control class(realization):
internal ControlState ControlState {
get { return _controlState; }
set { _controlState = value; }
}
Where ControlState is enum that contains members such as: Initialized, ViewStateLoaded, Loaded etc. here declaration
But as you can see this property is internal. So only way to get control state is proposed by Daniel Dyson.
You maybe able to find what you are looking for, by looking at the CurrentHandler and PreviousHandler properties of the current HttpContext.
if the method is called before OnLoad event of ASP.NET life cycle
throw an exception else continue execution of the method.
It is not clear which Onload event is meant, nor where the "method" resides. Is it the Page's Onload or a Control's OnLoad? Is it a Page's "method" or a Control's "method"?
Anyway, one can store sort of flag in the Context.Items Dictionary, which all controls (including Page) have access to during a request. This eliminates the need to use a general base page like suggested obove.
In the OnLoad method (no matter whether it is a Page's OnLoad or a Control's OnLoad):
Context.Items[UniqueID] = this;
In the "method":
if (Context.Items[UniqueID] != null)
{
throw new InvalidPageStateException();
}
My problem is this I have a base page that creates content dynamically. There are buttons on my Master Page that fire events that my base page needs to know about. But the OnLoad function on my base page fires before my Button_Command function on my master page. So I either need to figure out a way to load my base page after the Button_Command function has had the chance to set a variable or I must call a function in my base page from the Button_Command function.
Have you considered using strongly typed master pages?
You can also check out my answer to this question.
I believe you can do this with an interface
public interface ICommandable
{
public void DoCommand1(object argument);
}
So the child page implements this interface
public class MyPage : Page, ICommandable
{
public void DoCommand1(object argument) {
}
}
And on the master page
public class Master : MasterPage
{
public void Button_Command(object sender, EventArgs e)
{
if (Page is ICommandable)
{
(Page as ICommandable).DoCommand1(myargument);
}
else
throw new NotImplementedException("The current page does not implement ICommandable");
}
}
It has been a long time since I worked with webforms however, so I can't swear that this works. I seem to recall writing something like this before.
Could you simply encapsulate the logic that is Button_Command into a public method and call that method both from the Button_Command event on the Master Page and from the Load event on the child page? So something like
protected void Page_Load( object sender, EventArgs e )
{
var master = (MyMaster)this.Master;
master.Foo();
}