I am new in WP8 development and I am making an app that has a WebBrowserControl to access to my website. I want to save the state of WebBrowser when app comes to background, but I can't do this (i.e. when user wants to re-open application WebBrowser will load last page seen).
My code, based in this, is the following:
WebBrowser properties: Base and Source are empty.
App.xaml.cs:
public partial class App : Application
{
//Url to store current address to maintain state when application is in background
public Uri Url { get; set; }
//Boolean to get if phone has been previously in background
public Boolean firstRun = true;
private void Application_Activated(object sender, ActivatedEventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
Uri currentUrl;
if (settings.TryGetValue("Url", out currentUrl))
Url = (Uri)settings["Url"];
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings["Url"] = Url;
firstRun = false;
settings.Save();
}
MainPage.xaml.cs:
public partial class MainPage : PhoneApplicationPage
{
Uri baseUrl = new Uri("http://my_url");
// Constructor
public MainPage()
{
InitializeComponent();
webBrowser.Navigated += new EventHandler<NavigationEventArgs>(WebBrowserNavigation);
App app = Application.Current as App;
if (app.firstRun)
{
webBrowser.Navigate(baseUrl);
}
}
async void WebBrowserNavigation(Object sender, NavigationEventArgs navArgs)
{
string url = navArgs.Uri.ToString();
App app = Application.Current as App;
app.Url = navArgs.Uri;
}
I think you're confusing bring it to the foreground and relaunching. To bring it back to the foreground press the back button after pressing the windows button. You will see that your application is exactly where you left it. If you re-launch the program by pressing a title or using the start menu, it will start a new instance of it... thus showing your base URL.
So basically FirstRun does not matter in your program. When you launch your program you should grab the last URL by doing this
private void Application_Launching(object sender, LaunchingEventArgs e)
{
// this.FirstRun = true; // doesn't matter
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
Uri currentUrl;
if (settings.TryGetValue("Url", out currentUrl))
{
Url = (Uri)settings["Url"]; // got the last url
}
else
{
Url = new Uri(#"http://www.msn.com"); // last url not defined, set it to default base
}
}
Save your Last URL in both events
// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings["Url"] = Url;
settings.Save();
}
// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings["Url"] = Url;
settings.Save();
}
And when your MainPage gets loaded navigate to the saved URL
public MainPage()
{
InitializeComponent();
App myApp = Application.Current as App;
webBrowser.Navigated += new EventHandler<NavigationEventArgs>(WebBrowserNavigation);
webBrowser.Navigate(myApp.Url);
}
Doing it this way, it always saves your state and it doesn't matter if you bring it to the foreground or launch it again from the title or start menu. You can say that you properly tomestoned your WebBrowser URL at this point.
Related
Currently i have a winform where i need to open report in WebBrowser Control. I am using impersonation method to view as different user. But somehow the WebBrowser will pop up a windows security authentication for me to enter my credential. When i input the credential as someone that has the right to view the report (not my credential) it will just show a blank page. Not even a message that says:
The permissions granted to user 'Domain\first.last' are insufficient for performing this operation. (rsAccessDenied)
The First Page:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (new ImpersonateUser("TestUsername", Environment.UserDomainName, "TestPassword"))
{
Form2 reportForm = new Form2();
reportForm.Text = "Test";
reportForm.GetReportUrl("http://url/");
reportForm.ShowDialog();
}
}
}
The Second Page:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
label1.Text = Environment.UserName;
}
private void Form2_Load(object sender, EventArgs e)
{
webBrowser1.Refresh();
}
public void GetReportUrl(string repUrl)
{
webBrowser1.Url = new Uri(repUrl);
}
}
Can someone explains to me why is this happening? And how i can fix this? Thank you.
But i didn't get why you have to do impersonation to launch a form, from the above code you are not doing any by doing impersonation.
if you are facing the problem in launching a application under user profile then the below link will be helpful.
WTSQueryUserToken returning FALSE
My WebBrowser object will not Navigate() to the link I give it.
The object remains empty when I run it.
When I put the url into the url property though, it successfully loads the link.
namespace Program
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
webbMain.Navigate("https://twitter.com/login");
}
}
}
You can try the following:
You can try the following in Page_Load:
WebBrowser wbbMain= new WebBrowser();
wbbMain.AllowNavigation = true;
wbbMain.Navigate("http://www.stackoverflow.com");
Also, you can try to provide override for DocumentCompleted event.
If nothing works, then see if Internet explorer is isntalled. If its not installed then web brower may not work.
I have multiple windows. My LoginWindow has to validate the user. If this window is canceled the complete application should shutdown. If the user enter the correct login, the LoginWindow should be closed and the MainWindow open.
Question:
My problem is at the yellow diamond: How to determine the state of the login process?
That is my current state.
public partial class App : Application
{
[STAThread]
public static void Main()
{
var app = new App();
var login = new LoginWindow();
if (app.Run(login) == 1) //<-- Problem: How to get the state from login?
{
var mainapp = new MainWindow();
app.Run(mainapp);
}
}
}
I tried to get an exitcode from the loginwindow by using Application.Current.Shutdown(1); but it cause an InvalidOperationException on app.Run(mainapp);, because Shutdown closes the complete application.
Environment.Exit() terminates this process and gives the underlying operating system the specified exit code.
But a window has no "return value". You could handle the Closed event for the LoginWindow and check whether a property of thw window itself, or its view model, has been set. Please refer to the following example.
public class Program
{
private static readonly App app = new App() { ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown };
[STAThread]
public static void Main()
{
LoginWindow login = new LoginWindow();
login.Closed += Login_Closed;
app.Run(login);
}
private static void Login_Closed(object sender, EventArgs e)
{
LoginWindow loginWindow = (LoginWindow)sender;
loginWindow.Closed -= Login_Closed;
if (loginWindow.LoggedIn)
{
MainWindow mainWindow = new MainWindow();
app.MainWindow = mainWindow;
app.ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose;
mainWindow.Show();
}
}
}
public partial class LoginWindow : Window
{
public LoginWindow()
{
InitializeComponent();
}
public bool LoggedIn { get; private set; }
private void Login_Click(object sender, RoutedEventArgs e)
{
//if (authenticate)...
LoggedIn = true;
Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
LoggedIn = false;
Close();
}
}
I found a smart solution. A Window with return value is called "Dialog".
App.xaml.cs
[STAThread]
public static void Main()
{
var app = new App() { ShutdownMode = ShutdownMode.OnExplicitShutdown };
if (new LoginWindow().ShowDialog() ?? false == true)
app.Run(new MainWindow());
}
LoginWindow.xaml.cs
private void OnLoginClick(object, EventArgs)
{
this.DialogResult = true;
}
private void OnCancelClick(object, EventArgs)
{
this.DialogResult = false;
}
To exit the whole application use "Application.exit();" and to open the main windows create object of that form then use "object.Show()" and "this .hide()" to hide the login form.
For example:
Assume the query i.e. stored procedure like:
Create procedure dbo.usercheck
(
#userid nvarchar,
#password nvarchar
)
As
Select username from login table
C# code:
SqlCommand com=new
SqlCommand("dbo.usercheck","connection");
If(com.executescalar()==null)
{
Application.exit();
}
else
{
Mainform f=new Mainform();
f.show();
this.hide();
}
You can write the "Application.exit();" statement in cancel button's click event to close the application whenever you want to close whole application when clicked on cancel button of login form.
When user enters wrong user id or password then you can show the error message instead exit the application.
I would use the following code:
Declare a bool variable to check if user closed the app or if it was closed from your code:
bool userClosedForm = false;
Then inside the Close button add this line, after the code you already had there:
private void btnClose_Click(object sender, EventArgs e)
{
//your code
userClosedForm = true;
}
Add a Form_Closed event where you check the value of the variable:
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (userClosedForm == true) Application.Exit();
else
{
//your code to open the next form if the user logged in and you closed the form from code
}
}
Hope this helps ^^
I want to searialise and save the IsolatedStorageSettings.SiteSettings on all the tabs when the browser is closed. But I get the Exit event only on the tab that is presently active.
How is it possible that all the tab data is saved
public partial class App
{
private siteSettings = IsolatedStorageSettings.SiteSettings;
public App()
{
InitializeComponent();
this.Exit += App_Exit;
}
private static void App_Exit(object sender, EventArgs e)
{
App app = (App)sender;
app.Exit -= App_Exit;
siteSettings.Save();
}
}
From my Form1 I initialize a class scraper. In the scraper class is an function login. The idea is that that class log's the user in on an website, and returned the web browser so that an logged in webbrowser control is available in Form1.
I've got this code so far: Form1
private void button1_Click(object sender, EventArgs e)
{
Scraper scraper = new Scraper(this);
scraper.login(conf._webLogin);
}
public void updateLoginWeb(WebBrowser web)
{
webBrowser1 = web;
MessageBox.Show("DONE");
}
The conf class:
public WebBrowser _webLogin = new WebBrowser();
The scraper class:
private Form1 parent;
private WebBrowser _web_Login = new WebBrowser();
public Scraper()
{
}
public Scraper(Form1 parent)
: this()
{
this.parent = parent;
}
public void login(WebBrowser web)
{
_web_Login = web;
_web_Login.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(login_DocumentCompleted);
_web_Login.Navigate("http://www.google.com/");
}
private void login_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//This line is so you only do the event once
if (e.Url != _web_Login.Url)
return;
parent.updateLoginWeb(_web_Login);
}
I use google as test, but nothing works (not even an another site).
The problem is that the webbrowser in the Form isn't updated. It's still an white screen.
What do you guys think of this? Do you know what the problem is or do you guys know an better way to handle this?
I think your problem is that you can not simply assign the webBrowser variable:
webBrowser1 = web;
You are changing the Form1.webBrower1 variable, but the Forms.Controls collection is still pointing to the original webBrowser control.
Can't you just pass Form1.webBrower1 to scraper.login function?:
private void button1_Click(object sender, EventArgs e)
{
Scraper scraper = new Scraper(this);
scraper.login(webBrowser1);
}
public void updateLoginWeb(WebBrowser web)
{
//webBrowser1 = web; // you don't need this anymore
MessageBox.Show("DONE");
}
If you really need to replace your control you can do something like:
public void updateLoginWeb(WebBrowser web)
{
Controls.Remove(webBrowser1);
Controls.Add(web);
webBrowser1 = web; // you don't need this anymore
MessageBox.Show("DONE");
}
But you will probably to set the new webbrowser layout properties manually.