I have made a game where the character moves using wasd. In the same form on the right side there are some buttons and other controls but when they are pressed the character wont respond on keydown events. How can I solve that?
Explanation:
This is because Windows has the concept of "Focus". (Read up on it.) Key events are only sent to the control which has focus, and at any given time only one control within the form has focus. You probably have some control which renders your character, and you have placed your key event handlers on that control. When the form first pops up, you give focus to the rendering control, so everything is fine. But as soon as you click on another control, that control takes focus, so your rendering control does not have focus anymore.
Solution:
After a button gets clicked, use SetFocus() to return focus to your rendering control.
Related
I am making a game, and to open up and close the store, you press S. While in the store, you have six different choices to buy from, but they are all buttons.
However, once you buy something, the focus is no longer on the form, but on the button, and the key down event is part of the form, therefore, because the focus gets switched from the form to the button, the key down event no longer works, and disables you from closing the store and continuing on with the game.
My question is how to set the focus back to a form once a button is press? I started out with visual basic, and the code would be something along the lines of form1.setfocus, but its totally different in c#.
I have tried Activating the form, .focus, a lot, and nothing seems to be setting the focus back to the form. Help would be greatly appreciated.
Form1.focus();
But I think, to get keyboard events on Form itself, you need KeyPreview set to true for the Form so that Form gets Keys first and then other controls.
Try:
form.Focus();
MSDN:
The Focus method returns true if the control successfully received input focus. The control can have the input focus while not displaying any visual cues of having the focus. This behavior is primarily observed by the nonselectable controls listed below, or any controls derived from them.
Tell me more
You can add the key down event to the buttons too.
The WinRT TextBox control has a delete button that shows up when the control has focus and there is text in it.
When the control loses focus by tapping outside of it or tabbing outside of it, the delete button disappears.
When the control loses focus by tapping in a different app (two apps are up in splitscreen), the delete button doesn't disappear.
Is there a way to detect the different lost focus events? Nothing from the sender or RoutedEventArgs is different in the two cases where the control loses focus.
You can handle Window.Activated to check if the whole app has lost focus:
This event occurs when a Window has been activated or deactivated by
the system. An app can determine what the status of the Window
activation is by checking the
WindowActivatedEventArgs.WindowActivationState property. A Window
could be visible on screen but not be active (for example, in snapped
apps). Additionally, if any other parts of the system takes focus away
from the window, this event will occur. This could happen as a result
of user interaction or code, and the WindowActivationState will
indicate which action has taken place.
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.window.activated.aspx
The default behaviour of pressing back button when a textbox is on focus is that the virtual keyboard closes and the textbox loses focus. And the user press back key again, the window goes back to previous window.
However, I want the change this behavior. I want the window to go back to previous window directly when the back key is pressed, ignoring whether the textbox is on focus or not.
I tried the following methods,
Use HardwareButtons.BackPressed event, doesn't work (maybe it only works for Direct3D, I am not sure). The event isn't fired during back button pressed.
Use Textbox_onKeyUp, doesn't work. The event isn't fired during back button is up.
Use override void OnBackKeyPress, doesn't work. It does fire as expected during other cases, but during the situation when the textbox is from on focus to losing focus (the keyboard closes), the event isn't fired.
Use Textbox_OnLoseFocus, works fine but need a lot of condition checks because some times losing focus doesn't mean that I want to go back to previous page.
Please help. Thanks.
Finally I didn't change the behaviour, made a different design. But I still think that in that case, the Nokia's behaviour is most user-friendly.
I have a Form which covers the entire screen. I have a textbox on it which is normally hidden but appears when a user clicks, drags mouse and then leaves. After that user can enter any value in the text box. Once entered, ideally user should be able to click outside of textbox and then the normal service should resume.
By normal service I mean that form should start getting all the events. What I have done so far is that on TextBox's KeyDown event; when Escape key is pressed, I have set the focus to the main form like this:
this.Focus(); //where this is mainform.
But this doesn't seem to work since Textbox still keeps receiving all the keys. I have a KeyDown event handler both for Form and Textbox and I have checked that all the KeyDown events pass on to the TextBox. I have a TextBox Leave event Handler as well which never gets called.
This TextBox is the only control on the form and the main form is used for drawing shapes (if that matters).
So, how can I make this TextBox lose focus when user clicks outside of it.
if it works like in VB, for what I remember, try to set the form property KeyPreview to false so all keys will be passed only to the focused control on the form.
If you set your form KeyPreview property to true, your form has first chance to handle any keystrokes that you make. If it is something you want to handle i.e. escape as in your comment above, handle it in your form's KeyDownEvent and mark it as handled so your textbox will not see it.
From above Msdn Page:
When this property is set to true, the form will receive all KeyPress, KeyDown, and KeyUp events. After the form's event handlers have completed processing the keystroke, the keystroke is then assigned to the control with focus.
I guess back in '11 this didn't work, but now
this.ActiveControl = null;
works fine. However if you intend to use Tab to cycle controls, focusing a label with suitable TabIndex is the way.
I'm trying to implement code-completion popup window in my project. The window is derived from Form. It contains two controls: custom list derived from UserControl (it shows completion possibilities with icons) and a VScrollBar.
When the popup appears, it doesn't steal focus from the editor (form's ShowWithoutActivation is overriden to return true) and the editor sends certain keystrokes to the popup so the user can interact with it using keyboard. So far it works like a charm.
The problem is, I want to allow the user to use mouse as well. But, when the user clicks into the popup window, its form activates and steals focus from the editor. I can react to this by giving the focus back to the editor, I have even set up a Timer to do this regularly, but apart from being a poor solution, the title bar of the editor always flickers when this happens (when the popup is clicked).
Is there any way to interact with the popup form (using mouse) that doesn't make the form activate?
The ShowWithoutActivation's documentation reads: "If your non-activated window needs to use UI controls, you should consider using the ToolStrip controls, such as ToolStripDropDown. These controls are windowless, and will not cause a window to activate when they are selected." This seems exactly like the thing I need, but I want to use a custom control and a scroll bar.
The same problem would be with a tooltip that shows these two arrows to switch method overloads (known from VS) - the whole form would use no controls at all (only render the text and the arrows), but when clicked, it should not activate. The problem could be summarized up to "How to create a form that would never activate, but allow the user to interact with certail controls inside?".
Thanks.
Just override the onFocus event...
public partial class myListBox:ListBox
{
protected override void OnGotFocus(EventArgs e)
{
}
}
The issue is that you're using a Form for this rather than building some custom control that doesn't run in its' own UI thread like a Form does.
The flashing and highlighting is handled by windows whenever a Form activates/focuses. The only thing I cay think of is to make your Form borderless and create/draw/handle your own title bar that doesn't flash when focused.
OK, I may have found a solution. The key seems to be WM_MOUSEACTIVATE message, which the popup form must intercept and respond with MA_NOACTIVATE. But there's a catch - the control derived from UserControl still grabs focus when clicked (the scrollbar luckily doesn't anymore). The problem seems to be in the UserControl.OnMouseDown method, which internally puts focus on the control. There are some ways to fix this:
derive the control from Control instead of UserControl
override the OnMouseDown method and not call base.OnMouseDown there
make the control's CanFocus property return false, but this seems not possible, because that means to make the control either not visible or not enabled, which is both undesirable
The last case when the popup form steals focus seems to be when its resizing (using mouse) ends. But it is safe here to call Owner.Activate() as a result to Activated event...