I'm new to Xamarin, I'm using this example as a base for my on application.
I just noticed when I click back button the application get closed, I would like to avoid that.
do you have some hints and recommendations, maybe examples?
In your Content Page who will have to override the OnBackButtonPressed event and return true. You must return true because it signifies that the developer has handled the implementation of the back button click.
protected override bool OnBackButtonPressed()
{
return true;
}
Related
I am trying to prevent the back button being used by expiring the pages.
I have been trying to find an article on here to help and nothing works.
I have the function below that I call as the first thing on all my pages.
I call it in the Page_Load handler, is that the right place ?
I see no errors which is good, but my application just reacts as if there is no change. The back/forward buttons work and the pages display as normal and don't expire.
UPDATE:
As an added layer of security, what I want is the page to time out so if they use the "back" button they won't get the previous page. I have F5 covered so that doesn't repeat posts, and login is covered, if as I abandon the Session when they log out. But I want to stop the back button showing the previous page and force them to use the app navigation to get around my application.
I've known this functionality to fail penetration testing so I want to cover that off before I get to that point.
J
protected void Page_Load(object sender, EventArgs e)
{
MyWebApplication.SetPageStatus(Response);
....
}
internal static void SetPageStatus(System.Web.HttpResponse oResponse)
{
oResponse.ClearHeaders();
oResponse.ExpiresAbsolute = DateTime.Now;
oResponse.Expires = 0;
oResponse.CacheControl = "no-cache";
oResponse.Buffer = true;
oResponse.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
oResponse.Cache.SetExpires(DateTime.UtcNow);
oResponse.Cache.SetNoStore();
oResponse.Cache.SetRevalidation(System.Web.HttpCacheRevalidation.AllCaches);
}
I'm trying to host the .NET Windows Forms WebBrowser control on an MFC property page. To do this I'm using the CWinFormsControls class. This all works quite nicely, but since I'm on a property page there seems to be a problem with the property sheet consuming TAB and RETURN key presses to perform navigation or default key press behaviour, i.e. pressing the TAB key when the web browser control has focus does not move focus to the next control in the web page (the page has a username and password edit box plus a 'Submit' button and I'd like TAB to move between the boxes on the page and for RETURN to submit). End users aren't going to be satisfied with this mouse-only behaviour so I need the web browser to handle TAB and RETURN keys rather than the property sheet.
After some research - I'm a novice when it comes to MFC and WinForms - I think the problem may be that the property page is consuming these keys thanks to IsDialogMessage, which internally sends a WM_GETDLGCODE message to the web browser and the web browser only returning DLGC_WANTARROWS and DLGC_WANTCHARS, but crucially not returning DLGC_WANTTAB. So the web browser never sees the TAB key to handle it.
So I've tried many things, but the most promising approach appeared to be deriving my own control from WebBrowser and then overriding the WndProc function to explicitly handle WM_GETDLGCODE messages and request the TAB key:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x87 /* WM_GETDLGCODE */) {
m.Result = (IntPtr)0x83; // DLGC_WANTARROWS|DLGC_WANTTAB|DLGC_WANTCHARS
} else {
base.WndProc(ref m);
}
}
And this function does actually get called. However, the TAB keys still don't work. Attaching Spy++ to the web browser window reveals that despite appearing to handle WM_GETDLGCODE, the response isn't as expected:
Which I can't explain and obviously doesn't solve the problem.
So, am I going about this the right way? Is there a 'correct' solution to this problem?
I've tried using PreTranslateMessage to explicitly intercept TAB and RETURN key presses and somehow (SendKeys API) send them to the web browser control. This worked for TAB keys but caused a buffer overrun for the RETURN key. So no luck there and it felt like a nasty hack anyway.
This post is already getting long. If you need any more info then just ask. All help very gratefully appreciated.
After some research it seems that the better solution was to derive my own class from CPropertyPage and have that override PreTranslateMessage as:
BOOL CMyPage::PreTranslateMessage(MSG* pMsg)
{
return CDialog::PreTranslateMessage(pMsg);
}
i.e. make the property page behave as though it's a regular dialog. The reason for this is that property pages defer to the parent property sheet to handle key presses such as TAB and RETURN.
With this minor change my web browser control is getting all of the key presses and behaving as intended.
In case this helps someone, I was running my webBrowser in a modeless dialog. In the PretranslateMessage I had to do this for tabs, delete-keys and Enter-key to work correctly:
BOOL CMyDialog::PreTranslateMessage(::MSG *pMsg)
{
if (System::Windows::Interop::ComponentDispatcher::RaiseThreadMessage(*reinterpret_cast<System::Windows::Interop::MSG*>(pMsg)))
return TRUE;
else
return CVSimWnd::PreTranslateMessage(pMsg);
}
I have a Windows Phone 8 solution with the HTML5 template. My game is in a game.js file and I have a script in the webbrowser's body tag implementing my game. The game works as it should.
However, I have some problems with the hardware back button in Windows Phones. It closes my application, and I have tried overriding it, but I need to detect when the user is actually playing or is already in the menu screen, so I can let the app decide whether to go back to the menu or close the app.
I am thinking about using a global variable in my javascript/HTML5 game:
var IsPlaying = false
when the user clicks the start button on the main menu, IsPlaying becomes true.
When the user clicks the hardware back button, I want to evaluate the value of IsPlaying on my override method:
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
bool IsPlaying = //Get value from game
if (IsPlaying == true)
{
Browser.Navigate(new Uri(MainUri, UriKind.Relative)); //Restarts the game, thus bringing the user to the main menu
e.Cancel = true; //Cancels the default behavior.
}
}
So my question is, how can I retrieve the value of IsPlaying from the game?
Thanks
You can use the WebBrowser.InvokeScript method to execute a Javascript function from your C# code and retrieve the return value. So you can just write a function in your Javascript to return the value of the IsPlaying variable, then retrieve the value on the C# side by using InvokeScript.
I know that the dialog(showMessage) is a closed API and that you can not force a click event on Dialog with any web-based technologies such as jQuery or Javascript. The instance of the window within the browser is single threaded and locks the thread until the dialog receives an event. This I understand.
What I am trying to do is simulate a click event pragmatically for Test Case purposes. I am using the Telerik testing framework to run these Test Cases in C# .NET 4.5 environment.
So is it possible to simulate this click event? It is testing the behavior of one our buttons that when clicked the user must confirm they are leaving the page without saving changes.
Thanks to all in advance!
I am not familiar with Telerik's testing tools, but as far as i know the only way to "issue" such a click would be with a ui macro that automated mouse motions and actually clicked the screen at a particular location.
That said, you may be able to solve your problem by using a mocked method. Rather than directly calling window.prompt, instead define your own prompt function along the lines of:
debug = true; //remove or set to false when not testing
var myPrompt = function(){
if(debug){
return "Greetings, Program";
} else {
return prompt("Please enter your greeting:","Greeting");
}
}
You can naturally set this up for other types of message box, so long as you keep the type they return in mind.
I have an application for Windows 8 with a page (Frame) for displaying a list of items and a page for downloading & displaying the items details. I am also using MVVM Light for sending notifications.
Application use goes something like this:
Open Main Page
Navigate to List Page
Frame.Navigate(typeof(MyPage));
Choose Item
//Complete logic
Frame.GoBack();
Back on Main Page, I start downloading the file in the view model, I send ONE NotificationMessage saying BeginDownloadFile and after it is downloaded ONE NotificationMessage saying EndDownloadFile.
The first time I do steps 2,3, & 4 my NotificationReceived method is hit once, the second twice and so forth.
private async void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == Notifications.BeginDownloadFile)
{
FileDownloadPopup.IsOpen = true;
}
else if (msg.Notification == Notifications.EndDownloadFile)
{
FileDownloadPopup.IsOpen = false;
}
}
Additional information: I only have one FileDownloadPopup, yet each time, an additional popup is shown each time the NotificationMessageReceived method is called.
My only conclusion is that between navigating forwards and backwards in my app, there are multiple MainPages being created and never closed. This results in many NotificationsMessageReceived methods just waiting for a notification to come their way so they can show their popup.
I have two questions:
1. Does this sound like normal behaviour for a Windows 8 app?
2. How can I close all instances of the MainPage or return to the previous instance without creating a new instance?
Please let me know if I have missed something important out before marking my question down.
This sounds normal to me. The default navigation behaviour in Windows 8 is to create a new page instance each time you navigate to a new page, regardless of whether this is forward or back navigation.
Try setting the NavigatinCacheMode on MainPage to Required. See the MSDN documentation for details of how page caching works.
It sounds like you are registering eventhandlers in the page and then not removing them. Each time you navigate to the page again the handler is being added again in addition to the one you previously added. Try to add your event handler in OnNavigatedTo, and make sure you unregister it in OnNavigatedFrom.
protected override void OnNavigatedTo(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
MyEvent.OnDownloadRequest += MyLocalDOwnloadHandler; // add the handler
}
protected override void OnNavigatedFrom(Windows.UI.Xaml.Navigation.NavigationEventArgs e)
{
MyEvent.OnDownloadRequest -= MyLocalDOwnloadHandler; // remove the handler
}