I'm currently working on a calculator project and I have run into two problems.
The first problem is how to handle the keypress event so that numbers plus (+-/*.) all work however every other key is blocked. Heres the code im using at the moment:
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true;
}
I know I could add each symbol separately by using && (e.KeyChar != '+') && (e.KeyChar != '-') but is there an easier more efficient way of handle all of these keys?
Edit: Sorry forgot to mention that my calculator uses a text box so that is why I need to block the use of letters and some symbols
My second question is how can I stop the user being able to write two or more decimal points in one number for example 9.5.6 or 0.3.2.9?
Thanks
Declare char array on class level:
private char[] allowed = new char[]
{
'/','*','+','-'
};
On keypress event:
if (!char.IsDigit(e.KeyChar) && !allowed.Contains(e.KeyChar) )
{
e.Handled = true;
}
Related
I have a TextEdit.PreviewKeyDown method where I want to check if an input character is equal to a special character of my choosing.
For an instance I want to check if the user's input character is '#'. I'd use:
if(e.Key == Key.D3 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
The problem is I don't know what the special character will be at the time and I can't possibly program all the cases, so I wanted something like:
string strSpecChar = GetSpecialCharacter();
if(strSpecChar = e.Key) {do_sth();}
Which doesn't work at all, because if I press, for example '3', the e.Key value will be equal to 'D3', so if my strSpecChar value is '3' I can't get to the do_sth()
I have browsed through the System.Windows.Input.KeyEventArgs docs and I've found nothing and I've also read some discouraging posts on other forums.
Is there any way I would be able to compare the PreviewKeyDown e and string strSpecChar?
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
string strNewLigneSign = String.Empty;
if (InsertTextDialogHelper != null)
strNewLigneSign = InsertTextDialogHelper.GetNewLineSign();
if (e.Key.Equals(strNewLigneSign))
{
if (!String.IsNullOrEmpty(strNewLigneSign))
{
int strCaretPosition = TextBox.CaretIndex;
e.Handled = true;
string strNewText = "\r\n";
CurrentDialogData.TextValue = CurrentDialogData.TextValue.Insert(strCaretPosition, strNewText);
TextBox.CaretIndex = strCaretPosition + strNewText.Length;
}
}
}
EDIT:
As per #mm8's suggestion I tried to implement it in the TextEdit.PreviewTextInput property as follows:
XAML
<dxe:TextEdit Name="TextBox"
PreviewTextInput="TextBox_PreviewTextInput" \">
</dxe:TextEdit>
C#
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string strNewLigneSign = String.Empty;
if(InsertTextDialogHelper != null)
strNewLigneSign = InsertTextDialogHelper.GetNewLineSign();
if(!String.IsNullOrEmpty(strNewLigneSign))
{
if(e.Text.Contains(strNewLigneSign))
{
int strCaretPosition = TextBox.CaretIndex;
e.Handled = true;
string strNewText = Unhashify(e.Text);
CurrentDialogData.TextValue = CurrentDialogData.TextValue.Insert(strCaretPosition, strNewText);
TextBox.CaretIndex = strCaretPosition + strNewText.Length;
}
}
}
However when I run the app and set the breakpoints anywhere inside that method it seems never to go inside it.
The exact same solution worked for me back when I used it in wpf's TextBox, but as soon as I switched to devexpress, the TextBox_PreviewTextInput method is never called.
A key is a key and not a character. It's eventually mapped to a character depending on the input device.
You may want to consider handling PreviewTextInput and check the value of Text[0] of the TextCompositionEventArgs instead of handling PreviewKeyDown.
I am currently working on a custom control that allow users to enter either a decimal or in time format (hh:mm). So I would like that if the TextBox contain a period(.), the user will no longer add/enter a colon(:) and vice versa.
I have this code below so that user can only enter numeric, a period and a colon.
private void txtTime_KeyPress(object sender, KeyPressEventArgs e)
{
if ((!char.IsControl(e.KeyChar) & !char.IsDigit(e.KeyChar) & !(Convert.ToString(e.KeyChar) == ".") & !(Convert.ToString(e.KeyChar) == ":")))
{
e.Handled = true;
}
else
{
//only allow one '.' & ':'
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
else if (e.KeyChar == ':' && (sender as TextBox).Text.IndexOf(':') > -1)
{
e.Handled = true;
}
}
}
So my question is, how will I do it?
Can somebody help me? Thanks in advance.
For operators it is a nuisance if they have typed something, and they want to correct it, but they can't because there is an incorrect dot or a semicolon in it.
Suppose the operator tried to type 14:38:21, but instead types:
14.38
"Oh no, this is wrong, I wanted 14.38:21! So let's first continue typing :21 and then go back to change the dot into a colon!"
Imagine the operator's frustration when he can't type :21, and doesn't understand why
In windows forms, only validate entered input when the operator expresses he finished editing the input.
Therefore, use TextBox.OnValidating. When this one is called, you can either accept or decline the input and tell the operator what is wrong.
protected override void OnValidating (CancelEventArgs e)
{
e.Cancel = this.IsInputErrorDetected;
if (e.Cancel)
{
this.DisplayInputProblem();
}
}
Bonus point: also works with copy-paste.
I am not sure, if I understand your question good.
Maybe you are looking for maskedTextBox where you can specify mask of user input.
This one has mask for short time HH:MM
I need some help because I can't seem to get to display the text label here. I am using Windows Form C# VS 2015. When I press enter the error is on barangay = int.Parse(lblDistrict.Text); uhm also, I am applying the same way console.readline is used but it seems that it doesn't work. Can somebody help me in the code? :) Thanks in advance
private void txtBarangay_KeyPress(object sender, KeyPressEventArgs e)
{
int barangay = 0;
barangay = int.Parse(lblDistrict.Text);
if (e.KeyChar == (char)13)
{
if (barangay >= 1 && barangay <= 146)
{
lblDistrict.Text = "District 1";
}
else if (barangay >= 147 && barangay <= 267)
{
lblDistrict.Text = "District 2";
}
}
}
It is the matter of focus. When you press the key, which control is focused? Is it the one that you have written the KeyPress event for?
So you must make sure that either when the key is pressed either that specific control has the focus, or add this even to all controls.
I don't know what kind of Exception you get , but you must use Int.TryParse instead of int.parse .
check this link http://dailydotnettips.com/2016/01/16/back-to-basic-difference-between-int-parse-and-int-tryparse/
Thanks
First, Please include try-catch block in your program in-order to catch the exception.
If the string in the textBox contains anything other than ONLY numbers (Example "12er"), It will throw Exception. Try Int.TryParse if this is the case
I am developing a simple Universal Windows App using C#. I have a RichEditBox and I found a weird behavior when using Control+I key combination, which for some reason inserts a Tab (is that expected?). Because I wanted the combination of keys to toggle Italic font style, I thought the best way was through the KeyDown event.
So, this is my code:
private void richbox_KeyDown(object sender, KeyRoutedEventArgs e)
{
System.Diagnostics.Debug.Write("\nKeyDown : " + e.Key.ToString());
if (e.Key == VirtualKey.Tab)
{
richbox.Document.Selection.TypeText("\t");
e.Handled = true;
}
else if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) == Windows.UI.Core.CoreVirtualKeyStates.Down)
{
//If Control is pressed down, check if current key is B,I,U...
System.Diagnostics.Debug.Write(" => Control is down!");
switch (e.OriginalKey)
{
case VirtualKey.B:
toogleBold();
e.Handled = true;
break;
case VirtualKey.I:
e.Handled = true;
toogleItalic();
break;
case VirtualKey.U:
toogleUnderline();
e.Handled = true;
break;
}
}
}
My problem is, the condition on the Else If is not always true when I press the Control key. I would like to understand why and what could I do to fix it.
If I run the code and I press the control key a few times, this is the output:
KeyDown : Control => Control is down!
KeyDown : Control
KeyDown : Control => Control is down!
KeyDown : Control
...
Thanks in advance :)
I tried your code and used debugger output to see what the actual state of Ctrl is in those situations:
var state = Window.Current.CoreWindow.GetKeyState(VirtualKey.Control);
Debug.WriteLine(state);
What I found out is that the second time you press the key, its state is not Down, but Down|Locked, more specifically Windows.UI.Core.CoreVirtualKeyStates.Down | Windows.UI.Core.CoreVirtualKeyStates.Locked. It turns out CoreVirtualKeyStates is a flag enum and it can have multiple values at the same time. In this case you are comparing with == which means you don't get a match. You can first use the HasFlag method or bitwise AND (&) to get the right value out and then compare and you will be good to go!
That means either this:
else if ( Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).
HasFlag( CoreVirtualKeyStates.Down ) )
{
//rest of the code
}
Or this:
else if (
( Window.Current.CoreWindow.GetKeyState(VirtualKey.Control) &
Windows.UI.Core.CoreVirtualKeyStates.Down )
== CoreVirtualKeyStates.Down )
{
//rest of the code
}
Creating a key hook so that when the combination is pressed, the application will open again.
I have looked into various ways of doing it, however I do not know what the input combination will be unlike this example:
if (e.KeyCode == Keys.C && e.Modifiers == Keys.Control && e.Modifiers == Keys.Shift)
{
//Do work
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
//Paste
}
Our input combination is from the user, where they select which combination they want to input from a combo box.
public void KeyboardHooks_OnKeyPress(object sender, KeyPressArgs e)
{
//The first input
if (LastKey != Keys.None)
{
Keys combinationOne = (Keys)cmbCombinationOne.SelectedValue;
Keys combinationTwo = (Keys)cmbCombinationTwo.SelectedValue;
}
LastKey = e.Key;
MessageBox.Show("KeyPressed");
}
Not sure on how to go about setting our values to the combo box's
From your code snippets it looks like you're going the route of WinForms key events. If the user does a key combination in your application and you do this 'open' of something else, you're on the right path. You'll just need to make it dynamic to see if the user-defined items are pressed.
So when you save the user settings, convert it to a keycode so you can do the generic
if(e.KeyCode == Settings.FirstModKey && e.KeyCode == Settings.SecondModKey && e.KeyCode == Settings.FirstKey)
You'll need to consider the multiple scenarios, the modifiers Shift, Alt and Control could be none, one, two, or all three. In my above, you could have FirstModKey and SecondModKey the same value if the user chose Ctrl only, or they could be handling if they did Ctrl and Shift both. Then FirstKey is the non-mod key, like 'A'.
the application will open again
However, from the quote it sounds like you want a global hook, that wherever the user is in any application, with yours not running, you want to listen and do work if its your keycode. You need to look into a service and low level hooks. This can come close to keylogging and you need to be careful who your audience is, security risks and concerns that you might be breaking compliance.
{
//The first input
if (LastKey != Keys.None)
{
int combination1 = (int)Enum.Parse(typeof(Keys), cmbCombinationOne.SelectedValue.ToString());
int combination2 = (int)Enum.Parse(typeof(Keys), cmbCombinationTwo.SelectedValue.ToString());
int LastKeyPress = (int)Enum.Parse(typeof(Keys), LastKey.ToString());
ThisKey = e.Key;
if (combination1 == LastKeyPress && combination2 == Convert.ToInt32(ThisKey))
{
MessageBox.Show("Key pressed");
}
}
LastKey = e.Key;
}
This worked with my original existing code