Created a user control.
Within user control, I have a simple control, like a Literal, in the markup.
In the user control's Page_Load, I attempt to change a property, like Text, on control created in the markup.
Control is null.
What in the world am I missing?
(Begin rant: I am doing all these fancy things with login systems and dynamically adding/modifying controls on the fly with AJAX, etc, but I can't change an f'n static control's property! I can't even Google such a simple problem without finding something else! In the past, I had to dynamically generate the whole bloody page to avoid this idiotically simple problem. End rant.)
Page.LoadControl() has two overloads, one accepts a Virtual Path, the other accepts a Type.
Sometimes, when using the Type version overload, you get this kind of behaviour.
When possible, try to use the Virtual Path version of LoadControl.
Edit: as an FYI, this is because the actual Type of a User Control is not what you would expect it to be. ASP.NET kind of 'wraps' the Type of the User Control.
I figured out a way after analyzing the order a page is executed (http://msdn.microsoft.com/en-us/library/ms178472.aspx).
protected void Page_Init(object sender, EventArgs e)
{
literalGameName.Text = myGame.Name;
}
Init happens after controls have been made, but not after the page is done loading control-stuff.
I know this is an old one, but wanted to chime in on how I fixed a similar issue I was having. I have a usercontrol with an asp:Panel on it that I was trying to set the visibility off during the Page_Load, but the control was coming up null. I then noticed that my Page_Load definition looked like this:
protected void Page_Load(object sender, EventArgs e)
{
_myControl.visible = true;
}
When in fact, I needed the definition to look like this:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_myControl.visible = true;
}
Doing the override fixed the issue.
Related
Quite simple question, but I am having loads of issues with it.
protected void restorePagerNumber()
{
if (Session["PageNumber"] != null)
{
System.Diagnostics.Debug.Write(Session["PageNumber"]);
DataPager pager = searchListView.FindControl("searchDataPager") as DataPager;
pager.SetPageProperties((int)Session["PageNumber"] * pager.PageSize, pager.MaximumRows, false);
}
}
Thats what I currently have, I tried to use it before databind, after data bind, none of them seem to work. Can I actually change pager value after creating new object?
Doesnt sound logical, but I cannot access datapager without that. Is there another way to access dataPager that is in a listView and maybe another way to set its page number.
Cheers
I found a scenario that is similar to yours (https://web.archive.org/web/20210125144848/http://www.4guysfromrolla.com/articles/021308-1.aspx) and I verified that the sample application works calling SetPageProperties() at run-time.
Be sure to change the last "databind" argument in your SetPageProperties call to from False to True:
pager.SetPageProperties((int)Session["PageNumber"] * pager.PageSize, pager.MaximumRows, true);
then make sure you're calling restorePagerNumber at PageLoad
protected void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack) {
restorePagerNumber();
}
}
Hope that helps.
I have a problem that I can't resolve on the server side of my project.
I'll explain:
I have a page named Global,this is ASP.NET page.
This page uses a UserControl named CateGories.
Now I have a button on this UC page,that when I press I want to invoke a function on the Global page that makes a connection with my DB.
I decided to use delegates(events)
This is the code.
Global page:
//here i add my function to the event
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ShowCurrentTime.Text = DateTime.Now.ToString();
}
CateGories ClassCat = new CateGories();
ClassCat.MainDel += PopulateLinks;
}
//this is the function that the event will run
public void PopulateLinks(string CategoryName)
{....}
Code of the UC page (CateGories):
//delegation of the event
public delegate void Click(string ButtonName);
public event Click MainDel = null;
//function that invokes when I click a button
protected void News_Click(object sender, EventArgs e)
{
if (MainDel != null)
{
MainDel(News.Text);
}
}
Now everythig should work fine, but there is a problem, when the compiler gets to the
if(MainDel!=null)
...
It doesn't get in the function, there go MainDel is null.
I can't see the problem here, why after I insert function to MainDel, its gets null eventualy...
I'll be happy if someone can help
thanks.
Max.
I think I've encountered this problem before, when working with web applications the way I would a windows application.
The problem lies in that when the page gets reloaded, a new instance of your page class is created so any values from the last server interaction are lost.
MainDel is indeed null for what I can see.
You're creating one instance of CateGories on your Web Form and another one on your User Control. And once you check it for beeing null on the UC the reference is to the not initialized object.
One possible way to do that is creating and adding the User Control programatically to the page before PageLoad() and keeping a reference to it so you can access it's properties.
Another solution could be using Page.FindControl to find the UC and make the subscription to the event.
The method names above may be incorrect, it's been a long time without working with web forms.
Ok I'm trying to understand how best to handle ViewState, for the programmatic setting of default values using C#. I understand that the construction of the ViewState hidden field is based on every value that is set after the OnInit event is triggered. What I'm not clear about is if there is a difference between using the control's constructor or the OnInit event to set default values.
public MyControl(){
this.Text = "SomeDefaultValue";
}
versus
protected override void OnInit(EventArgs e){
this.Text = "SomeDefaultValue";
}
I've seen some places that suggest testing the ViewState value for null in the get of the given property, like so:
public string Text {
get {
return this.ViewState["Text"] == null ?
"SomeDefaultValue" :
this.ViewState["Text"] as string;
}
set { this.ViewState["Text"] = value; }
}
I don't like that because it makes clearing the value confusing.
So, Is there any functional difference between using the constructor vs OnInit to set default ViewState values?
In terms of minimizing ViewState, there is no difference, as ViewState starts tracking after the OnInit method is run.
There are some functional differences, however: until the control is initialized, you cannot access other properties like the Page. For this reason, I usually prefer to use either OnInit or some handler tied to the Init event.
Also, be careful about overriding OnInit: you should call base.OnInit() to make sure that other event handlers for the Init event still get called.
I highly recommend that you read this excellent article on the topic: http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
Edit
To clarify, the ViewState starts tracking for a given control after the OnInit method is run for that control. So in the given example, you are safe to override OnInit like this:
protected override void OnInit(EventArgs e){
this.Text = "SomeDefaultValue"; // Make sure this happens before base.OnInit
base.OnInit();
}
This works because the Text property is saving the value to the ViewState of this control. However, let's say you have another child control (I'll use a Label as an example). That Label's OnInit will already have been run by the time your control's OnInit method is called. So if you want to change the Label's Text value, you'll need to do it during that label's OnInit phase (or sooner).
You could do it in the constructor of the current control:
public MyControl(){
this.Label.Text = "SomeDefaultValue";
}
... but as mentioned earlier you won't have access to the external control structure, which may be necessary in some cases. A good alternative in these cases is to use an Init event handler on the label itself. You can hook up the event handler itself in your constructor:
public MyControl(){
this.Label.Init +=
(sender, e) => this.Label.Text =
((TextBox)Page.FindControl("SomeControl")).Text;
}
... but this will only work if the control is declared directly as a member of your class. If the label is inside a template (like in a Repeater), you'll need to use markup to hook it up:
<asp:Label runat="server" OnInit="Label_Init" />
with the code-behind:
public void Label_Init(object sender, EventArgs e)
{
var label = (Label)sender;
label.Text = ((TextBox)Page.FindControl("SomeControl")).Text;
}
This latter example has the advantage of working in just about every circumstance I can think of, but it requires more boilerplate code, as well as a change in markup. So pick your poison based on your specific situation.
There is quite a detailed document on the ViewState over at MSDN:
...server controls don't begin tracking
view state changes until right at the
end of the initialization stage.
Second, when adding dynamic controls
that need to utilize view state, these
controls will need to be added during
the Page's Init event as opposed to
the Load event.
Just from this alone, I would say, if you're utilising the ViewState, use OnInit.
I have an UpdatePanel.
and I have a PlaceHolder inside this UpdatePanel.
There is a number of UserControls. One of them will be loaded dynamically,
according to some selections.
Control mycontrol = this.Page.LoadControl("myusercontrol.ascx");
myplaceholder.Controls.Add(mycontrol);
after loading a specific UserControl, I wanted to get the text written in
a TextBox that is in the loaded UserControl from the Parent page.
TextBox mytextbox = (TextBox) Page.FindControl("myusercontrol")
.FindControl("mytextbox");
The problem was the text is always empty !
What am I missing ?
I appreciate your help.
You should load your UserControl overriding OnInit as mentioned before. And why were you looking entire page to find the UserControl? You can use PlaceHolder.Controls...
This how I got it work
protected override void OnInit(EventArgs e)
{
Control userControl = this.Page.LoadControl("WebUserControl.ascx");
testPlaceHolder.Controls.Add(userControl);
userControl.ID="id";
base.OnInit(e);
}
protected void testButton_Click(object sender, EventArgs e)
{
Control testUserControl = (Control)testPlaceHolder.Controls[0];
//Control testUserControl=(Control)testPlaceHolder.FindControl("id");
TextBox mytextbox = (TextBox)testUserControl.FindControl("testTextBox");
testButton.Text = mytextbox.Text;
}
When you say that the text is always empty, do mean the TextBox object is null or literally the .Text of the textbox is empty?
Remember that in web applications you have to post back to the server to refresh results and update controls among other things.
Try posting back to the server and seeing if that helps.
Have you considered adding a property to your user control to return the text?
eg:
public class YourControl : UserControl
{
public string Text
{
get
{
return this.TextBox1.Text;
}
}
}
Usually, User Controls are used for encapsulation - you wrap up all the details of controls, behaviour etc in a UC so other code doesn't have to deal with it.
By referring to controls within the UC directly - by name or ID - you're breaking the model. Can I suggest you don't do this, instead if you need to get information from the UC you add a property, event or method to it that the container can call.
That way if you need to change the UC - control names, types, styles, or additional logic is used later - you only need to change that property/event/method in the UC, not in the (for example) 100 places it might be used in the code.
If you could let us know why you need this information or more specific details about the example, perhaps we can suggest some code to implement this.
So, what should I do ?
Just get the posted values manually.
Request.Form[yourcondeol.UniqueID]
by debugging this you can see all the posted data.
Request.Form
I use frame to load pages in my WPF project, is there a way to detect a page loading is the first or not? Something like "IsPostBack" in ASP.NET, I'm trying to find an equivalent to it in WPF.
I found IsPostBack is a property in System.Web.UI, should I include this namespace in my page?
I still have to use a static variable "bool SystemLoad = true", at the first load it is True and then I set it to False, so when the page is reloaded, it doesn't do as at the first load.
Thank you!
IsPostBack is not relevant to a WPF application, and since your WPF application window does not inherit 'Page', there is no way you can use IsPostBack variable from System.Web.UI.
The best you can do is to implement your custom logic as below.
private bool isLoaded;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
if (isLoaded)
return;
isLoaded = true;
}