Use SHIFT + ENTER for multiline textbox in UWP - c#

I would like to adjust the behavior of a TextBox, so that SHIFT + ENTER on the keyboard inserts a new line, while just ENTER executes a different command (such as changing focus or pressing "send" like in messaging apps).
By default, the AcceptsReturn property of the TextBox being set to true inserts a new line when ENTER is pressed. Changing AcceptsReturn to false seems to prevent the new line from working at all, even if I manually add the new line:
private void ContentTextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to false in XAML.
if (e.Key == VirtualKey.Enter)
{
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
{
// SHIFT is pressed, so add a new line.
this.ContentTextBox.Text += "\r";
}
else
{
// SHIFT is not pressed, so execute my ENTER logic.
this.Focus(FocusState.Programmatic);
}
}
}
Based on this post, I was able to come up with a workaround that functionally works, but has a visual side effect. I set AcceptsReturn to true, and then manually remove the new line when SHIFT is not pressed, followed by executing the code I want when just ENTER is pressed. The side effect is that the textbox expands to accommodate the new line, then immediately shrinks again, suggesting that its automatically handling the ENTER input before my handler is even run. The code for this follows:
private void ContentTextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to true in XAML.
if (e.Key == VirtualKey.Enter)
{
// If SHIFT is pressed, this next IF is skipped over, so the
// default behavior of "AcceptsReturn" is used.
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down)
{
// SHIFT is not pressed, so remove the new line.
string textboxText = this.ContentTextBox.Text;
textboxText = textboxText.Remove(textboxText.Length - 1);
this.ContentTextBox.Text = textboxText;
// Execute my ENTER logic.
this.Focus(FocusState.Programmatic);
}
}
}
Is there a different way to do this, or a way to get rid of that side effect? I tried adjusting the e.IsHandled value, but that didn't work (which makes sense, if the default behavior is running before my code).

(In continuation from comment)You can use PreviewKeyDown Event as keydown event will not fire for system handled keys
private void TextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down)&& e.Key == Windows.System.VirtualKey.Enter)
{
//Add New Line
}
else if (e.Key == Windows.System.VirtualKey.Enter)
{
//This will prevent system from adding new line
e.Handled = true;
}
else
{
e.Handled = false;
}
}

Handling the PreviewKeyDown event, and marking the event as "handled" prevents the new line from being added in the first place (and thus also prevents the side effect). The full working code follows:
private void ContentTextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to true in XAML.
if (e.Key == VirtualKey.Enter)
{
// If SHIFT is pressed, this next IF is skipped over, so the
// default behavior of "AcceptsReturn" is used.
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down)
{
// Mark the event as handled, so the default behavior of
// "AcceptsReturn" is not used.
e.Handled = true;
}
}
}
private void ContentTextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to true in XAML.
if (e.Key == VirtualKey.Enter)
{
// If SHIFT is pressed, this next IF is skipped over, so the
// default behavior of "AcceptsReturn" is used.
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down)
{
// SHIFT is not pressed, so execute my ENTER logic.
this.Focus(FocusState.Programmatic);
}
}
}

Related

Forms, basic calculator key triggering problem

private void UserInputText_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.D4 && e.Modifiers == Keys.Shift) || (e.KeyCode == Keys.Add))
{
if (String.IsNullOrEmpty(UserInputText.Text))
{
MessageBox.Show("Bir sayı giriniz.");
UserInputText.Clear();
return;
}
if (double.TryParse(UserInputText.Text, out sayı1))
{
CalculationResultText.Text = sayı1 + " + ";
islem = "+";
UserInputText.Clear();
}
else
{
MessageBox.Show("Sadece sayı değeri girebilirsiniz.");
UserInputText.Clear();
}
}
}
I am coding a basic forms calculator. I am trying to trigger addition function and clear the textbox when textbox is focused and user presses "+" key. "if (String.IsNullOrEmpty(UserInputText.Text)) and else conditions work well. But if no Message boxes shows up as in the
if (double.TryParse(UserInputText.Text, out sayı1)) condition, the "+" character remains in the textbox as in the image. Thanks for help.
If I understand correctly, you want to first check the character that was typed in and if it's incorrect then you want to prevent this character from appearing?
If so, then you need to set e.Handled = true property when you want to prevent it.
This call tells the GUI element (your TextBox) that "I did all the checks for this event (i.e. KeyDown event), and I don't want you to contribute in handling of this event (i.e. normally the TextBox would try to add this character to its Text property, but you prevent it)".
Check out documentation on KeyEventArgs.Handled.
KeyPress event enables you to prevent any further changes in the TextBox.
You can do that thanks to Handled property of KeyPressEventArgs
private void UserInputText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '+')
{
UserInputText.Clear();
e.Handled = true;
}
}

How to make TextBox handle text like a hyperterminal in c#?

When the user enters a character with the TextBox in focus, I do not want the character to show up on the TextBox at all and I don't want to use the Clear() method as there may be other text in the TextBox I don't want erased. so far I've tried:
private void WriteBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13) // enter key pressed
{
WriteBox1.Text = "";
}
// Code to write Serial....
String writeValues = WriteBox1.Text;
String withoutLast = writeValues.Substring(0, 1);
WriteBox1.Text = withoutLast;
}
This leaves the last letter entered in writeBox1. I need it to delete all characters entered.
I've also tired:
writeValues.Replace(writeValues, "");
WriteBox1.Text = writeValues;
Try setting Handled property on eventargs. Set Handled to true to cancel the KeyPress event. This keeps the control from processing the key press.
example :
private void keypressed(Object o, KeyPressEventArgs e)
{
// The keypressed method uses the KeyChar property to check
// whether the ENTER key is pressed.
// If the ENTER key is pressed, the Handled property is set to true,
// to indicate the event is handled.
if (e.KeyChar == (char)Keys.Return)
{
e.Handled = true;
}
}
https://msdn.microsoft.com/ru-ru/library/system.windows.forms.keypresseventargs.handled%28v=vs.110%29.aspx

control what the enter key does in WPF

I have a RichTextBox that i am searching text in and I want to be able to control what the enter key does when text is selected. I am able to use this if test below to call the method that I want, but my issue is after the method gets hit when the enter key is pressed it then moves the text to the second line and I want to be able to stop this from happening when the text is highlighted.
I test to check if the text is selected when enter is pressed.
if (IsTextSelected == true)
{
btnSearch_Click(sender, null);
}
You can listen to the PreviewKeyDown event like:
<RichTextBox PreviewKeyDown="RichTextBox_PreviewKeyDown"/>
and in the handler:
private void RichTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
// DO YOUR WORK HERE and then set e.Handled to true on condition if you want to stop going to next line//
e.Handled = true;
}
}

Richtextbox deletes selected text

I have the following code:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
}
}
When I press the N key , the selected text is replaced with "n". I read this Selecting text in RichTexbox in C# deletes the text ,but it had no effects.
I am using Windows Forms.
Likely, you will need e.Handled = true; in this to stop the event.
http://msdn.microsoft.com/en-us/library/system.windows.forms.keyeventargs.handled.aspx
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
e.Handled = true;
}
}
Try it yourself:
Open up the editor, type some text, mark some of this text and press N. What happens? The marked text is replaced with n.
The same thing happens in your RichTextBox. Important to understand here is, that with the event you set up, you only add some functionality and leave the default event handling (handled by the OS) intact.
So with your code, on a key press you just do
richTextBox1.Select(1, 3);
which selects some characters and afterwards the default event handling kicks in. Thus there is some marked text which gets replaced with N.
So, you simply have to mark the event as handled by yourself. Not using the Handled-property, but with the SuppressKeyPress-property.
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
e.SuppressKeyPress = true;
}
}
The documentation of Handled clearly states:
If you set Handled to true on a TextBox, that control will
not pass the key press events to the underlying Win32 text
box control, but it will still display the characters that the user typed.
Here is the official documentation of SuppressKeyPress.

override navigation of datagridview using enter key is not working

I want to modify the current behaviour of datagridview related to navigation on enter key. Current behaviour is to jump to the next row and same column, and I want to jump to the next column and same row so I have implemented the following keyDown event:
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
int numCols = this.dataGridView1.ColumnCount;
int numRows = this.dataGridView1.RowCount;
DataGridViewCell currCell = this.dataGridView1.CurrentCell;
if (currCell.ColumnIndex == numCols - 1)
{
if (currCell.RowIndex < numRows - 1)
{
this.dataGridView1.CurrentCell = this.dataGridView1[0, currCell.RowIndex + 1];
}
}
else
{
this.dataGridView1.CurrentCell = this.dataGridView1[currCell.ColumnIndex + 1, currCell.RowIndex];
}
e.Handled = true;
}
}
The problem is that the above event is not being raised on enter key pressed despite I have subscribed to the datagridview keydown event correctly by doing:
this.dataGridView1.KeyDown += new KeyEventHandler(dataGridView1_KeyDown);
Hence that, the current behaviour on enter key pressed continues being the default: next row and same column.
Any ideas?
Have you tried KeyUp? I would guess the default behavior to move to another row would occurr on KeyUp, give it a test, press enter and hold it and see if it moves down a column or if it waits for you to keyup. Also could be keypress, might test each of these to see because your event might be firing before the default event behavior.
Also, are you certain the code which has the event subscription is executing? If it's in the standard place I would assume so, but I'm just throwing out there the possibility that you have that line placed in a method which does not execute just in case.
private void dataGridView2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
e.Handled = true;
SendKeys.Send("{tab}");
}
}

Categories

Resources