I'm creating an UWP app (C# .NET) where there is textbox. I want to implement a shortcut (Ctrl+F) to search texts in the textbox. I know how to find texts, but I don't know how to implement the shortcut.
I found this:
if ((e.Control && e.KeyCode == Keys.F) || (e.Control && e.KeyCode == Keys.S))
{
//do something
}
...but it isn't working for UWP. I tried this (textarea is name of textbox):
private void textarea_KeyDown(object sender, KeyRoutedEventArgs e)
{
if ((e.Key == Windows.System.VirtualKey.Control) && (e.Key == Windows.System.VirtualKey.F))
{
flayoutFind.ShowAt(appBarButtonFind as FrameworkElement);
}
}
but it isn't working too. How can I do it?
And for the future, is there any way, how to override default functionality and shortcut of textbox Ctrl+Z (undo)?
You should be using "Accelerators" and "Access keys" as described here:
https://learn.microsoft.com/en-us/windows/uwp/input-and-devices/keyboard-interactions
Basically, you will have to register for events
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated += Dispatcher_AcceleratorKeyActivated;
private void Dispatcher_AcceleratorKeyActivated(CoreDispatcher sender, AcceleratorKeyEventArgs args)
{
//Implementation
}
You can check the sample in detail here: https://github.com/Microsoft/DesktopBridgeToUWP-Samples/blob/master/Samples/SQLServer/BuildDemo/MainPage.xaml.cs
Related
I have a TextBox in a C#/XAML desktop app and I want to detect the Shift+Enter command. How can I do this?
So far I have only been able to find information on commands like Ctrl+A, etc.
ModifierKeys.Shift allows you to identify key pressed combinations which includes Shift:
private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && (Keyboard.Modifiers == ModifierKeys.Shift))
{
// Handle..
}
}
Another option is Keyboard.IsKeyDown static method (see Shoe's answer).
if (Keyboard.Modifiers == ModifierKeys.Shift && Keyboard.IsKeyDown(Key.Enter))
{
MessageBox.Show("test");
}
A good example can be found here.
public void TextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
{
MessageBox.Show("Pressed " + Keys.Shift);
}
}
I need to be able to detect if an "undo" has been triggered, and whether or not it has had an effect on the contents of my RichTextBox.
Of I type content into the RichTextBox at the minute, and press Ctrl+Z, windows seems to handle the undo for me. I want to be able to write code that will get triggered straight after that. I have been looking around and can't find anything.
Thanks in advance.
Starting from .Net 3.0, there is a simple built-in way to get notified when an undo command (among others) is executed:
CommandManager.RegisterClassCommandBinding(typeof(MyClass),
new CommandBinding(ApplicationCommands.Undo, OnUndo));
Just call this line of code in the static constructor (or somewhere else) and add a static method:
private static void OnUndo(object sender, ExecutedRoutedEventArgs e)
{
//your code
}
WINFORM:
You could exploit the KeyDown event and detect if Ctrl+Z is pressed:
richTextBox.KeyDown += new KeyEventHandler(richTextBox_KeyDown);
private void richTextBox_KeyDown(object sender, KeyEventArgs e){
if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Z){
//undo detected, do something
}
}
WPF :
richTextBox.KeyUp += new KeyEventHandler(richTextBox_KeyUp);
void richTextBox_KeyUp(object sender, KeyEventArgs e) {
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.Z) {
//undo detected, do something
}
}
I think you're going to have to implement that yourself. I'm not aware of an event out of the box that will suit your needs.
You might also want to have a look at Monitored Undo Framework.
And here for additional reading.
If I well understand you, you want to compare content before and after the Ctr+Z.
Then you should do :
In XAML File :
<RichTextBox PreviewKeyDown="RichTextBox_PreviewKeyDown" KeyUp="RichTextBox_KeyUp" />
In CS File :
private void RichTextBox_KeyUp(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.Z)
{
Console.WriteLine("After : " + new TextRange(((RichTextBox)sender).Document.ContentStart, ((RichTextBox)sender).Document.ContentEnd).Text);
}
}
private void RichTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.Z)
{
Console.WriteLine("Before : " + new TextRange(((RichTextBox)sender).Document.ContentStart, ((RichTextBox)sender).Document.ContentEnd).Text);
}
}
Then, you will see in the output of your application the content of your RichTextBox before the Ctrl+Z and the content after.
I've try it and it works fine !
As already described, CommandBindings can be used. I prefer binding to each control instead of binding to all controls of a specific class. This can be done in the following way:
this.richTextBox.CommandBindings.Add(
new CommandBinding(ApplicationCommands.Undo, this.RichTextBoxUndoEvent));
private void RichTextBoxUndoEvent(object sender, ExecutedRoutedEventArgs e)
{
e.Handled = true;
this.richTextBox.Undo();
}
Is it possible, to capture (somewhere in app.xaml.cs i guess) any key and if it pressed open window?
Thanks for help!
There is a better way. Found this on a MS forum. Works like a charm.
Put this code in Application startup:
EventManager.RegisterClassHandler(typeof(Window),
Keyboard.KeyUpEvent,new KeyEventHandler(keyUp), true);
private void keyUp(object sender, KeyEventArgs e)
{
//Your code...
}
You could use something like this gist to register a global hook. It will fire whenever the given keys are pressed while your application is running. You can use it in your App class like this:
public partial class App
{
private HotKey _hotKey;
protected override void OnActivated(EventArgs e)
{
base.OnActivated(e);
RegisterHotKeys();
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
UnregisterHotKeys();
}
private void RegisterHotKeys()
{
if (_hotKey != null) return;
_hotKey = new HotKey(ModifierKeys.Control | ModifierKeys.Shift, Key.V, Current.MainWindow);
_hotKey.HotKeyPressed += OnHotKeyPressed;
}
private void UnregisterHotKeys()
{
if (_hotKey == null) return;
_hotKey.HotKeyPressed -= OnHotKeyPressed;
_hotKey.Dispose();
}
private void OnHotKeyPressed(HotKey hotKey)
{
// Do whatever you want to do here
}
}
Yes and no.
Focus plays a role in the order for which a given key is handled. The control which captures the initial key press can opt to not pass the key along, which would prohibit you from capturing it at the top most level. In addition there are controls within the .NET framework that swallow certain keys under certain scenarios, however I am unable to recall a specific instance.
If your application is small and the depth is nothing more than a Window with buttons, this is certainly attainable and would follow the standard approach to capturing key strokes within a WPF application.
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
myVariable = true;
if (ctrl && e.Key == Key.S)
base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
myVariable = false;
base.OnKeyUp(e);
}
If your application is large you can attempt a global hook as detailed here but understand that the aforementioned caveats can still exist.
I am working on a C# winForms application where I am using lots of RichTextBoxes. I found out that if I copied an image and pasted that in any RichTextBox, the image would be posted. Is there a way not to allow images to be pasted in the RichTextBox. In other words, to only allow keyboard characters.
The problem with the answer above is that it doesn't work in cases where there is mixed content. For example if you highlight a few rows from a spreadsheet and paste into a richtextbox you end up with more than just the raw text. I think the better solution is below:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
if (Clipboard.GetData("Text") != null)
Clipboard.SetText((string)Clipboard.GetData("Text"), TextDataFormat.Text);
else
e.Handled = true;
}
}
EDIT: The method below was shared by MrCC and is a more direct / better approach than my method above.
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
if (Clipboard.ContainsText())
richTextBox1.Paste(DataFormats.GetFormat(DataFormats.Text));
e.Handled = true;
}
}
I was able to answer my question. Here it is in case someone else was looking for it.
private void InputExpressionRchTxt_KeyDown(object sender, KeyEventArgs e)
{
bool ctrlV = e.Modifiers == Keys.Control && e.KeyCode == Keys.V;
bool shiftIns = e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert;
if (ctrlV || shiftIns)
if (Clipboard.ContainsImage())
e.Handled = true;
}
Maybe, you can catch paste event and check what object copied to RichTextBox.
If it Image, just delete it.
I have the follwing code (which is not working):
private void Window_PreviewKeyDown(object sender, KeyEventArgs e) {
e.Handled = true;
if ((e.Key == Key.P) && (Keyboard.Modifiers == ModifierKeys.Alt)) {
MessageBox.Show("Thanks!");
}
}
Why doesn't this work? The event is firing, but
(e.Key == Key.P) && (Keyboard.Modifiers == ModifierKeys.Alt))
never evaluates to true.
My similar events using Ctrl instead of Alt in this way work. Also my events that include Ctrl and Alt work as well.
A better way to work with keys in WPF is Key Gestures
e.g. note that this is an example, not a solution
<Window.InputBindings>
<KeyBinding Command="ApplicationCommands.Open" Gesture="ALT+P" />
</Window.InputBindings>
There's more to it that that but you'll work it easily enough. That's the WPF way to handle keys!
PK :-)
You need to do a 'bitwise and' with the ModifierKeys as shown below...
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if ((e.Key == Key.P) && ((e.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt))
{
MessageBox.Show("Thanks!");
e.Handled = true;
}
}
Also, do not forget to set the Handled property of the e parameter...
MSDN gives us this example:
if(e.Key == Key.P && e.Modifiers == Keys.Alt)
does this work for you?