I have a web page which is contained a Data Filter and a report.The Data Filter is a user control. The report is loaded inside the main page so totally i have two pages. one user control and one web page.
Now i am going to gather the data by clicking a button inside the user control then i can use it to filter the table, but it seems that during the post back it goes first to the Page_Load method of the main, not the user control so the report is constructed before filtering.The BtnPreviewReport_Click must be executed earlier than the page_Load.
What should i do ?
User control
protected void BtnPreviewReport_Click(object sender, EventArgs e)
{
Date = Year.Text + "/" + Month.Text + "/" + Day.Text;
}
Main Page
protected void Page_Load(object sender, EventArgs e)
{
string date = UserControls1.Date;
Response.Write(date);
}
Output : Nothing
I am not sure why the ButtonClick event should be run earlier than page load.
But here's a simple way to solve your question:
private bool isPageLoaded = false;
private bool isButtonClicked = false;
private void ButtonClick()
{
isButtonClicked = true;
doTheFirstThing();
if( isPageLoaded )
{
doTheSecondThing();
}
}
private void PageLoad()
{
isPageLoaded = true;
if( isButtonClicked )
{
doTheSecondThing();
}
// else let the button click handle the SecondThing()
}
Related
I have an aspx page. On pageLoad a call a method that loads a user control
protected void Page_Load(object sender, EventArgs e)
{
LoadUC();
}
This loads the user control onto the page (into a placeholder) passing a few generic values.
private void LoadUC()
{
ucTS ctrl = (ucTS)Page.LoadControl(_ucTSPath);
ctrl.ParentId = 0;
ctrl.addNew = false;
phFG.Controls.Add(ctrl);
}
The user control (which contains a repeater) loads the initial placeholder as well as another placeholder on the initial page:
protected void Page_Load(object sender, EventArgs e)
{
LoadItems();
}
private void LoadBOMItems()
{
List<Item> dtItem;
if (ParentId == 0)
{
if (ViewState["ItemFG"] == null)
{
dtItem = //Gets list of items
}
else
{
dtItem = (List<Item>)ViewState["ItemFG"];
}
ViewState["ItemFG"] = dtItem;
}
else
{
if (ViewState["Items" + ParentId] == null)
{
dtItem = //get list of items
}
else
{
dtItem = (List<Item>)ViewState["Items" + ParentId];
}
ViewState["Items" + ParentId] = dtItem;
}
if (dtItem.Count > 0)
rptTSItem.DataSource = dtItem;
rptTSItem.DataBind();
}
}
in the binding, I bind the repeater, but I am also adding more of the same user control.
The problem comes when I click add a new item to the repeater. The initial click, everything saves fine and a new row is added. The second click the user control is not found on the initial page and so the save method is not fires. The 3rd click, everything is fine, the 4th, the user control is not found. This keeps happening. Why is my usercontrol not always found? I have tried doing a postback check in multiple places, but that doesn't seem to work.
I am still not 100% sure why the event would fire properly every OTHER time as opposed to just the first time, but the solution was simply adding an ID to the user control.
private void LoadUC()
{
ucTS ctrl = (ucTS)Page.LoadControl(_ucTSPath);
ctrl.ParentId = 0;
ctrl.addNew = false;
ctrl.ID = "someID"
phFG.Controls.Add(ctrl);
}
and whenever I re-added the user control from within the user control, I pass the same ID.
Is there any way to update the ViewState from a page event (such as a button click) BEFORE the Load event of the page?
I understand that the event handlers only get called after the load events, but is there any way around this?
Due to the life-cycle of an ASP .net page. The only way to pass state to the server that can be accessed OnPageLoad is by using a HiddenField on the page which is updated on the client-side with Javascript.
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["val"] != null)
{
int s = Convert.ToInt32(ViewState["val"]);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (ViewState["val"] != null)
{
int s = Convert.ToInt32(ViewState["val"]);
s = s + 5;
ViewState["val"] = s;
}
else
{
ViewState["val"] = 6;
}
}
This is the code i tested on my machine
and on page load i am getting the updaetd value each time,
I have a web form which dynamically loads controls upon selection in combobox(devexpress). I have the following code on main form
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
if (Session["_active_control"] != null)//persist control on postbacks
{
Control cntrl = Session["_active_control"] as Control;
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
}
}
protected void cmb_control_SelectedIndexChanged(object sender, EventArgs e)
{
Control cntrl= Page.LoadControl("~/" + cmb_control.SelectedItem.Value);
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
Session["_active_control"] = cntrl;
}
also I have a user control having three Textboxes and a button having code
protected void btn_save_Click(object sender, EventArgs e)
{
lbl.Text = ASPxTextBox1.Text + "<br>" + ASPxTextBox2.Text + "<br>" + ASPxTextBox3.Text;
}
My problem is that the save button of user control is not firing if i load it dynamically (I have checked using breakpoints and also the code shown above. however it runs smoothly if I use it statically.(i.e. by dragging in design mode)
You are right that you have to persist the control across postbacks.
However the Page Load event is too late to add back your controls. Do this on the Init event of your page and you should be good. To receive a postback event, the control should be present when ProcessPostData(called before PreLoad) is called.
Also for textboxes you will want to receive the values entered by the user. This too happens on ProcessPostData, if you add you control after that, you will not receive the values entered by the user.
Refer: ASP.NET Page Life Cycle
hey i found the solution
instead on creating the controls in combobox_selectedindexchanged i put my control creation code on Pageload based in combobox.selectedindex i.e.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (cmb_control.SelectedItem != null)
{
Control cntrl = Page.LoadControl("~/" + cmb_control.SelectedItem.Value);
cntrl.ID = "_new_ctrl" + cmb_control.SelectedItem.Value;
pnl_main.Controls.Clear();
pnl_main.Controls.Add(cntrl);
}
}
see Button click event not firing within use control in ASP .Net
I have a WebBrowser element in a page, to which I would like to add a back and forward buttons, and have those buttons disabled when there's nothing to go back to and nothing to go forward to.
In Cocoa, the UIWebView has methods to easily check that: canGoBack and canGoForward, and you have goBack and goForward methods available (along with reload etc..)
Android has the exact same method names for achieving the same.
I see those methods are available in .Net 4 and 3.5 SP1.
I've found some references about using javascript commands in Silverlight but I find this very cumbersome, plus there's no way to detect if there's anything in the history (unless of course I manage this myself)
Surely, there's something a tad more advanced in Windows Phone ..
Here is how I ended up doing it.
This assumes you have set a backButton and forwardButton; the status of these buttons will be updated accordingly depending on where you are in the navigation stack.
webView is the WebBrowser object
List<Uri> HistoryStack;
int HistoryStack_Index;
bool fromHistory;
// Constructor
public HelpView()
{
InitializeComponent();
HistoryStack = new List<Uri>();
HistoryStack_Index = 0;
fromHistory = false;
webView.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(WebView_Navigated);
UpdateNavButtons();
}
private void backButton_Click(object sender, RoutedEventArgs e)
{
if (HistoryStack_Index > 1)
{
HistoryStack_Index--;
fromHistory = true;
webView.Navigate(HistoryStack[HistoryStack_Index-1]);
updateNavButtons();
}
}
private void forwardButton_Click(object sender, RoutedEventArgs e)
{
if (HistoryStack_Index < HistoryStack.Count)
{
HistoryStack_Index++;
fromHistory = true;
webView.Navigate(HistoryStack[HistoryStack_Index-1]);
UpdateNavButtons();
}
}
private void UpdateNavButtons()
{
this.backButton.IsEnabled = HistoryStack_Index > 1;
this.forwardButton.IsEnabled = HistoryStack_Index < HistoryStack.Count;
}
private void WebView_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (!fromHistory)
{
if (HistoryStack_Index < HistoryStack.Count)
{
HistoryStack.RemoveRange(HistoryStack_Index, HistoryStack.Count - HistoryStack_Index);
}
HistoryStack.Add(e.Uri);
HistoryStack_Index++;
UpdateNavButtons();
}
fromHistory = false;
}
I have a back button added to the applicationbar of a page in one of my apps which contains a webbrowser. I wanted the back button in the app bar to take the web page navigation backward, and wanted the hardware back button to go to the previous xaml page. This way, the user doesn't have to use the hardware back button to navigate backward through all the visited web pages in the webbrowser in order to go back to the prior xaml page. Here is how I did it, and you could easily set up a forward stack and when the user clicks the back (appbar) button, the page pops from that stack and is pushed to the forward stack.
private void NavigateWeb()
{
if (!loaded)
{
NavigationStack.Clear();
try
{
Web.Source = new Uri("http://m.weightwatchers.com/");
loaded = true;
}
catch (Exception ex)
{
MessageBox.Show("Unable to navigate to page.\n" + ex.Message,
"Error", MessageBoxButton.OK);
}
}
}
void Web_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
NavigationStack.Push(e.Uri);
}
void btnBack_Click(object sender, EventArgs e)
{
if (NavigationStack.Count > 2)
{
// get rid of the topmost item...
NavigationStack.Pop();
// now navigate to the next topmost item
// note that this is another Pop - as when the navigate occurs a Push() will happen
Web.Navigate(NavigationStack.Pop());
}
}
The reason I check for NavigationStack.Count > 2 is that the particular webpage that I'm showing in the webbrowser always starts with a "click here to continue" link on the first page, and there is no reason to go back to there. That's the downfall of showing other people's sites in your webbrowser - you don't have control over what is shown.
In regards to the javascript solution it is doing something like this:
private void backButton_Click(object sender, RoutedEventArgs e)
{
try
{
webView.InvokeScript("eval", "history.go(-1);");
}
catch
{
// Eat error
}
}
private void forwardButton_Click(object sender, RoutedEventArgs e)
{
try
{
webView.InvokeScript("eval", "history.go(1);");
}
catch
{
// Eat error
}
}
with having the IsScriptingEnabled set to true for the WebBrowser element.
However, this always generates an exception with error 80020006. I read various posts about how the DOCTYPE could have been the culprit, the system caching or IsScriptEnabled being set after the content was loaded... It just never worked...
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) // If page loads for first time
{
Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString()); // Assign the Session["update"] with unique value
//=============== Page load code =========================
//============== End of Page load code ===================
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Session["update"].ToString() == ViewState["update"].ToString()) // If page not Refreshed
{
//=============== On click event code =========================
Label1.Text = TextBox1.Text;
//lblDisplayAddedName.Text = txtName.Text;
//=============== End of On click event code ==================
// After the event/ method, again update the session
Session["update"] = Server.UrlEncode(System.DateTime.Now.ToString());
}
else // If Page Refreshed
{
// Do nothing
}
}
protected override void OnPreRender(EventArgs e)
{
ViewState["update"] = Session["update"];
}
}
This is not working for high resolution gradient background.
Consider wrapping your button and the label in an updatepanel control, which uses AJAX to refresh their contents.
The rest of the page will not be reloaded and the action will not affect the browser navigation.
See this page on how an updatepanel control works.
Since you are handling the button click event in server side there has to be a postback to handle it.
If you do not want a post back to happen change the event handling to "client click"
//Heinzi code worked for me just made a small change in OnPreRender event, assign the ViewsState value when its not post back
protected override void OnPreRender(EventArgs e)
{
if (!IsPostBack)
{
ViewState["update"] = Session["update"];
}
}