GWT: PushButton is not removing hovering if the click opens dialog - events

I've got a simple GWT PushButton which opens some dialog by click. The CSS styles are written in such a way that onHovering changes the appearance of the button.
The problem starts when I open some dialog by clicking on this button and close it. The onHovering styles remain!
This happens because in the CustomButtom which is the parent of PushButton there is a code which removes the hovering only when MouseOut event occurs. The problem is that if you open dialog with some dark semi-transparent screen it never occurs. The corresponding event is not issued and the button remains in onHovered state.
I try to fix this by firing this event manually. Fortunately, when the user closes that dialog I can catch onBlur event and try to do something in that moment. I try to create OnMouseOut event manually:
#Override
public void onBrowserEvent(Event event) {
int type = DOM.eventGetType(event);
if (type == Event.ONBLUR)
{
NativeEvent evt2 = Document.get().createMouseOutEvent(1, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, MyPushButton.this.getElement());
MyPushButton.this.getElement().dispatchEvent(evt2);
}
logger.info(event.getType());
super.onBrowserEvent(event);
}
... but for some reasons this code never sends an event. New MouseOut event is not logged in console and the onHovering styles are not changed. No exceptions are thrown.
Why I cannot fire the event?
Is there other ways to solve this issue?
GWT 2.5.1

This is a known issue: https://code.google.com/p/google-web-toolkit/issues/detail?id=2228
Actually, there are several issues with custom buttons, and you're encouraged to use Button (or SubmitButton or ResetButton) and CSS if possible; or maybe TextButton (or a custom cell-based ButtonBase subclass).
ToggleButton might be an exception as it has no real equivalent, other than a checkbox.

Finally I've made it working. Please notice Thomas Broyer's answer which is more broad.
#Override
/**
* In case onClick opens dialog, mouseOutEvent is not issued, thus preventing the button
* from removing the onHovering styles. Firing that event manually onBlur.
*/
public void onBrowserEvent(Event event)
{
if (DOM.eventGetType(event) == Event.ONBLUR)
{
NativeEvent mouseOutEvent = Document.get().createMouseOutEvent(1, 0, 0, 0, 0, false, false, false, false, NativeEvent.BUTTON_LEFT, getElement().getParentElement());
getElement().dispatchEvent(mouseOutEvent);
super.onBrowserEvent(Event.as(mouseOutEvent));
}
super.onBrowserEvent(event);
}

Related

Detect Back Arrow Press Of The NavigationPage in Xamarin Forms

Is there any way to detect the press of the back button of the Navigation Page in Xamarin forms?
You can override your navigation page "OnBackButtonPressed" method:
protected override bool OnBackButtonPressed()
{
Device.BeginInvokeOnMainThread(async () =>
{
if (await DisplayAlert("Exit?", "Are you sure you want to exit from this page?", "Yes", "No"))
{
base.OnBackButtonPressed();
await App.Navigation.PopAsync();
}
});
return true;
}
If you are using the shell, you can override the Shell's OnNavigating event:
void OnNavigating(object sender, ShellNavigatingEventArgs e)
{
// Cancel back navigation if data is unsaved
if (e.Source == ShellNavigationSource.Pop && !dataSaved)
{
e.Cancel();
}
}
Update:
OnBackButtonPressed event will get fired ONLY on Android when user press the Hardware back button.
Seems like you are more interested to implement when any page get disappeared you want to do something!
In that case:
You have the page's two methods -
protected override void OnAppearing()
{
base.OnAppearing();
Console.WriteLine("Hey, Im coming to your screen");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
Console.WriteLine("Hey, Im going from your screen");
}
You can override those 2 methods on any page to track when they appear and disappear.
Recent updates to Xamarin forms mean you can now do this in an application made with Shell Navigation for navigation back arrow on both platforms.
Use the Shell.SetBackButtonBehavior method, for example running this code in the constructor of your page object will allow the back navigation to take place only when the bound viewmodel is not busy:
Shell.SetBackButtonBehavior(this, new BackButtonBehavior
{
Command = new Command(async() =>
{
if (ViewModel.IsNotBusy)
{
await Shell.Current.Navigation.PopAsync();
}
})
});
In the body of the Command you can do whatever you need to do when you are intercepting the click of the back button.
Note that this will affect only the navigation back button, not the Android hardware back button - that will need handling separately as per the answers above. You could write a shared method called from both the back button pressed override and the command on shell back button behaviour places to share the logic.
You must override native navigationbar button behavior with custom renderer. OnBackButtonPressed triggers only physical device button. You can read good article how to achive this here

Can we override NAVIGATION BACK BUTTON press in Xamarin.forms?

Can we override navigation back button pressed in Xamarin.forms?
I have one navigation back button and the one save button in navigation bar.Save button hits the web service and saves in asynchronous way. While saving although i used progressing bar, navigation back button can be pressed and hence the app crashes due to index out of range exception on navigation stack.I tried using OnDisappearing() , did not work. I wanna cancel the PopUpAsync(),if the save is not done completely, but failed to achieve that. Is there any solution for this scenario? Can we override the navigation back button press event using any custom renderer ?
For controlling the back button to do what I want, I used this method in Xamarin:
public override bool OnKeyDown(Keycode HWkeyCode, KeyEvent e)
{
if (HWkeyCode == Keycode.Back)
{
StartActivity(typeof(FrontPageActivity));
return true;
}
return false;
}

Multiple leave events generated in Custom widget in Qt

I receive a Leave Event every time i move a pixel with my mouse over a customized QFrame i did. Why is this happening?.
I reimplemmented the leave and enter event as follows. As you can see i tried to comment the QFrame enterEvent, and restrict the repetition with a boolean, but it doesnt work because an enter and leave are continuously generated:
void enterEvent( QEvent *event ){
//QFrame::enterEvent(event);
if (!mouseHover_)
{
mouseHover_ = true;
emit hoverInSignal("");
}
}
void leaveEvent( QEvent *event ){
//QFrame::leaveEvent(event);
if (mouseHover_)
{
SmartUIWrapper::Instance()->addInfoMessage("out");
emit hoverOutSignal();
mouseHover_ = false;
}
}
Does it have something to be with the focus?
I discovered the reason.
I created a panel over this QFrame when i hovered.
When i moved the mouse, since the panel is positioned on the right bottom side of the cursor position, everytime i moved over the QFrame to the right or bottom, when i hovered this new panel i created, it looses the focus, so it gets closed again, then another hover comes, and then it´s created again... and again... everytime i hover the new panel.

Do code after OnNavigatedTo

I Have Code get IdUsers From Other Page
String IdUsers;
public Main_Wallets_Page()
{
InitializeComponent();
MessageBox.Show(IdUsers);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
String Id;
if (NavigationContext.QueryString.TryGetValue("IdUsers", out Id))
IdUsers = Id;
}
The MessageBox Alway be Null. I Want to MessageBox Show the "IdUsers" after OnNavigationTo (Do not put the MessageBox IN "OnNavigationTo").
How can i do it ?
You shouldn't use MessageBoxes in OnNavigatedTo because if the user does not press a button your app will crash since the framework thinks that navigation has failed. MessageBoxes in the constructor are equally as bad.
I can think of two options (I use #1 for these sorts of things):
Show the MessageBox in the Loaded event. But be careful it can be
fired more than once. In the constructor you might add the handler for the Loaded event and then in the handler you'd detach from the handler so that it is called only once.
Use Dispatcher.BeginInvoke around the MessageBox.Show call so that it does not block navigation. That might still block the Dispatcher thread. If you really wanted to go this route you could use ThreadPool.QueueUserWorkItem or a TPL Task.
I also have used OnLayoutUpdated in place of the Loaded event but I can't remember exactly why :) It seems like it might have been that the page hasn't yet displayed in Loaded and it has in the other event.
If this value was initialized, you can store it in application isolated storage. Then, when constructor is called, you can read it from there. In this case value of user ID will be initialized and MessageBox won't show you NULL.
DO NOT place MessageBox into OnNavigatedTo event.
Try to create an empty project with MainPage and Page2. Place button on MainPage to navigate to Page2. In Page2 place MessageBox in OnNavigatedTo event. Then everythig will work fine if you Start Debugging from VS. BUT if you deploy and run it you will see that when you navigate to Page2 you see MessageBox. Then don't do anything, just wait for about 15 sec. MessageBox will react as Canceled and APPLICATION WILL BE CRASHED! without any navigation to Page2 or MainPage. The same thing happens if you use Dispatcher.BeginInvoke around the MessageBox.Show.
I assume that OnNavigatedTo event has a timeout which works only when app is deployed. So you should run your MessageBox when Navigation is competed.
Everything works if you do
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
base.OnNavigatedTo(e);
var lcTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 200) };
lcTimer.Tick += (s2, e2) => {
(s2 as DispatcherTimer).Stop();
if (MessageBoxResult.OK == MessageBox.Show("Test, don't push", "", MessageBoxButton.OKCancel))
MessageBox.Show("OK");
else
MessageBox.Show("Cancel");
};
lcTimer.Start();
}
Note: If you have some code in OnNavigatedTo run above code at the end of OnNavigatedTo.
I liked what Austin Thompson(upvote) has adviced with ThreadPool.QueueUserWorkItem. But note that with this approach you need to place MessageBox inside the Dispatcher.BeginInvoke otherwise you will receive cross-thread exception. So the code is the following
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
base.OnNavigatedTo(e);
ThreadPool.QueueUserWorkItem((stateInfo) => {
Dispatcher.BeginInvoke(() => {
if (MessageBoxResult.OK == MessageBox.Show("Test don't push", "", MessageBoxButton.OKCancel))
MessageBox.Show("OK");
else
MessageBox.Show("Cancel");
});
});
}

How to handle back button in windows phone 7?

I have an application, the main page contains few functions. To explain in detail - I have save, color palette button in my main page. When any of these buttons are clicked, save pop up or color palette appears. How to handle back button of the device, when color palette or save pop up is opened. When back button is pressed at these scenario it should just make them invisible and stay on the main page. When nothing is being performed in the main page, then it should come out of the app. I tried to make their visibility collapsed on back button press. But it still is coming out of the application.
Please, guide me in this. Thanks in advance.
Override PhoneApplicationPage.OnBackKeyPress and then set CancelEventArgs.Cancel to true if you want to stop it from actually going back.
protected override void OnBackKeyPress(CancelEventArgs args)
{
if (PanelIsShowing)
{
HidePanel();
args.Cancel = true;
}
}
The back button behaves as is intended by Microsoft.
If you change its behavior you risk your application not being certified for the Marketplace.
If you want the back button to close the popups, turn the popups into pages so the back button navigates back to the main page..
You need to use
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (_popup.IsOpen)
{
_popup.IsOpen= false;
e.Cancel = true;
}
else
{
base.OnBackKeyPress(e);
}
}
That should do the trick.

Resources