I have a button (view state enabled) in Master web page and set it to visible=false in one of the child web pages. If a second child page is opened, the button state (visible=false) is not persisting.
It seems viewstate is only valid for one page and is not transferred to other web pages. Is there some kind of trick to make viewstate global for all web pages?
No, viewstate is page specific. You will need to use something like a session variable or a querystring parameter to pass your state between pages.
No, You cannot make view state global, they are page specific. I would suggest to use cookies if you really want to make it client side otherwise you can use session.
If you need to store on a "global" level, you should be using the Application State. You could also use Cache Object.
You may be wanting to pass values from one page to another, you can achieve this by using the Context object in combination with the Server.Transfer.
1) You need a public property on the source page returning the Value to pass
namespace SomeNameSpace
{
public partial class SourcePage: System.Web.UI.Page
{
public string ValueToPass
{
get
{
if (Context.Items["ValueToPass"] == null)
Context.Items["ValueToPass"] = string.Empty;
return (string)Context.Items["ValueToPass"];
}
set
{
Context.Items["ValueToPass"] = value;
}
}
........
}
}
2) Do a Server.Transfer(DestinationPage.aspx)
3) In the Page_Load event of the destination page
namespace SomeNameSpace
{
public partial class SourcePage: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var value = this.Context.Items["ValueToPass"];
}
}
}
Hope this helps
Related
I don't think the title is the best description for my problem but, the problem is as following:
I have a base class like:
public class BasePage : System.Web.UI.Page
{
public static ProjectDTO Project { get; set; }
// some other code
// Setting the project once per session.
public void SetProject()
{
Project = (ProjectDTO)HttpContext.Current.Session["Project"];
SiteMaster masterPage = Master as SiteMaster;
masterPage.Project = Project;
}
}
And then i have an aspx page like:
public partial class SomePage: BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
//callling the base method to set the project
SetProject();
}
//some db method which requires the Project.Id property.
GetSomeInfo(Project.Id)
{
//irelevant code
}
}
Everything works fine, but, when i have 2 users online at the same time, they will obviously call the SetProject method, and if one of them uses GetSomeInfo method, the Project.Id property will be the latest one set, not the one from the current user session.
Can anyone help me fix this problem?
PS:
A dirty fix would be to read the session variable every time i have to use the Project, won't be a problem, but my page has like 10 methods requiring that property (a lot of redundant code)
A secondary fix would be to declare a public property on SomePage and use that, but then, i would find Project from the BasePage redundant and i don't like that approach because there are quite a few pages requiring the Project property and using the BasePage (filters, searches, etc on objects belonging to that Project)
EDIT After some more testing, 2 different users at the same time, and after Glubus comments, the problem happens only when the page is loading for one of the users (the user which is not loading anything will get wrong results from the database while the other user is loading a page.)
EDIT2 The workflow is as following:
User goes to home page where a list of projects are available (read from db) -> clicks on one project (when the user clicks the project i'm setting a session variable to be read later). Then the user can see/use other data related to this project.
EDIT3
When a user click on a project, they will navigate to a Dashboard page. Here, on the Page_Load even i'm setting the session variable, like:
public partial class Dashboard : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
int projectId;
int.TryParse(Request.QueryString["projectId"], out projectId);
if (projectId > 0)
{
Session["Project"] = ProjectSvc.GetProjectById(projectId);
SetProject();
}
}
}
ProjectDTO class:
public class ProjectDTO
{
public int idProject { get; set; }
public string Title { get; set; }
public string Users { get; set; }
public string Description { get; set; }
}
I'm setting the Project to the Site Master because i have a label which requires to be seen on the screen with the Project Name and description.
In order to access the Project from the current Session from all places, including WebMethods, declare a static readonly property in BasePage that directly accesses the Session.
public class BasePage : System.Web.UI.Page
{
public static ProjectDTO Project
{
get {return (ProjectDTO)HttpContext.Current.Session["Project"];}
}
// some other code
// Passing the Project to the Master.
public void SetProject()
{
SiteMaster masterPage = Master as SiteMaster;
masterPage.Project = Project;
}
}
You can get rid of the SetProject() call altogether if you also use BasePage.Project to access the current project from the Site Master.
During testing, make sure that you are not using the same browser instance for testing. When session managements happens via cookies and you have two users logged in into the same browser instance, they will actually use the same ASP.net session.
Perhaps a worst case scenario solution - but....
If you are really intent on making the Project variable accessible to all subsequent users, you maybe need to move away from sessions and just declare it as a static?
This way it will be shared application wide, retaining the last assigned value.
In my MainPage.xaml I've got a SplitView that loads many pages inside a frame created in it's SlplitView.Content.
I've got data in a MainPage's variable that needs to be sent to every page that loads in my SplitView content's frame according to the ListBoxItem clicked.
Also in the current page I may have to update the MainPage's variable before a new page is loaded.
How can I do this? Is there a way to declare a global variable? Can I transport that information from a page to another updating it's value on the parent page?
I think you can declare a public static variable in App Class in App.xaml.cs, and use it in any pages in the app.
In App.xaml.cs:
sealed partial class App : Application
{
...
public static string MyTestVar { get; set; }
...
}
In MainPage.xaml.cs:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
App.MyTestVar = "world";
}
}
And for some other cases like implementing a setting page, you can check Store and retrieve settings and other app data.
Complementing the last answer I solved my problem by declaring an internal static variable in my "App.xaml.cs".
internal static string foo = "";
Then to access it I used:
App.foo = "my string";
There is also a more elegant way to preserve and restore page data when leaving it (which is what I needed) as follows: https://msdn.microsoft.com/pt-br/library/windows/apps/ff967548%28v=vs.105%29.aspx
Is there a way to get access to a puplic property on a user control from a nested master page?
Let me explain further
I have 3 deep master pages
global.master
LargeTopNav.master (inherits global.master)
LargeTopNav25-50-25.master (inherits LargeTopNav.master)
feature.aspx - This page is where I would like to access a custom user control I have on LargeTopNav.master to be able to set a property.
I'm fairly new to .net so any help is appreciated.
There is a MasterType property you could set on the feature.aspx page like e.g.:
<%# MasterType VirtualPath="~/masters/LargeTopNav.master" %>
Then, in turn, provide access to the control's property through a property you create in your LargeTopNav.master master page class:
public partial class LargeTopNavMaster : MasterPage
{
// ...
public string ThePropertyOfTheContainedControl
{
get { return MyContainedControl.TheProperty; }
set { MyContainedControl.TheProperty = value; }
}
// ...
}
Last, in your feature.aspx page, access the property of the master page that provides access to the underlying control:
public partial class Feature : Page
{
// ...
protected void Page_Load( object sender, EventArgs e )
{
Master.ThePropertyOfTheContainedControl = "Some nice text.";
}
// ...
}
Generally what I do in this scenario is make your master page implement an interface (which will have the property for your user control), and then from your page feature.aspx use this.Master (or this.Master.Master, make sure to check for null) to get a reference to the master page.
Then, just typecast the master page to your interface, and access the property.
I have the master page code behind like this:
public partial class TheMasterPage : System.Web.UI.MasterPage
{
string test = null;
protected void Page_Init(object sender, EventArgs e)
{}
}
When I'm in the Page_Load function in the code behind of the content page, I don't see the variable test as being available. Am I declaring it wrong?
Thanks.
Your property should be public and should have get, set
public string test
{
get; set;
}
I already answered it a little early Accessing property of master page inside content page
Having a master Page is not the same as inheriting a page class. What you would want to do is have a public property on the master page, and then access that from the content page.
I have an asp.net page with many dozens of controls representing multiple database entities. I would like to track when any of the data for these entities is changed.
If I add a page member such as
public Page1 : System.Web.UI.Page
{
protected bool Entity1HasChanged { get;set; }
protected void RegisterChange(object sender, EventArgs e)
{
Entity1HasChanged = true;
}
}
Then for each control OnTextChanged event or equivalent I call a method that sets this boolean to true.
I would then like to run a method AFTER all control events have completed which does some database updates. What page event can I hook into to do this? Reading the page on the LoadComplete event it only states that all load events will have completed.
Does anyone know how I should achieve this? Am I doing this completely the wrong way?
Thanks,
Ian
Look at INotifyProperyChanged, INotifyPropertyChanging and INotifyCollectionChanged as your starting point.
Try OnPreRender.
ASP.NET Page Life Cycle Overview
This will also still allow you to modify the page output once you've completed the database operations (e.g. if you want to show a status box to say that the operations completed).
This is a really good question. I messed around with something quick that I think will work. You could create your won TextBox that inherits from TextBox:
namespace ServerControl1
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class TextBoxWithChange : TextBox
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public bool HasEntityChanged
{
get
{
bool hasEntityChanged = (bool) ViewState["HasEntityChanged"];
return hasEntityChanged;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
}
}
Then you could write a little jQuery script to change that attribute when the client side OnTextChanged event fires. On submit of the form you then could query that HasEntityChanged attribute for any of these TextBoxes.
For this example I put the server control in it's own Library and registered it like this:
<%# Register TagPrefix="MyCompanyName" Namespace="ServerControl1" Assembly="ServerControl1" %>
Then you can declare it on your page like this:
<MyCompanyName:TextBoxWithChange ID="ChangerTextBox" runat="server" HasEntityChanged="false"></MyCompanyName:TextBoxWithChange>