I am creating a Windows 8.1 app and after the user presses a button, a popup opens over most of the screen. There are several textboxes inside the popover.
I found this sample code from microsoft about how to detect the appearance of the on-screen keyboard.
I have also found the following SO posts and sites basically informing that there is no way to force the keyboard to close, and the correct thing to do is in fact programmatically focus a hidden element on the page or disable and then re-enable the textbox:
Forcing Windows 8 soft keyboard to hide
Windows 8 soft keyboard not hidden
Show/Hide Keyboard Automatically Widnows 8
How to Dismiss Touch Keyboard
So I followed the advice and created an invisible button. When the user taps the close button, it is supposed to give focus to that button and dismiss the keyboard. What happens is the textbox does lose focus, but the keyboard does not go away. If I cause the close button to give focus to the hidden button and close the popup (which is the desired effect), the keyboard does not go away until the view (that was previously under the popup) is tapped.
How can I make closing the popup cause the keyboard to dismiss?
EDIT: It appears that there might be a way to programmatically dismiss the keyboard because triggering the App Bar to open while the keyboardi s open automatically dismisses the keyboard.
When the textbox that shows the virtual keyboard was disabled it will dismiss the virtual keyboard. so the solution is set the textbox property IsEnabled to false and set it again to true so it can be use again.
TextBox.KeyDown += (s, a) => {
if (a.Key == VirtualKey.Enter) {
TextBox.IsEnabled = false;
TextBox.IsEnabled = true;
}
It was impossible to programmatically manage the touch-keyboard's appearance and disappearance. Unfortunately, changing the IsEnabled property didn't work for me.
The touch-keyboard appearance principle was known as Focus-driven, but I had walked out by setting the property IsTabStop=True on the UserControl explicitly. Besides, the TextBox won't activate the touch-keyboard if its IsTabStop=false.
In theory, I think the system searches the next potential TextBox,
so that if so it wasn't to close and re-open, with
touchable+inputable property. Maybe there were kind of bug that while releasing the Focus, current TextBox releases only his
"touchable" focus, and didn't finish to release the keyboard's
"inputable" focus, because that by default only the input-controls
have Tab-Stoppable property.
By the way, if we close the UserControl by a CustomControl's Close button, the IsTabStop=true will be needed on his parent.
PS: Solution tested only on Windows 8.1 Store Application.
Please check my answer to my own question:
https://stackoverflow.com/a/24252140/126537
Based on #Paul 's answer. Not very elegant, but works as charm.
In my app this works fine:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.KeyDown += Strona_KeyDown;
}
private void Strona_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter)
{
this.Focus(FocusState.Pointer);
}
}
In UWP Windows 10 simple disable/enable doesn't work anymore. But this works:
TextBox.IsEnabled = false;
var t = new DispatcherTimer();
t.Interval = new TimeSpan(0, 0, 1);
t.Tick += (a, b) =>
{
t.Stop();
TextBox.IsEnabled = true;
};
t.Start();
Find more elegant solution? Please share.
Related
We have some Forms that have no border / no toolbox (overlays)
Whenever the user clicks somewhere else in the underlaying window, the overlay-form is send to the background (regular non-modal-form behaviour)
Is there an Event for this, so the "overlay" could detect it's visibility change and close itself?
Maybe it can be handled within in resize / paint event, where the "invisibility" can be catched?
Background:
Typical "Select-Or-Create-New" UseCase. Clicking "plus" shows the tiny creation-form. Currently it's "topmost", so the user needs to hit "Escape" to get rid of it. (Else there would be a mess of "background-overlays", hence the question)
Would be more "userfriendly" if a click on something else closes that "tiny form":
You can use the Deactivate event of the form:
private void Form1_Deactivate(object sender, EventArgs e)
{
Visible = false;
}
When a UI element ( control ) is focused in a uwp app it can be triggered with Spacebar or the Enter keys, this is not limited to Desktop but also helps in Xbox so user can navigate through the controls and press on any focused control to active its Command.
Use case
But in My use case I want only Enter key to trigger that behaviour and Spacebar should not do anything at all no matter which control is pressed on the screen.
The reason to this requirement is that I am building a MediaPlayer application and no matter which control or button is focused within the app when I press Spacebar I want to simply link it to the Play/Pause Behaviour of my media element.
Not a Duplicate
This question is not a duplicate of : UWP - Don't fire Click event when pressing space (like in Movies & TV app)
Because in the question linked above, the answer was only relevant if any of the AppBarButtons were focused so they will not do anything on pressing Space but only will be invoked with Enter. But in my use case I want to apply the same behavior even outside the MediaPlayerElement control. I have a NavigationView and MediaPlayerElement resides in one of the pages, so I want this behavior to work even when a NavigationViewItem is focused or any other control which can be focused and invoked should only be invoked with Enter and not Space.
Is there a app level solution where I can apply this behaviour at the very root control and it descends to all of its children i.e : whole app?
What I have tried
I have tried with the already answered question (linked above) and that works fine for its limited scenario. And I have also tried setting AllowFocusOnInteraction=false to every app bar button and also other extra controls I have in the style of my CustomMediaTransportControls. But this is also limited to MediaPlayerElement only and also it prevents tab navigation which is not good for accessibility.
You can do this by handling the PreviewKeyDown event higher in the visual tree hierarchy, for example in the Page.
Subscribe to the event in the Page constructor:
public MainPage()
{
this.InitializeComponent();
this.PreviewKeyDown += MainPage_PreviewKeyDown;
}
Or in XAML:
<Page ... PreviewKeyDown="MainPage_PreviewKeyDown">
And in the event handler set the KeyRoutedEventArgs to handled when the Space key was pressed:
private void MainPage_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Space)
{
e.Handled = true;
}
}
This way the key down event will never reach any control below in the hierarchy because the PreviewKeyDown event propagates the tree before the event takes place.
There are many ways could approach, You could listen the current Content PreviewKeyDown event to detect Space press.
public Scenario1()
{
this.InitializeComponent();
Window.Current.Content.PreviewKeyDown += Content_PreviewKeyDown;
}
private void Content_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
e.Handled = e.Key == VirtualKey.Space ? true : false;
}
You could also GLOBAL HOTKEY for your uwp app that could be used when your app's window not in foreground. For more derail you could check this blog .
In my app,I just have a page with four text boxes, so when i click a text box soft keyboard appears, now when i want to move to next textbox then i have to tap outside the textbox to make the keyboard disappear and then click on another text box. I don't think it is user friendly, so i have two options,
1)To change the functionality of return button(to make it work as tab).
2)To reduce the frame size and so scrolling will be enabled.
How can I do the foretold two options in windows phone 7??
for the first option
Make return key of the input panel work like tab key.
make key down event of 1st textbox like this
private void txt1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
txt2.Focus();
}
}
similarly make this event for txt2 and txt3 and give focus accordingly and on on txt4 keydown event focus the main grid.
and about the 2nd way. Its a big problem in wp according to my knowledge.
For moving to next textbox #Amu 's answer will work perfect, and to dismiss the keyboard,
if (e.Key == System.Windows.Input.Key.Enter)
{
this.Focus();
}
That will take the focus away from your text box and will bring it to your screen.
And So keyboard will disappear!
I'm coding a windows form application running on a barcode scanner.
The plantform is .Net2.0CF/C#.
What i want is whenever user input wrong, the app will pop a messagebox and block the next input(actually,a scan action) until user click the OK on the screen.
But normally the user will continuously scan the next stuff as they didn't find anything went wrong, this will insert a Enter keydown so the messagebox will be closed, in one word, the messagebox does not stop the user.
How can i code this? Below is a very simple code snippet
private void tb_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.ToString() == "Return")
{
if(!ValidateInput(tb.Text))
MessageBox.Show("Error");
}
}
You can create your own window (Form) that displays the error message, but does not react on the enter key.
It should contain a button which the user can click (as you wrote), however you need to make sure the button does not have focus when the window is displayed. (Because if it had focus, pressing the return key will "click" the button.)
A simple way for doing this is adding another control which has TabStop set to true (e.g. a textbox, another button) and which has a lower TabIndex property than the button.
Additionally, maybe you might want to do a
System.Media.SystemSounds.Beep.Play();
when showing the window to draw the user's attention to the window.
I am relatively new to C#. I have a window with buttons. If the window is out of focus and I click on a button the first time, the first click grabs focus for the window and all subsequent clicks will perform their respective actions.
Is there a way to execute the event associated with the button instead of grabbing focus?
It sounds like you are describing how ToolStrips operate, which does not fire a click event unless the application has the focus.
A work around is to use your own ToolStrip and let the mouse activation give the control the focus, which in turn will then let the button fire it's click event:
public class ToolStripIgnoreFocus : ToolStrip {
private const int WM_MOUSEACTIVATE = 0x21;
protected override void WndProc(ref Message m) {
if (m.Msg == WM_MOUSEACTIVATE && this.CanFocus && !this.Focused)
this.Focus();
base.WndProc(ref m);
}
}
Rebuild your solution and you should see a ToolStripIgnoreFocus control available in your tool box. Try adding that to your form and then add your tool buttons accordingly.
This is how most Windows apps work - the app needs to have focus before it can receive click events.
As far as I know, you've described an inherent Windows behaviour and as such it could be impossible to do.
An alternative is to harness 'Always on top' style of windows app which is explained here:
How to make a window always stay on top in .Net?
This is normal windows behavior. Something that I don't think you can override (so that the click event fires, but doesn't bring your app to the foreground, and active state).
If you don't want to bring focus to the window, but still want to provide some 'interaction' with the window itself, try keyboard hooks or hotkey events. Examples:
http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvb/thread/2622427d-1e15-4f30-b01d-57b0ba054f5c
Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#
Low-level Keyhook
http://www.pinvoke.net/default.aspx/user32/RegisterHotKey.html