Page_Init vs Page_PreRender conflict with rendering LI and CSS - css

Hi and thanks in advance.
I have an issue where I show some links at the top of page (they are not breadcrumbs) and for different circumstances I need to turn some on/off and for the page the user is on highlight that one. When I originally put the page together the call to the function that displays the links was in the Page_Init like so in the master page:
protected new void Page_Init(object sender, EventArgs e)
{
SetTabs(session);
}
protected void SetTabs(session)
{
makeTab.add(session.param, session.param);
makeTab.generate();
}
protected void add(param, param)
{
Tabs.add(new tab() { link = param, name = param });
}
protected void generate()
{
foreach(tab t in Tabs)
{
liTab.Text = string.Format("<li>{1}", t.name, t.link);
}
}
The links that get created are an unordered list of items displayed inline.
And I have a separate method that is applying a style change to highlight the link that is associated with the page that the user is on that is called from the Page_Load of the page itself:
protected void Page_Load(object sender, EventArgs e)
{
Master.makeTabBlue(nameOfTab);
}
However, in order to make hidden tabs reappear correctly, I had to move SetTabs(session) to the Page_PreRender function so that they would be called after the page was saved, when session is updated but now that I have done that the function that makes the tabs blue no longer has an effect. I've read about the page life cycle and I think that the CSS that's rendered in makeTabBlue is only effective during the Page_PreInit or Page_Init cycles but if I move the makeTabBlue to either of those then the page starts throwing additional errors that the controls can't be found which makes sense because they aren't called until PreRender. And calling it in the save function has no effect either. Where should I be calling makeTabBlue from so that it works correctly?
UPDATE:
In this particular situation, the resolution to my issue was to leave the SetTabs in the Page_Init, leave makeTabBlue in the Page_Load and I added a unique class to the LI and I am hiding, showing the links via javascript by storing values in a hidden field and checking that field when the js loads.

The last time you can do something with the page is on the Page_LoadComplete() (the one before PreRender) method. Changes to the markup will still take effect if you do it here. This should allow you to run some code in your init then run stuff later on whilst still affecting the front end.
Another option would be to add a variable in the code behind:
protected string TabColour = "some default colour";
Then on the front end, do something like:
<div style='color:#<%= TabColour %>'></div>
Where the div example above is your tab.
This would allow you to set TabColour on the prerender event but still show the correct colour on the front end as it's evaluated in the Rendering event. I prefer this method as page life cycle can be tricky and this avoids being constrained by it.

Related

Advice on how to search for products with criteria

I have a asp.net website and in the masterpage I have some dropdown controls where the user selects criteria for products.
After the last selected dropdown box I send the selected values to another page which is child to masterpage and I make a query to the database and present the results in a gridview.
My problem is that the masterpage is refreshed and all the selected values are cleared.
How can I keep the values to masterpage dropdown boxes or is there any better solution for this?
The Master Page will never keep data if you redirect to another page, the only thing you can do is to use session variables. You can "mask" the session values using static variables:
public static string MyValue
{
get { return (string)HttpContext.Current.Session["MyValue"];}
set { HttpContext.Current.Session["MyValue"] = value; }
}
Assign the values to your "static" variables before doing the redirection, and in the Page_Load of the Master Page you can read those values and assign everyone to the respective controls. For example:
In Page1.aspx.cs:
public void DoRedirect()
{
SiteMaster.MyValue = txtControlPage1.Text;
Response.Redirect("~/Page2.aspx", true);
}
When the Page2.aspx is loaded, the Page_Load of the Master Page will be called and you can do this:
protected void Page_Load(object sender, EventArgs e)
{
//Page_Load of Site.Master.cs
if (!IsPostBack)
{
txtSomeControl.Text = SiteMaster.MyValue;
MyUpdatePanel.Update();
}
}
No matter how many pages you will redirect, the Master Page will always read the values from your static variables and all you need is to assign values before do the redirection.
I've added an invisible Panel in the Masterpage and hide all the controls inside. Instead of posting to another page i'm filling the controls with the data and reveal the Panel.
I found that this is faster and easier.
Thanks for your help

asp.net - RadioButton "CheckedChanged" event does not work when it is unchecked

I have two RadioButtons on my Web Form and here is the code:
protected void RadioButton1_CheckedChanged(object sender, EventArgs e)
{
}
protected void RadioButton2_CheckedChanged(object sender, EventArgs e)
{
Response.Write(DateTime.Now.ToLongTimeString());
}
When I check RadioButton2, time appears on the page but when I check RadioButton1(RadioButton2 is unchecked now) it does not update the shown time and removes it.
the event function must be called when it checks and unchecks.I don't understand what is wrong here and why the time disappears
(As it is obvious, I know about GroupName property and AutoPostBack. My problem is something else)
You can check property of each control and check AutoPostBack=True
and also if checked="true"
I tried it on different ways and opened my pages with different browsers and I figured out a few things. the most important of them which is related to my problem:
When a control Calls back, the page refreshes and that is why the time disappears. It sends the status of all controls using post method to itself and they would be the same way as they were. But the time is not written on a control and it would not be saved.
As I said if it was for example on a Label, the text would be kept:
Label1.Text = DateTime.Now.ToLongTimeString();
It answers the first question but I still think that the event function must be called when the RadioButton is being unchecked.

asp.net dynamic user control button click issue

I made researching about this subject I could not find proper answer.
In my default.aspx page, I have a treeview. Codes are in default.aspx like below:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
Control ucont;
if (TreeView1.SelectedNode.Value == "Yeni Dönem")
{
ucont = LoadControl("usercontrols/yenidonem.ascx");
PlaceHolder1.Controls.Add(ucont);
}
else
{
ucont = LoadControl("usercontrols/tabloktar.ascx");
PlaceHolder1.Controls.Add(ucont);
}
}
I load user controls dnynmicaly. User controls are have button control. I can not fire user control's button click when I load it dynamcally. How can I solve this ?
Thanks.
First of all, I would not recommend adding control dynamically later than in Page_Load event. Other things to remember is that You should add it on each page load and assign unique ID value the control that does not change between postbacks.
In this case, the easiest way would be to always add both controls to the page and show appropriate one using Visibility property.
If that's not suitable for You, try to move the code from TreeView1_SelectedNodeChanged to the Page_Load event and load appropriate control on each postback until it should be changed to another one.
I haven't tested this, so if You have any issues when using thise answer, let me know in the comments and I'll try to help.

How to dynamically change master page's master page?

I am trying to change the master page dynamically, and although it's easy to do from a content page (overriding OnPreInit), there is no such event for a master page. Is it possible to introduce this event somehow?
UPDATE: I got halfway there by going via the PreInit of the pages at the bottom of the ladder, turns out you can do things like base.Master.MasterPageFile = "/master.Master";, but for some reason this doesn't load the stuff in the header of the top-most master page, namely stylesheets.
Quoting from: Can I change a nested master page's master dynamically?
Just tested this and it works from the PreInit of the Page that is using the nested MasterPage.
protected void Page_PreInit(object sender, EventArgs e)
{
this.Master.MasterPageFile = "/Site2.Master";
}
Obviously you will need to ensure that the ContentPlaceholderIds are consistent across the pages you are swapping between.
If you overrode the MasterPageClass and added your own onPreInit you might could do it, but I don't think even that would work. There's definitely no construct for it according to Reflector, nothing to even override, altho since it inherits UserControl then there's always OnInit ... alternately you could attempt to override get_Master() but that might not work either ...
Use the masterpage constructor.
Let's say you want to use a different master page without a menu, pass query string NoMenu.
protected void Page_PreInit(object sender, EventArgs e)
{
//You'll go through infinite loop if you do not check if we already have the new master page, this will switch to different master page if requested without a menu for example
if (Request.QueryString["NoMenu"] != null && this.MasterPageFile != "/MasterPageNoMenu.master")
{
this.MasterPageFile = "/MasterPageNoMenu.master";
base.OnPreInit(e);
}
}

asp.net: How to get a button to affect the page contents

In Page_Load I populate an asp:Table with a grid of images. I have a button that when pressed I would like it to repopulate the page with different images.
However it appears that when the button is pressed Page_Load is called again, followed by the script specified by the button. I thought that I could simply set a variable in the button script which is checked during Page_Load, but this will not work.
What is the most asp.netish way to approach this? Should I be populating my table somewhere other than in Page_Load, or should my button be doing something different?
Your button event gets called after page load. As such, you should put your button code in there.
I'm not terribly sure why you'd try to stuff all of your event code into Page_Load, but it's best to keep it separated.
GOOD
protected void Page_Load(object sender, EventArgs e)
{
MethodThatDynamicallyCreatesControls();
}
protected void MyImage_Click(object sender, EventArgs e)
{
MyImage.Property = newValue;
MyImage2.Property = newValue2;
PopulateTables(newValues);
}
BAD
protected void PageLoad(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
//Check to see if "MyButton" is in the Request
// if it is, it's the button that was clicked
if (Request["MyButton"])
{
MyImage.Property = newValue;
MyImage2.Property = newValue;
PopulateTables(newValues);
}
}
}
As rick said, it's all a matter of understanding the postback.
page_load gets fired every time the page is refreshed. however in many cases, you only want certain things to happen on the first time a page is loaded. in your case, you want the default images to load. by putting all 'one time' events for a page load in a
if (!Page.IsPostback )
{
}
it will only fire on the first time the page is loaded. this is what you want to load your first set of images.
Then in your button click event (which triggers a postback), the code within the if statement will not execute again. and you can load your second set of images in your button's event handler.
That button you're using should call a method in your code behind,so you can know that the button is was clicked, ex:
protected void Important_ButtonClicked(Object sender, EventArgs e)
{
//do what I want to do
}
<asp:Button id="Button1"
Text="MakeChanges"
OnClick="Important_ButtonClicked"
runat="server"/>
Actually I understand what your problem is now, seems like you just have values being set in your page load with no condition check in you page load, so every time you have a postback it refreshes the page to original state, the reason for that is because everytime you trigger a refresh(postback) on the page, the pageload method is invoked, so you need to set original setting in your page load,but have them in the condition, as
if(!Page.Postback) which gets triggered the first time you visit this page. Which means this is where your defaults go and if(Page.Postback) is where your always true things should go. ex:
protected void Page_Load()
{
// this is where I want things to always happen whenever the page is loaded
//for example, no matter what happens I want a certain image in the background
if(!Page.Postback)
{
//set my values for the first and only time
}
else //hint Page.Postback
{
//you can play with the page here to make necessary changes
//but Button click method will still be invoke so thats where button click
//changes should be made
}
}
A PostBack happend when the page is reload. The first page load, Page.IsPostBack has value false. When an event happend, Page.IsPostBack has value true.
So doing the thing like this will definitely works
void Page_Load()
{
if (!Page.IsPostBack)
{
//do your first time binding data
}
How to: Create Event Handlers in ASP.NET Web Pages
EDIT:
Your state change events are not going to fire correctly if you re-bind controls(ie:DropDownList) data on every postback.
void Page_Load()
{
if (!IsPostBack)
{
//load your data
}
}

Resources