I'm trying to use text entry on maui to fire an event when completed. I have set the "Completed" event to a handler and it works correctly on windows. But on Android I have no joy, the event just isn't firing.
I realise there is a bug in Maui which is preventing this. But it looks like the problem was discovered in August? It's a fairly basic thing, well at least it appears to be on the face of things.
What is the best work around for this? The only thing I can think is by using the textchanged event instead of completed. This works correctly, but then i have to bodge it by doing this sort of thing:
if (entry1.Text.EndsWith("#"))
{
//Then string is complete, so need to fire correct event
System.Diagnostics.Debug.WriteLine("Complete String Detected");
}
This works and I can use it since I'm awaiting for input from a barcode scanner, so I can set the last terminating character to whatever I want. In this case I set it to a #. I can't figure out a way to detect the return key being pressed.
Thanks
Andrew
There is a similar issue on the github about the Entry.Completed and Entry.ReturnCommand not executed.
This comment shows the cause and the workaround about this problem.
detect the return key being pressed
In addition, I can't understand the problem. I have created a sample to test. The Entry.Completed event will call when I pressed the enter key. I don't kown the return key you mentioned is what. But you can use the IOnKeyListener for the android to detect any key being pressed.
Create a Listener class in the /Platform/Android:
public class MyKeyListener : Java.Lang.Object, IOnKeyListener
{
public bool OnKey(global::Android.Views.View v, [GeneratedEnum] Keycode keyCode, KeyEvent e)
{
var edittext = v as AppCompatEditText;
if (keyCode == Keycode.Enter && e.Action == KeyEventActions.Down )
//I used the Entry key as the example, you can use any other key you want to replace it.
{
edittext.ClearFocus();
edittext.SetBackgroundColor(Color.GreenYellow);
return true;
}
return false;
}
And in the page.xml:
<Entry Completed="Entry_Completed" x:Name="entry"/>
Set the listener to the entry by overriding the OnHandlerChanged() in the page.cs:
protected override void OnHandlerChanged()
{
base.OnHandlerChanged();
#if ANDROID
(entry.Handler.PlatformView as AndroidX.AppCompat.Widget.AppCompatEditText).SetOnKeyListener(new MauiAppTest.Platforms.Android.MyKeyListener());
#endif
}
You can also set the listener with the handler. Finally, you can try both the method above and the workaround in the issue on the github.
Related
I am working on a Vala GTK application that starts minimized by default and I want to bind a specific keyword shortcut to bring the minimized window to the front.
I am able to handle Keyboard events using Accelerators when the app is focus ed, but I am unable to intercept any key press from the system when the app is minimized.
How can I make the app listen to system keyboard events so I can detect the key press accordingly?
Thank you.
I took a look at the source for Ideogram to see how it registers Super-e as a hot-key. It looks to be basically the following, including first checking that a custom hot-key has not already been registered for the application.
// These constants are set at class level.
public const string SHORTCUT = "<Super>e";
public const string ID = "com.github.cassidyjames.ideogram";
// Set shortcut within activate method.
CustomShortcutSettings.init ();
bool has_shortcut = false;
foreach (var shortcut in CustomShortcutSettings.list_custom_shortcuts ()) {
if (shortcut.command == ID) {
has_shortcut = true;
return;
}
}
if (!has_shortcut) {
var shortcut = CustomShortcutSettings.create_shortcut ();
if (shortcut != null) {
CustomShortcutSettings.edit_shortcut (shortcut, SHORTCUT);
CustomShortcutSettings.edit_command (shortcut, ID);
}
}
It uses a CustomShortcutSettings class included in its source to handle the reading and writing to the system settings. The class originated in another application called Clipped.
It seems that if Find.Execute finds a result inside a ContentControl, it will cause the ContentControlOnEnter and ContentControlOnExit events to fire. It's particularly annoying because the exit event fires even if the selection is still in the content control, so any code which sets the states of buttons dependent upon a content control being active will appear to be in the incorrect state.
Given a document containing a single content control with the word "test", and the following code:
// In setup
Application.ActiveDocument.ContentControlOnEnter += ActiveDocument_ContentControlOnEnter;
private void ActiveDocument_ContentControlOnEnter(Word.ContentControl ContentControl)
{
var selRange = _Application.Selection.Range;
_logger.Debug(m => m("Selection: {0}-{1}", selRange.Start, selRange.End));
}
//Later in another method
var finder = _Application.ActiveDocument.Range().Find;
_logger.Debug("Find.Execute start");
finder.Execute("test);
_logger.Debug("Find.Execute end");
The following gets logged:
38137 [VSTA_Main] DEBUG - Find.Execute start
38141 [VSTA_Main] DEBUG - Selection: 1-5
38149 [VSTA_Main] DEBUG - Find.Execute end
We have a lot of code that handles ContentControlOnEnter and ContentControlOnExit events, and having the find operation cause them to be called is really causing problems!
Is there any way to use Find.Execute without having it trigger these events? Failing that, is there a good way to distinguish between the Find-triggered ones and the genuine user ones? I have tried using the time between the enter and exit events, but this is not reliable.
I had similar problems in Word, though it was about the Selection event. I tried many solutions, but only one helped. In your case, make a new field bool _skipEnterAndExitEvents and set it true before calling
finder.Execute("test) and false after calling. And in the enter and exit event handlers check this field, if the field is true then just skip. This solutions is not beautiful, looks like a hack, but other solutions are even uglier and don't really work.
I think I found a decent solution:
private bool _doIgnoreNextExit = false;
private void ActiveDocument_ContentControlOnEnter(Word.ContentControl ContentControl)
{
if (Application.Selection.Find.Found)
{
_logger.Debug("Ignoring CC enter event caused by Find operation");
_doIgnoreNextExit = true;
return;
}
// Do things
}
private void ActiveDocument_ContentControlOnExit(Word.ContentControl ContentControl)
{
if(_doIgnoreNextExit)
{
_logger.Debug("Ignoring fake exit");
_doIgnoreNextExit = false;
return;
}
// Do things
}
How do I clear the selection in my Eclipse RCP application?
Basically I would like to clear it on escape key down:
Display display = PlatformUI.createDisplay();
display.addFilter(SWT.KeyDown, new Listener() {
#Override
public void handleEvent(Event event) {
if (event.character == SWT.ESC) {
// if this is escape key, clear selection in the application
}
}
});
I thought I would be able to do something like PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().clearSelection()/setSelection(IStructuredSelection.EMPTY), but no go.
You need to look up the ISelectionProvider rather than the ISelectionService. That will provide you with a setSelection() method.
You can get the selction provider from the site:
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart().getSite().getSelectionProvider();
or
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getSite().getSelectionProvider();
Note that some of those return values could be null so add the appropriate checks.
You can't clear the selection provided by the selection service directly.
The selection the service returns is provided by a 'selection provider' (ISelectionProvider) for the current part.
You can get the selection provider from an IWorkbenchPart with IWorkbenchPart.getSite().getSelectionProvider().
ISelectionProvider has a setSelection method but it often does nothing or throws an exception so you may not be able to clear the selection.
In GWT I want to handle the click event, but only when user clicks on a day.
There's a valueChangeHandler but it fires when value change, so when I click two times at the same day it will fire once.
Other option is to use addHandler or addDomHandler in which I can add ClickHandler, but it fires always, no matter if I click a day or if I pass to other month.
Both options for me are not functional.
Any ideas how to do it?
Use the addvalueChangeHandler then after that set the value to something else. It's a hack but it works for me.
calendarWidget.addValueChangeHandler(new ValueChangeHandler<Date>() {
#Override
public void onValueChange(ValueChangeEvent<Date> event) {
calendarWidget.setValue(new Date(0));
}
}
Firstly , you should describe more details . I don't know exactly what you really want to do.
Here my advices.
(1). Use Cookies to save infomation of current used user and set expire day to 1day.
(2). Don't use addNewHandler. You should use global variable of one handler instance and initialize it to NULL . At first tought to this , you would be initialized it. That may creat only one time and you can check is it NULL . eg:
private CloseHandler handler;
.......
if (handler == null) {
handler = new CloseHandler<PopupPanel>() {
public void onClose(final CloseEvent<PopupPanel> event) {
........
}
};
}
(3). You can also use simple handler as you with and if fired event to it , save in a Map with current time and unique value (eg:sequence of login user.etc). When after hit it again , you retrive and match the times of both current and previous.
Be useful for you..
You can also add handler on your DateBox.getDatePicker() and your DateBox.getTextBox().
You can add another handlers as like this...
dateBox.addHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Window.alert("click");
}
}, ClickEvent.getType());
I have a wxTextCtrl-derived class that overrides OnDropFiles. However, dragging something over the control does nothing. (The cursor changes to the 'not allowed' cursor.) I tried DragAcceptFiles(true) but that only enabled the built-in drop handler. (Which just loads the file into the control.) How can I get my own handler to be invoked?
I also tried SetDropTarget, but that never got invoked either. It worked in a wxFrame, though.
Any ideas?
This is a stripped down version of what I have in one of my projects:
My form code
wxTextCtrl* textctrl = new wxTextCtrl(...);
textctrl->SetDropTarget(new DropFiles(textctrl));
The dropfiles class
class DropFiles: public wxFileDropTarget{
public:
DropFiles(wxTextCtrl *text): m_Text(text){}
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& arrFilenames);
private:
wxTextCtrl *m_Text;
};
bool DropFiles::OnDropFiles(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxArrayString& arrFilenames){
//Just take the first filename
m_Text->SetValue(arrFilenames.Item(0));
return true;
}
Hope that helps!
You have to handle the EVT_DROP_FILES event. Any other attempt to get notified will fail :(