【问题标题】:Suppress Key "Bing" with KeyPressEvent?使用 KeyPressEvent 抑制键“Bing”?
【发布时间】:2018-09-21 16:07:34
【问题描述】:

在我们的应用程序中,有一个用户控件,它允许输入一个数字(在 numericupdown 内),然后是一个 combobox,它允许选择 SI 前缀([p, n, µ, m, -, k, M, G, T] 从小到大)

现在,为了更方便使用,我认为最好在numericUpDown 上捕获KeyPress-Event 并相应地设置combobox。 (如果m被按下,选择mili (m),如果G被按下,选择Giga (G)

这与以下处理程序/选择器完美配合:

 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;
            }
        }
    }

TrySelect 只执行以下操作:

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;
    }

这很好,但每次用户在numericupdown 上按下非数字键时都会听到“BING”。

我读到了e.SuppressKeyPress,很遗憾,KeyPressEventArgs 不提供该功能 - 它仅适用于 KeyEventArgs

所以,用KeyDown-Event 尝试整个事情是可行的。 (没有“BING”)-但我无法捕获大写键,因为每个KeyDown 都会立即触发事件...

 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;
            }
        }
    }

有什么想法吗?

【问题讨论】:

  • 这不是重复的吗:Stop the 'Ding' when pressing Enter
  • @LarsTech 否,因为Keys.Enter 是单个键,它与KeyDown-Event 一起使用,如示例所示。 SHIFT+G是通过KeyPress-Event捕获的,缺少e.SuppressKeyPress-Property。
  • 我不明白这个问题。如果用户按下了一个您不满意的键,那么它就会响起。如果您不想听到叮当声,请始终为非数字字符设置 e.Handled = true。 SuppressKeyPress 无关紧要,KeyPress 事件已经引发。 KeyDown 在外来键盘布局上不是一个好主意。
  • @HansPassant 是的,但在这种情况下 - 在numericupdown 上,我对m, k, G,T... 等有效字母感到满意,因为为了方便起见,它们应该被发送到另一个控件 - 所以我不想要一个“必应”。 Handled=true(谷歌搜索!)不会删除 numericupdown 字段的 BING。 (错误或功能?)只有 e.SuppressKeyPress 可以。

标签: c# winforms keypress keydown


【解决方案1】:

想出一个办法:

当使用KeyDown-Event 时,您可以使用e.Modifiers 来检查是否同时按下了另一个键。

我不知道为什么,但是对于 KeyDown-Event e.KeyValuee.KeyCode 总是返回密钥的大写版本。

因此,我修改了处理程序以将每个字符转换为小写,并且仅在同时按下SHIFT 时将其转换为大写:

有效 - 没有“BING”(对于有效的 SI 前缀)。 :-)

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;
            }
        }
    }

上述解决方案不适用于µ(CTRL+ALT+m 或 ALT GR+m)


更新:这不是 100%,但我现在还没明白:

  • 如果按下 ALT 键,Char-Code 始终报告“M”。

更新 2:


所以,我不得不从匹配 char.isLetter() 的蜜蜂中排除“m”(如果按下了 alt),最后添加另一个检查。

我发现,比较 e.KeyValue==77 按预期工作,而比较 c=='m' 没有...(然后 µ 被插入到 numericupdown 中,这是不应该的)

if (ctrl &amp;&amp; alt &amp;&amp; c=='m'):

if (ctrl &amp;&amp; alt &amp;&amp; e.KeyValue==77)

不知道为什么 - 想法?

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;
            }

        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多