Within our application, there is a usercontrol, which allows to enter a number (inside a numericupdown
) followed by a combobox
which allows to select the SI-Prefix ([p, n, µ, m, -, k, M, G, T]
small to big)
Now, for easier usage, I thought it would be nice to capture the KeyPress
-Event on the numericUpDown
and set the combobox
accordingly. (If m
is pressed, select mili (m)
, if G
is pressed, select Giga (G)
)
This works flawless with the following handler / selector:
private void numericUpDown1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsLetter(e.KeyChar))
{
//Check, if its valid for si prefixes.
if (this.siSelector1.TrySelect(e.KeyChar)
{
e.Handled = true;
}
}
}
Where TrySelect
does nothing but the following:
public Boolean TrySelect(Char chr)
{
var entry = this.comboBox_siPrefix.Items.Cast<KeyValuePair<String,Double>>().Where(e => e.Key.Contains("(" + chr + ")")).FirstOrDefault();
if (!entry.Equals(new KeyValuePair<String, Double>()))
{
this.comboBox_siPrefix.SelectedItem = entry;
return true;
}
return false;
}
That's fine, but everytime the user hears a "BING" whenever a non-numeric Key is pressed on the numericupdown
.
I read about e.SuppressKeyPress
, which unfortunately isn't available with KeyPressEventArgs
- it's only available for KeyEventArgs
.
So, trying the whole thing with the KeyDown
-Event works. (No "BING") - but I wasn't able to capture capital keys, as every KeyDown
will fire the Event immediately...
private void numericUpDown1_KeyDown(object sender, KeyEventArgs e)
{
KeysConverter kc = new KeysConverter();
if (char.IsLetter(kc.ConvertToString(e.KeyCode)[0]))
{
//Check, if its valid for si prefixes.
if (this.siSelector1.TrySelect(kc.ConvertToString(e.KeyCode)[0]))
{
e.Handled = true;
e.SuppressKeyPress = true;
}
}
}
Any Ideas?
Figured out a way:
When Using KeyDown
-Event, you can use e.Modifiers
to check, if another key is down'd at the same time.
I dunno why, but for the KeyDown
-Event e.KeyValue
as well as e.KeyCode
always return the CAPITAL version of the key.
So, I modified the handler to convert every char to lower-case, and only convert it to upper-Case if SHIFT
is pressed at the same time:
Works - no "BING" (for valid SI-Prefixes). :-)
private void numericUpDown1_KeyDown(object sender, KeyEventArgs e)
{
KeysConverter kc = new KeysConverter();
char c = char.ToLower(kc.ConvertToString(e.KeyValue)[0]);
if (char.IsLetter(c))
{
//Caps?
if (e.Modifiers == Keys.Shift)
{
c = char.ToUpper(c);
}
//Check, if its valid for si prefixes.
if (this.siSelector1.TrySelect(c))
{
e.Handled = true;
e.SuppressKeyPress = true;
}
}
}
The above solution does not apply for µ
(CTRL+ALT+m or ALT GR+m)
Update: This is not 100%, but I didn't get it by now:
Update 2:
So, I had to exclude the "m" from beeing matched with char.isLetter()
(if alt
is pressed) and finally add another check.
I found, that comparing e.KeyValue==77
worked as expected, while comparing c=='m'
didn't... (then µ
was inserted into the numericupdown
, which it shouldn't)
if (ctrl && alt && c=='m')
:
if (ctrl && alt && e.KeyValue==77)
Dunno why - Ideas?
private void numericUpDown1_KeyDown(object sender, KeyEventArgs e)
{
KeysConverter kc = new KeysConverter();
char c = char.ToLower(kc.ConvertToString(e.KeyValue)[0]);
Boolean ctrl = e.Control;
Boolean alt = e.Alt;
Boolean shift = e.Shift;
int keyPadStart = (int)Keys.NumPad0;
int keyPadEnd = (int)Keys.NumPad9;
if (e.KeyValue >= keyPadStart && e.KeyValue <= keyPadEnd)
{
//send to numeric updown.
return;
}
if (char.IsLetter(c) && !alt)
{
if (shift) c = char.ToUpper(c);
//Check, if its valid for si prefixes.
if (this.siSelector1.TrySelect(c))
{
e.Handled = true;
e.SuppressKeyPress = true;
}
}
//not working: if (ctrl && alt && c=='m')
if (ctrl && alt && e.KeyValue==77)
{
//Check, if its valid for si prefixes.
if (this.siSelector1.TrySelect('µ'))
{
e.Handled = true;
e.SuppressKeyPress = true;
}
}
}