I have a web user control that holds three dropdownlists: One holds days, second holds months and the third one holds years. Days and months are static.But year items will change upon need to avoid entering wrong year. Let me first list here what I do in order, then i'll ask my question:
I have a private int yearSpan.
In private method PopulateYearList I say:
int year = DateTime.Now.Year;
int span = year - this.yearSpan;
for (int i = span; i <= year; i++)
{
ddlYears.Items.Add(i.ToString());//Here I get NullReferenceException
}
I've overriden the default constructor to receive yearSpan as an argument:
public DatePicker(int yearSpan)
{
this.yearSpan = yearSpan;
this.PopulateYearList();
}
Now, as you might have guessed in my PopulateYearList method I get NullReferenceException because I try to add an item to ddlYears that has not been constructed yet. What would you suggest to do to solve this?
don't call this.PopulateYearList in constructor, rather call it on Load event of user control.
Also I prefer you to not use constructor of your user control rather use public property as it can maintain its state.
e.g. in Page:
protected void Page_Load(object sender, EventArgs e)
{
UserControl1.TimeSpan = DateTime.Now.Year;
}
In UserControl:
protected void Page_PreRender(object sender, EventArgs e)
{
if(this.IsPostBack)
{
PopulateYearList()
}
}
As long as you don't make any change to that control from your parent page, any event after your controls are load , you can call this.PopulateYearList. I called it in PreRender event as if somebody changed the value from page it would be overriden by user control value at the end, thus I am sure my values are not tempered.
Let me know if I am missing something.
Ether call the PopulateYearList in the Page_Load of your usercontrol. Like this:
protected void Page_Load(object objSrc, EventArgs e)
{
if(this.IsPostBack)
PopulateYearList()
}
Or make the PopulateYearList public and call it on the page when you bind the page controls
Related
I've just started learning ASP.NET and I'm facing a problem with getting textbox values. I want to do a simple calculator with only 4 basic operations but what happens is that after I click the + sign and click Go, I see that I didn't store the first number at all. Second number is fine though. Here is a sample of my code.
public partial class deafult : System.Web.UI.Page
{
public TextBox output = new TextBox();
public double temp,tempAdd, calc;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
tempAdd = Convert.ToDouble(output.Text);
output.Text = String.Empty;
}
//User enters another number after clicking Add button then clicks Proc
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
}
I debugged and tempAdd is always 0 but I get the number in temp. temp variables and calc is defined public.
You essentially have the problem with all of your variables being re-initialized on load of the page. Unlike winforms, web is stateless.
There are ways of persisting state between refreshes, however. The most obvious choice for your application would be to only go to the server once with the both values and what you want to do with them. ie One button click.
However, for personal edification, it may be worth looking up ViewState. This allows you to store values in an array of sorts and retrieve them even after a refresh.
There are also Session and Application level arrays in ASP.NET that work in similar ways.
Every time you call the page (by events) all your properties is initialized.
Try to do all your logic in one event or store your properties in manager / service / db.
In web (Asp.Net) on every postback properties will get cleared, try to use ViewState or Session variables to hold these values. Refer Asp.Net State Management concepts from MS.
Hope this may help you.
Web controls are State less so you should user session sate to hold the first value then do your stuff...
Ex:-
protected void btnAdd_Click(object sender, EventArgs e)
{
Session["tempAdd"] = output.Text;
output.Text = String.Empty;
}
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
string oldval=Session["tempAdd"] != null ?Session["tempAdd"].ToString() :"";
if(oldval!="")
tempadd=Convert.ToDouble(oldval);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
I'm having a hard time building a filtering system in Sitecore 7.
I have 2 sublayouts, on the same level of the page.
Sublayout A is a sidebar that contains a list of checkboxes and has an event that populates a List with the selected values.
Sublayout B displays a set of items.
What I would like to do, is send the populated List from sublayout A to sublayout B in order to filter the items list based on what the user selected.
I was able to do this by passing the data through Session, but this is not an optimal way of handling that data.
I've tried defining a property for sublayout A and loading the list there, but I can't get the exact instance of sublayout A from sublayout B in order to read the populated property.
Also, trying to Page.FindControl("IdOfSomeElementFromSublayoutA") always returns null in Sublayout B. Even though I've casted Page as the .aspx page that contains both Sublayouts.
I'm using Sitecore 7 Update 2.
Thanks a lot for your time.
The best way to do this is by raising (and subscribing to) events using the Sitecore.Events.Event class. Your sidebar sublayout would raise an event using something like the following within a button's click event handler:
Sitecore.Events.Event.RaiseEvent("YourEventName", new YourEventArgsClass { Property = "SomeValue" });
then in the other sublayout you would need to have the following set up in order to handle the event:
public partial class YourOtherSublayout : System.Web.UI.UserControl
{
private System.EventHandler eventHandlerRef;
protected void Page_Load(object sender, EventArgs e)
{
eventHandlerRef = EventHandlerMethod;
Sitecore.Events.Event.Subscribe("YourEventName", eventHandlerRef);
}
protected void Page_Unload(object sender, EventArgs e)
{
if (eventHandlerRef != null)
{
Sitecore.Events.Event.Unsubscribe("YourEventName", eventHandlerRef);
}
}
private void EventHandlerMethod(object sender, EventArgs e)
{
if (e != null)
{
//do stuff here
}
}
}
Note: it is important to keep the Page_Unload code there otherwise you will see the EventHandler method being called multiple times.
After adding a control in the dayrender event, is there a way to find the control later? I have tried
calendar.FindControl("lblSample")
but without success.
Here is some of my code to be more clear:
protected void calSample_DayRender(object sender, DayRenderEventArgs e)
{
Label lblSample = new Label();
lblSample.ID = "lblSample";
lblSample.Text = "Sample";
e.Cell.Controls.Add(lblSample);
}
After the day render event and the page loads completely, I have a link button event where I try and get the control back
protected void lbtnSave_Click(object sender, EventArgs e)
{
//Not working
Label lblSample = calSample.FindControl(lblSample);
//Also can't get to work, this was using Ross' suggestion and the recursive find function he wrote about. I'm probably just not using it correctly.
Label lblSample = ControlFinder.FindControl<Label>(calSample, "lblSample");
}
The issue was because the control was not added to the page until the dayrender method - meaning you could not get a reference to it on a post back. Using the Page.Request.Params collection the OP was able to grab the value out on the postback.
The problem is that the find control is not recursive and the control you want is probably inside another control.
This shows you how to make a recursive find control method that would help: http://stevesmithblog.com/blog/recursive-findcontrol/
Alternatively if you post the calendar controls code I can probably help you a bit more.
Ross
This answer is because of Ross' comment above showing me that I could use the Page.Request.Params to find the value I was after. It's not the cleanest solution but it works!
If you add a dropdownlist to a calendar control in the day render event
protected void calSample_DayRender(object sender, DayRenderEventArgs e)
{
DropDownList ddlSample = new DropDownList();
ddlSample.ID = "ddlSample";
ddlSample.DataSource = sampleDS;
ddlSample.DataBind();
e.Cell.Controls.Add(ddlSample);
}
You can get the selected value back like this, of course I need to put in more checks to verify that the dropdownlist exists, but you get the picture
protected void lbtnSave_Click(object sender, EventArgs e)
{
string sampleID = Page.Request.Params.GetValues("ddlSample")[0];
}
I'm with a problem and want to know if someone can help me.
I'm creating a table with some controls and I want to save all control values in every postback. As the controls are just defined after the page_load, I can't solve my problem this way:
object o;
protected void Page_Load(object sender, EventArgs e)
{
o = createObject();
Create_Table();
if (Page.IsPostBack)
Save_Data();
}
I thought I could execute Save_Data() at the begining of every postback event, but I think that should exist a better way to solve my problem.
Thanks.
Since you want it to be at the page level why not use ViewState? Since o appears to always be set with the same data there probably isn't need to set it more then once, though if you really want to you can remove the if not postback stuff...
protected object o
{
get {
return ViewState["o"];
}
set {
ViewState["o"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack) { o = createObject(); }
Create_Table();
if (Page.IsPostBack)
Save_Data();
}
Your variable 'o' will not contain your original value once the postback is done. This is because each request creates a new page object on the server and your member variable values will be lost. It would be better to use the built in 'Session' property to save your data between requests.
See my answer here
I have tried what seems like everything - I've done similiar things many times before, but I'm obviously missing something.
I have a UserControl (ucA) - on ucA is a LinkButton that loads a different UserControl (ucB) programatically into a panel on ucA. ucB has TextBoxes, etc.
Why isn't my control maintaining it's state? ie: The textboxes are loosing thier value on postback - the control tree shows the name of the control and the Form values show the value (in trace.axd)
Here is the code for ucA (basically)
public int SlideCount
{
get { return Convert.ToInt32(ViewState["SlideCount"]); }
set { ViewState["SlideCount"] = value; }
}
protected void LinkButton1_Click(object sender, EventArgs e)
{
SlideCount += 1;
LoadSlideControls();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
LoadSlideControls();
}
private void LoadSlideControls()
{
this.pnlAnnouncementHolder.Controls.Clear();
for (int i = 0; i < SlideCount; i++)
{
this.pnlAnnouncementHolder.Controls.Add(
LoadControl("AnnouncementSlide.ascx"));
}
}
Heres a full example of what im trying to do:
http://keithsblogs.com/ControlTest2.zip
The problem Vyrotek points out is that the control is added a little to late to the lifecycle on the click event - anyone have any ideas?
I just tried to recreate what you have setup and I dont seem to experience the same problem. Would you like me to send you my Solution somehow?
Final Edit, I promised -
Try this solution: http://www.vyrotek.com/code/ControlTest2.zip
I am installing express edition as I type. By that time, why should you clear the controls on click of the button? cant you just add/load the uc once control on click of the link?
By doing this, you would not be clearing the old controls and they would retain the value.