How to handle master page button event in content page? - asp.net

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();
}

Related

WebPart RenderControl doesn't render contents

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

page event when using page methods?

I have the following that I'm using in every page:
public partial class Pages_MyPage : System.Web.UI.Page
{
ViewUserPreferencesModel TheUserPreferences;
Protected void Page_Load(object sender, EventArgs e)
{
TheUserPreferences = (ViewUserPreferencesModel)Session["SessionUserPreferences"];
And then I use a Page Method like this:
[WebMethod]
public static string GetAppointements(string DateInput)
{
ViewUserPreferencesModel TheUserPreferences = (ViewUserPreferencesModel)HttpContext.Current.Session["SessionUserPreferences"];
My question is this: Do I need to include the statement that loads user preferences when I run the page method or are the statements in the Page_Load event triggered when the page method is called, and if they are, will the variable be populated?
Thanks.
No, Page Methods do not follow the ASP.NET page lifecycle. However, even if they did, your TheUserPreferences variable won't be accessible in the static context.

inject jquery into every ASP.Net page

Is there any way to inject JQuery into every page on an ASP.Net site without adding the script tag to every page individually?
Using Master Page is easy way to do that. But if you already constructed your site, implementing this with master page may be mass of work. Instead of that you can create BasePage class which is inherited System.Web.UI.Page as below:
Check this out
public class BasePage:System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
// Define the name, type and url of the client script on the page.
String csname = "ButtonClickScript";
String csurl = "~/script_include.js";
Type cstype = this.GetType();
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
// Check to see if the include script exists already.
if (!cs.IsClientScriptIncludeRegistered(cstype, csname))
{
cs.RegisterClientScriptInclude(cstype, csname, ResolveClientUrl(csurl));
}
base.OnInit(e);
}
}
Every page which derived from BasePage includes that script source dynamically. (see below)
public partial class Default : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
//Some code ...
}
}
But, if you didn't create your site yet, Master Page is the easiest way to do that.
Use Master Page. Inject the JQuery into MasterPage only, all your aspx pages will use the MasterPage.
use document.write

Get state of ASP.NET page life cycle

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();
}

Update links on master page with data from child page

I have a menu of report links in my master page. I need to append an ID to the end of each whenever the user changes a value on the child page. What's a good way to accomplish this?
UPDATE: I should have mentioned that the child update is happening inside an UpdatePanel, meaning the master page is not reloaded when the change happens.
A MasterPage is really a child control of the page which it controls. You can control a MasterPage like any other control on your page (almost). All you need to do is get a reference to it.
You add a property to the code of your MasterPage, so its code may look something like this:
public partial class _default : System.Web.UI.MasterPage
{
protected string m_myString = string.Empty;
public string myString
{
get { return m_myString; }
set { m_myString = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
Then you have to cast the this.Master property to your MasterPage
public partial class index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Cast here to get access to your MasterPage
_default x = (_default)this.Master;
x.myString = "foo";
}
}
In response to your UPDATE:
The updated panel could write the ID to a hidden field and the menu events could look for that hidden fields in Request.Form["fieldName"].
Note that you shouldn't fieldName.Text because ASP.NET does a bad job of returning the right value for fields that have been AJAXed.

Resources