Response.Redirect will Lost ViewState? - c#

Suppose, on Page_Load() of a page (WebForms) that I create this Control :
HtmlGenericControl optionBox = new HtmlGenericControl("div");
optionBox.Attributes["class"] = "class_1";
Than, a use will recall the page using a LinkButton. On the method called from this button, I change the class of my previous div :
protected void cmdCerca_Click(object sender, EventArgs e)
{
...
div.Attributes.Add("class", "class_2");
...
}
Well, if I watch on the rendered result, I'll see that the class of the div have been changed.
This means that, in the next call to this page (from this context, example calling cmdCerca_2_Click), that object will be recovered from the View, getting class_2, not class_1.
But, this doesnt happens if, at the end of cmdCerca_Click, I call the same page with Response.Redirect(). Seems that the View will be lost.
Why? And how can I fix it?
Hope the question is clear.

You need to add the controls in the page init event, rather than load, in order to get them into the control tree.
You must be recreating this control on every postback? In this case, your default class will be set every time.

Related

UWP StartBringIntoView not working in Page_Loaded

I have 3 BladeItems in another page. And I want to navigate from MainPage to that page and bring the requested BladeItem into view. But it is not working.
I first thought it was because that the page has not been loaded. So I put it into the Page_Loaded. However, it is still now working. Why is that?
private void Page_Loaded(object sender, RoutedEventArgs e)
{
TitleBarHelper.SetDarkTitleBar();
Window.Current.SetTitleBar(AppTitleBar);
UpdateTitleBarLayout(Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().TitleBar);
FullMediaControl.Update();
SetMusic(MediaHelper.CurrentMusic);
FullPlaylistControl.ScrollToMusic(MediaHelper.CurrentMusic);
if (MusicInfoRequestedWhenUnloaded)
{
MusicPropertyBladeItem.StartBringIntoView();
MusicInfoRequestedWhenUnloaded = false;
}
else if (LyricsRequestedWhenUnloaded)
{
LyricsBladeItem.StartBringIntoView();
LyricsRequestedWhenUnloaded = false;
}
}
Source Page Code is here. This page can be navigated using the "Show Lyrics" or "Music Info" item in the MenuFlyout at the right bottom more button.
And actually the FullPlaylistControl.ScrollToMusic in the code above is also not working. It just scrolls to a row in a ListView. I guess they might be the same reason.
This is the documentation for StartBringIntoView.
According to the instructions in the documentation, this method is only possible when the control is rendered on the visual tree, so you need to modify it when you call the method.
You want MusicPropertyBladeItem.StartBringIntoView() to work, you need to call it in the MusicPropertyBladeItem_Loaded event. For the same reason, you need to call ScrollToMusic when the FullPlaylistControl is loaded.
Page_Loaded only means that the page is loaded, but it doesn't mean that the controls have been rendered.
Best ragards.

Event wont work with user control

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.

How to access UserConrtorl's controls in this situation

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

What determines whether NavigationCommands.BrowseBack calls the page constructor?

I have two pages with similar logic in them. Load the page, click some buttons that will show/hide other buttons, continue to next page. When I hit the next page, if I click the back button I am returned to the previous page.
The difference is that one page (FirstPage) will have the constructor called when I click the back button, which has a call to reset the defaults. The other page (SecondPage) doesn't get the constructor called and I'm not sure why.
public FirstPage()
{
InitializeComponent();
DisplayStuff();
}
FirstPage has KeepAlive set to False.
public SecondPage(object arg1, object arg2)
{
InitializeComponent();
DisplayStuff(arg1, arg2);
}
This page also has KeepAlive set to False. These two pages don't inherit from anything and there is nothing that overrides any of the properties. The only difference I can see is the empty constructor, so I tried giving SecondPage an empty constructor and still no luck.
I'm relatively new to WPF (I work on it for an hour or two every 6 months), so what am I missing?
Here is the back button in case it is relevant.
<Button Command="{x:Static NavigationCommands.BrowseBack}" />
Edit: When I click the back button, SecondPage doesn't keep its state. It just loads an empty page because DisplayStuff hasn't been called yet.
Navigation Code:
NavigateTo(new SecondPage(arg1, arg2));
protected void NavigateTo(Page page)
{
NavigationService.Navigate(page);
}
I created a similar sample application and had similar behaviour. What I figured out that when you go back to a page the constructor is not called unless the page is the first page in the journal
Read this section in Navigation in WPF:
When the page Page is navigated back to, using the journal, the following steps take place:
The Page (the top journal entry on the back stack) is instantiated.
The Page is refreshed with the state that was stored with the journal entry for the Page.
The Page is navigated back to.
Good luck!
After reading Paul Stovell's article on WPF navigation, the way I want to display stuff is not going to work.
When navigating, if you click "Back", WPF can't possibly know what values to pass to the constructor; therefore it must keep the page alive. Here's the trace output:
Since WPF can't call the constructor, it won't. It'll just keep the page alive.
He goes on to mention that KeepAlive doesn't work if you're not navigating via URI, and Loaded and Unloaded are called each time, so I can just move all my logic there and I won't need the constructor to be called on the back navigation.

ASP.NET PopupControlExtender Problem

I am trying to create a popup which will be used to select a month/year for a textbox. I have kind of got it working but however when I try and read from the textbox when I Submit the form it returns an empty string. However visually on the page I can see the result in there when I click the Done button which can be seen in the screenshot.
http://i27.tinypic.com/2eduttx.png - is a screenshot of the popup
I have wrapped the whole textbox/popup inside a Web User Control
Here is the code of the control
Code Behind
ASP Page
and then read from the Textbox on the button click event with the following
((TextBox)puymcStartDate.FindControl("txtDate")).Text
Any suggestions of how to fix the problem?
You may need to read the form posted value rather than the value from the view state. I have the following methods in my code to handle this.
The below code just grabs the values in the request headers (on post back) and sets/updates the controls. The problem is that when using the ASP.NET Ajax controls, it doesn't register an update on the control, so the viewstate isn't modified (I think). Anyways, this works for me.
protected void btnDone_Click(object sender, EventArgs e)
{
LoadPostBackData();
// do your other stuff
}
// loads the values posted to the page via form postback to the actual controls
private void LoadPostBackData()
{
LoadPostBackDataItem(this.txtYear);
LoadPostBackDataItem(this.txtDate);
// put other items here if needed
}
// loads the values posted to the page via form postback to the actual controls
private void LoadPostBackDataItem(TextBox control)
{
string controlId = control.ClientID.Replace("_", "$");
string postedValue = Request.Params[controlId];
if (!string.IsNullOrEmpty(postedValue))
{
control.Text = postedValue;
}
else
{
control.Text = null; // string.Empty;
}
}

Categories