I am using devexpress controls in my page, but that is not the problem.
Here is what happens, I have created a property in the page with a get only, this property will retrieve query string value from a ViewState. I store the value in the ViewState on page load event which is enclosed in !IsPostBack. After I store
note that i have put an update panel on my master page.
I searched the net and found that ViewState values are never stored in callbacks, I don't know if that is the reason. Here is my code:
public partial class _Default : BasePage
{
private Int64 RequestId
{
get
{
return (Int64.Parse(ViewState["RequestId"].ToString()));
}
}
protected override void Page_Load(object sender, EventArgs e)
{
//Check for security
base.Page_Load(sender, e);
if (!IsPostBack)
{
GetQueryString();
gridBind();
}
}
private void GetQueryString()
{
string requestId = this.Request.QueryString["RID"];
if(!String.IsNullOrEmpty(requestId))
ViewState["RequestId"] = Int64.Parse(this.Server.UrlDecode(requestId))
else
ViewState["RequestId"] = 0;
}
}
I edited the question, the first problem i had was due to the IE7 stupidity, but nevertheless ViewState after each postback is null. I tried to use the EnableViewState but it's always null. It's the same in any page I use in my solution. We can't use ViewStates at all. There is definitely something wrong.
Related
MasterPage:
public string strP;
public void Page_Load()
{
strP = #"SELECT * FROM ...";
}
Content Page:
public void Page_Load() {
if (!Page.IsPostBack) {
string strO = Master.strP; //strO = null
}
}
I know I am supposed to use the Page_Init but can someone assist me in ensuring I am able to get the set value of strP from the content page.
This is down to the page lifecycle...
The Content Page's load method will fire BEFORE the Masterpage's Load method. Slap a breakpoint in both Load event handlers and you'll see what I mean...
The Page_Load() is meant for you to do some things related to the page. You postpone some things you can't do in the constructor for the relevant objects missing (like the Request, Response, etc).
Looking at your code, setting a static SQL statement, which doesn't require any interaction with the request, etc. can be done in the constructor already.
If it is related to the request, you could put that in the Init event of the master page.
Also see my related answer on Variables from Master Page always empty.
In case others have the same questions or would like to know how to achieve what I requested, here is the detailed steps:
First assign the public variables in the MasterPage:
public string strO;
protected void Page_Init(object sender, EventArgs e)
{
strO = #""; //whatever the variable supposed to be
}
Call in Content Page:
public string strOT;
protected void Page_Init(object sender, EventArgs e)
{
strOT = Master.strO;
}
I have a MasterPage with a GridView on a UpdatePanel. On one of my content pages I have a button which adds items to a session which I want to appear in the Gridview which is on the MasterPage. I'v got the items in the Gridview but have problem with refresh or postback or something like that. Does anyone have an answere to this?
If you have refresh issue in updatepanel, then it means that the post back button is aether not inside the update panel or the panel is not updated manually.
For this case I assume you cant put the button inside the panel as it is part of content page, so i suggest you set panel's UpdateMode to conditional and have some refresh method on your masterpage. In order to see this method in the content page make some Interface with this method and let the masterpage use this interface.
then in the content page take the masterpage referense and consume the refresh method.
e.g.
The interface
public interface IMaster
{
void RefreshPanel();
}
The masterpage
(note it uses the IMaster interface that we created before)
public partial class MasterPage : System.Web.UI.MasterPage, IMaster
{
protected void Page_Load(object sender, EventArgs e)
{
//Load items from session
}
public void RefreshPanel()
{
UpdatePanel1.Update();
}
}
The content page
public partial class ContentPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
//Add items to session
//....
//Now refresh the updatepanel on the masterpage
IMaster masterPage = Master as IMaster;
masterPage.RefreshPanel();
}
}
You will need to look into using Events and Delegates. Basically, you will create an Event on the Usercontrol which your MasterPage will react to. There are many other websites with examples, so just google ASP.NET Events and Delegates.
I have a class level price variable decalred inside a page, like this:
public partial class _Default : System.Web.UI.Page
{
private MyClass myVar = new MyClass();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
myVar.LoadData();
myVar.ShowData();
}
}
protected void cmdRefresh_Click(object sender, EventArgs e)
{
myVar.ShowData();
}
}
The problem I have is that after the initial load, the first time that the button is pressed it seems to reset myVar, and all its data is lost. Is this a known issue with ASP.NET and is there a workaround?
Use the ViewState to store the class, if you just need to save the classfor the current page. IF you want to save it for the entire site, then look into things like Sessions.
private MyClass myClass
{
get {
if (this.ViewState["myVar"] != null)
{
return (MyClass)this.ViewState["myVar"];
}
}
set{
this.ViewState["myVar"] = value;
}
}
The variable myVar will never be persisted across postbacks, you need to use some method of caching, such as Application / Session / ViewState / Cookies.
Yes that is a know functionality. Basically you page object is created for every request, so properties are set for you (IsPostBack being one of them) but you need to take steps you self to make sure that fields (declared in code) is populated every time. In this particular case either by fetching Them or keeping Them in the form (viewstate) or session data. Which one to choose should depend on such as size of data, time to refetch, data store loads etc.
How can I pass user control properties to the page AND make these properties available to all methods on the page (and not just to one method that is fired on a control action, e.g. onControlClick)
I have a set up of essentially 3 pages:
user control (ascx/cs)
class (cs) - that contains user control properties
host page (aspx/cs) - references the user control
The user control consists of 3 interrelated dropdowns. I'm having success passing these dropdown values through a class onto the page via an event that is fired when a user clicks on the dropdown menu. So this way the host page is continously aware of the values in the user control. However, I want the page to use the control's properties (stored in a class) on all of its methods - how do I make this user control class available to all?
Also I'm using ASP.NET and C# by the way.
Here's the Code (not sharing the full code here - just the snippets of a similar code block)
On the ASPX for Menu Host Page:
<linked:LinkMenu2 id="Menu1" runat="server" OnLinkClicked="LinkClicked" />
Host Page (cs):
protected void dropdownclicked(object sender, ddtestEventArgs e)
{
if (e.Url == "Menu2Host.aspx?product=Furniture")
{
lblClick.Text = "This link is not allowed.";
e.Cancel = true;
}
else
{
// Allow the redirect, and don't make any changes to the URL.
}
}
Host Page (aspx)
<asp:dropdowncustom ID="dddone" runat="server" OnddAppClicked="dropdownclicked" />
Control (cs)
public partial class usercontrol_tests_dropdown1 : System.Web.UI.UserControl
{
public event ddtestEventHandler ddAppClicked;
}
public void selectapp_SelectedIndexChanged(object sender, EventArgs e)
{
ddtestEventArgs args = new ddtestEventArgs(selectlink.SelectedValue);
ddAppClicked(this, args);
}
Class:
public class ddtestEventArgs : EventArgs
{
// Link
private string link;
public string Link
{
get { return link; }
set { link = value; }
}
public ddtestEventArgs(string link)
{
Link = link;
}
}
public delegate void ddtestEventHandler(object sender, ddtestEventArgs e);
Hopefully this is what you're after. The best way to do it is to expose your controls as public properties from your user control. So, in your user control, for each drop down list add a property:
public DropDownList DropDown1
{
get { return dropDownList1; }
}
public DropDownList DropDown2
{
get { return dropDownList2; }
}
You can do the same for any other properties you want to access on the host page:
public string DropDown1SelectedValue
{
get { return dropDownList1.SelectedValue; }
set { dropDownList1.SelectedValue = value; }
}
Then, from your host page you can access the properties through the user control:
string value = UserControl1.DropDown1SelectedValue;
or
string value = UserControl1.DropDownList1.SelectedValue;
Here's a couple of other answered questions that you might find useful as I think (if I've understood correctly) this is what you're doing:
Getting data from child controls loaded programmatically
How to change the value of a control in a MasterPage.
Lets say i have this usercontrol
public class test : UserControl {
public int Count { get; set; }
public test() {
Count = 3;
}
public override DataBind() {
aRepeater.DataSource = dal.GetObjects(Count);
base.DataBind();
}
}
and i use it on my page like this
<my:test runat="server" Count="<# something %>" />
my problem now is that i am not able to get the value of Count in my usercontrol before after the call to base.DataBind(). I guess its something with databinding values to itself. The workaround sofar has therefor been
public override DataBind() {
base.DataBind(); // to bind values to self
aRepeater.DataSource = dal.GetObjects(Count);
base.DataBind(); // to bind new values that is dependent on the the first bind
}
It works, but it just doesn't seem right. My question is therefor whats the best practices is for this scenario.
Just override OnDataBinding method, not DataBind:
protected override void OnDataBinding(EventArgs e) {
base.OnDataBinding(e);
aRepeater.DataSource = dal.GetObjects(Count);
}
DataBind method essentially consists of two steps: 1) OnDataBinding(), 2) DataBind() for each child control.
It makes sense, because Count="<# something %>" occurs at DataBind(). I think you should handle all the data binding at DataBind() in this case (and not to use page binding methods). Of course this is only a matter of beautifying the code - nothing more.
Do you have to set the Count property of your user control in you .ascx file? How about not having a Count property at all or setting Count in the code behind of the page that includes the user control?
<my:test runat="server" id="test1" />
Code behind:
//User control code behind. GetCount() returns an int.
public override DataBind() {
aRepeater.DataSource = dal.GetObjects(GetCount());
base.DataBind();
}
or
//Page that has the user control.
protected void Page_Load(object sender, EventArgs e)
{
this.test1.Count = 5;
}
//User control code behind.
public override DataBind()
{
aRepeater.DataSource = dal.GetObjects(this.Count);
base.DataBind();
}