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);
}
Related
I have a tool that only runs when the Ctrl key is pressed. I'm listening for it in this function in my view model.
private ImageManipulationTool WheelTool
{
get
{
bool IsControlPressed = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);
if (CurrentTool == loupeTool && IsControlPressed)
{
return loupeRadiusTool;
}
else if (CurrentTool == zoomTool || IsControlPressed)
{
return zoomTool;
}
// default wheel tool
return sliceTool;
}
}
But this isn't really MVVM-correct. The keyboard is basically an element of the view. And now my code isn't testable because, as a view model, I'm pretty sure that even simulating key events won't work because there's no target.
So I know the answer is input bindings on the window. However, the solutions I've seen don't seem to cover my cases:
I'm using just the control key, and it doesn't seem like you're allowed to bind to a modifier key without a "normal" key
I need to know if the key is pressed, but the keybindings seem to only listen for key down.
Less important, I'd like the key binding to be in the file for my UserControl rather than all the way up in the MainWindow. But it seems like Window.InputBindings is where these need to go.
How can I get all of this to work?
One possiblity is to use the events PreviewKeyDown and PreviewKeyUp in your UserControl. From there you can check the keystates and set a property in your viewmodel.
private void UserControl_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (sender == null)
return;
if(sender is YourUserControl uc && uc.DataContext is YourViewModel vm)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
vm.IsCtrlKeyPressed = true;
}
}
Implement the PreviewKeyUp event and you are ready to use the IsCtrlKeyPressed-Property without breaking the MVVM pattern.
Edit: Seems like you don't need to check e.KeyStates since you are on the KeyDown/Up Event anyways. But you can use Keyboard.IsKeyDown if you want to be sure.
Users of my application have a second keyboard with special function keys. Unfortunately, the keys are mapped to buttons such as F, G, F1 and so on. I would like to handle PreviewKeyDown and prevent any keys from these keyboards having an effect in normal controls such as TextBoxes.
In WPF, is there any way of determining which keyboard raised the event?
No, it is not possible directly in WPF.
using System.Windows.Input you could be able to achieve this by capturing the event that is fired in your code behind. Sample code below shows how this can be done in Textbox.
private void SampleTextbox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete) // delete key is pressed
{
e.Handled = true; // Ignore key press
}
}
I have a datagrid in a Silverlight application. Clicking on the first row, and then pressing the Enter key causes the selection to move to the next row. I do not want this behavior - the Enter key is used for totally different purposes on this screen.
I realize that this is part of the editing framework, but I need a way to turn it off. I tried setting IsReadOnly to True (even though the control isn't technically read-only) and that didn't have any effect.
I attached to the datagrid KeyDown event but it's not called when the Enter key is pressed. It works fine for other keys.
I'm stumped. Thanks for your help.
Yeah, that's annoying.
As far as I know, the only option is to create your own control that inherits from DataGrid, and do what is needed before passing the event on to the base.
public class NewDataGrid : DataGrid
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
//do what is needed here
e.Handled = true;
}
base.OnKeyDown(e);
}
}
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
I have combobox in WPF application that when the user clicks on it, it selects all the text. How can I change the behavior of this to when the user clicks it just set the typing cursor like a normal textbox?
Try
<ComboBox IsEditable="True" />
According to Reflector, the ComboBox code contains this:
private static void OnGotFocus(object sender, RoutedEventArgs e)
{
ComboBox box = (ComboBox) sender;
if ((!e.Handled && box.IsEditable) && (box.EditableTextBoxSite != null))
{
if (e.OriginalSource == box)
{
box.EditableTextBoxSite.Focus();
e.Handled = true;
}
else if (e.OriginalSource == box.EditableTextBoxSite)
{
box.EditableTextBoxSite.SelectAll(); // <==
}
}
}
This method is registered for the GotFocus event in the static constructor using the EventManager:
EventManager.RegisterClassHandler(typeof(ComboBox), UIElement.GotFocusEvent, new RoutedEventHandler(ComboBox.OnGotFocus));
So, I think you can only change that behavior by deriving a custom control from ComboBox and override this event registration by your own method which replaces the call to SelectAll() with another method which sets the caret to the correct position. However, I do not know how to set the caret to the click position. You might have to use Reflector on the TextBox to find that...
Seems that I had to solve similar issue.
It's quite tricky, but the way I solved is to set IsEditable to false/true from code, at the same time I set the focus on TextBox.
Not the pretties way but does the job.