I have a small problem with the context menu in C#/WPF. I will open it within a canvas, being attached to a rectangle. I have defined to open it with the space key, and it works fine. Now I want to change to the App-Key (aka Menu-Key, Application-Key, Contxt-Key, etc.). When I press the App-Key, the context menu appears, but as far as a release the key, it disappears. For test case, I also tried it with the key 'a', and it also works fine. Does anyone know why it disappears after releasing the button? Has this key some special behaviour?
Here is the code:
private void Rect_KeyDown(object sender, KeyEventArgs e) {
if (e.Key == Key.Space || e.Key == Key.A || e.Key == Key.Apps) {
e.Handled = true;
componentWithFocus.MainRectangle.ContextMenu.IsOpen = true;
}
}
For all who have the same problem, here is the solution:
The App-key should not be handled in the KeyDown event, is has to be handled in the KeyUp event.
BR,
Ossi
Related
I have a ListView with the following KeyDown event handler:
private void ListViewOnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.A)
{
Debug.WriteLine("KeyDown is A");
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
ListViewHelper.SelectAll((ListView)sender);
}
}
}
Yet the Debug.WriteLine is only ever invoked, i.e. I see KeyDown is A
in my output window, if I only press key A. If I press CTRL, the event is invoked, but e.Key shows as LeftCtrl (using a breakpoint), and hold CTRL down and press A, the Debug.WriteLine is not invoked. Using a breakpoint for debugging shows that while I am holding CTRL down, the handler keeps getting invoked for LeftCtrl only.
It's not working because the special combination is already handled by ListBox control.
Using PreviewKeyDown instead seems to work.
Pay attention by setting e.Handled = true;
I have simple win form application with the tab and combo box controls.
Combo box control has a style of "Simple".
Tab control has key down event.
When I press Enter key on the combo control it fires TWO key down events. If you change the combo style to any other, the key down event fires only one which it is something I expect.
Has anybody got any ideas why I am getting two key down events for single enter key press?
I have found similar issue on the Microsoft website, but that was related to .NET 1.0.
http://support.microsoft.com/kb/814970
It has probably something to do with the Enter key having pre-defined behavior for the Simple DropDown style.
You can try this work-around in the KeyDown event:
void comboBox1_KeyDown(object sender, KeyEventArgs e) {
e.SuppressKeyPress = true;
// do stuff
}
As you can guess, the KeyPress event won't fire now.
If you need to still process things in the KeyPress event, you can try this work-around:
void comboBox1_KeyPress(object sender, KeyPressEventArgs e) {
if (e.KeyChar == (char)Keys.Enter) {
e.Handled = true;
} else {
// do stuff
}
}
KeyPress from Combobox accepts just 'char' keys. For you purpose, please, use KeyDown event for combobox and e.Handled property.
Then your code will work and look like:
private void comboBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
comboBox2.KeyDown += new KeyEventHandler(comboBox2_SelectionChangeCommitted);
}
if (e.KeyCode != Keys.Enter)
{
e.Handled = false;
}
}
I'm working on a WPF application and I want to show/hide the menu when the users press ALT. The following piece of code works when I press the right alt key but not with the left one. When the menu is visible, clicking on right AlT key selects the first entry of my menu (which is well a main menu) instead of hiding it.
So I suppose that right ALT key has a default behaviour I have to override inside my event or somewhere else.
private void Window_KeyDown(Object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftAlt || e.Key == Key.RightAlt)
{
this.Show_HideMenu(sender, e);
}
}
i am new to WPF and in my application I want to maintain tab order through navigation keys(up/down arrow keys). so i iterate each control in grid on window load event and add delegate as following
private void Window_Loaded(object sender, RoutedEventArgs e)
{
foreach (UIElement element in gridChild.Children)
{
if (element.GetType() == typeof(TextBox))
{
TextBox tb1 = (TextBox)element;
tb1.PreviewKeyUp += TextBox_KeyDown;
}
else if (element.GetType() == typeof(PasswordBox))
{
PasswordBox tb1 = (PasswordBox)element;
tb1.PreviewKeyUp += TextBox_KeyDown;
}
else if (element.GetType() == typeof(Button))
{
Button tb1 = (Button)element;
tb1.PreviewKeyDown += TextBox_KeyDown;
}
}
}
and handler is following
private void TextBox_KeyDown(Object sender, KeyEventArgs e)
{
if (e.Key == Key.Down || (e.Key == Key.Enter && sender.GetType()!=typeof(Button)) )
{
e.Handled = true;
UIElement focusedElement = Keyboard.FocusedElement as UIElement;
if (focusedElement != null)
{
focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
}
else if (e.Key == Key.Up)
{
e.Handled = true;
UIElement focusedElement = Keyboard.FocusedElement as UIElement;
if (focusedElement != null)
{
focusedElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Previous));
}
}
}
its works well when i use navigation keys except one issue.Issue is that when Press up or down navigation keys on Button, then it skip one textbox which are next in tab order. I am not sure that what is wrong with above code. Please suggest what should I do for maintain tab order through navigation keys.
TabOrder is called so because focus is switched between controls with Tab key, not arrow keys. Your problems are caused by the fact that some controls may suppress arrow key events, such as TextBox in your case. But actually you can overcome this by adding event handler this way:
textBox.AddHandler(TextBox.KeyDownEvent,
new KeyEventHandler(TextBox_KeyDown),
handledEventsToo: true);
TextBox handles arrow keys down events because it uses those keys in text navigation. So the TextBox handles them (moves the caret) and sets e.Handled = true, which stops the event from bubbling up - that's why you don't catch this event.
But as I said, navigating focus with arrow keys may be frustrating to user. You can navigate with Tab key. WPF fully supports this approach and even sets the tab indexes itself, so that focus is moved from left to right and then from top to bottom of the window as user presses Tab key. You can prevent control from being focused with Tab key by setting its IsTabStop property to false. Also you can define your own tab order by setting elements' TabIndex property. No code at all is needed to make this approach work.
One more reason for you to prefer this approach to one that you implemented is that your code is hard to maintain. Look at your Window_Loaded handler. What if you add some controls to this window in future? You will have not to forget to add code there too. What if new window appears in your application? You will have to duplicate this block of code.
I am working in a WPF application, using C#.net
I want to know, is there any way to disable Backspace button on a particular xaml page.
I want to prevent user from using the Backspace button on this particular xaml page. Even if the user presses the Backspace button, no effect should take place.
Thanks
If you want to prevent backspace going back up the navigation history in a WPF Frame, including special "Back" hardware buttons, use:
NavigationCommands.BrowseBack.InputGestures.Clear();
NavigationCommands.BrowseForward.InputGestures.Clear();
You'll need to catch the onKeyDown event and set handled to true for backspace.
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Back)
{
e.Handled = true;
}
}
So I preferred the approach by sipwiz because I did not want to disable all keyboard shortcut (I still want to use ALT-Left etc just not the Backspace).
For me using a WPF NavigationWindow, overriding the OnKeyDown method did not work at all, the window still navigated back when I pressed the Backspace key. Overriding the OnPreviewKeyDown did seem to work to start with but then I ran into problems when I needed the Backspace key to work with textboxes.
So I took what I learned from the approach by Ed Andersen and I added the following code to my NavigationWindow constructor:
KeyGesture backKeyGesture = null;
foreach(var gesture in NavigationCommands.BrowseBack.InputGestures)
{
KeyGesture keyGesture = gesture as KeyGesture;
if((keyGesture != null) &&
(keyGesture.Key == Key.Back) &&
(keyGesture.Modifiers == ModifierKeys.None))
{
backKeyGesture = keyGesture;
}
}
if (backKeyGesture != null)
{
NavigationCommands.BrowseBack.InputGestures.Remove(backKeyGesture);
}