none
KeyDown與Click問題 RRS feed

  • 問題

  • 想請問,一個Form上是否無法同時存在KeyDown與Click的觸發呢
    在無button的情況下,KeyDown的觸發是正常的,但Form上加入button後,KeyDown就失效了。
    無論怎麼使用鍵盤,改變的只有Button的focus狀況

    2009年12月13日 上午 06:40

解答

  • 不可能吧, this大說的方法應該是正常的, 不過 "Enter"鍵就另當別論了
    MSDN文件有提到這一段 , 引述自 Control. KeyDown 事件
    「某些按鍵 (如 TAB、RETURN、ESCAPE 和方向鍵) 是自動由控制項處理。為了要讓這些按鍵可以引發 KeyDown 事件,您必須覆寫表單中每一個控制項的 IsInputKey 方法。覆寫 IsInputKey 的程式碼需要判斷是否已按下其中一個特殊按鍵並傳回 true 的值。

    所以如果是這些特殊按鍵. 還要再多加上覆寫 IsInpurKey方法才可以.
    像以下程式碼
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

          

            private void button1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("click");
            }

         

            private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show(sender.ToString ());
               e.Handled  = true;
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                this.KeyPreview = true;
            }
                  
        }
    當按 英文或數字鍵時它會正確回應由Form1引發, 但按 "TAB", "Enter"等等非字元輸入時不會回應. 因為要另外覆寫button的 IsInputKey方法.
    另請參閱MSDN文件庫[Control. IsInputKey 方法 ] .
    還有一個建議, 當有人回答你一個提示的時候, 你應該就那個提示去查一下資料 (ex: MSDN文件庫), 會比較容易瞭解更多的東西,
    因為我們也不可能長篇大論地回答你問題, 更何況, 自己動手查能體會的更深.


    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月14日 上午 04:20
    版主

所有回覆

  • 有程式碼嗎 ? 你這樣寫實在看不出來問題的重點.
    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月13日 上午 06:54
    版主
  • HI,

    Form上加入button後,要處理KeyDown事件, 必須將Form的KeyPreview屬性設定為True
    2009年12月14日 上午 02:13
  • 你好:
    我更改了KeyPreview屬性 ,但結果相同呢
    改變的仍然只有Button的focus狀況

    2009年12月14日 上午 03:53
  • 不可能吧, this大說的方法應該是正常的, 不過 "Enter"鍵就另當別論了
    MSDN文件有提到這一段 , 引述自 Control. KeyDown 事件
    「某些按鍵 (如 TAB、RETURN、ESCAPE 和方向鍵) 是自動由控制項處理。為了要讓這些按鍵可以引發 KeyDown 事件,您必須覆寫表單中每一個控制項的 IsInputKey 方法。覆寫 IsInputKey 的程式碼需要判斷是否已按下其中一個特殊按鍵並傳回 true 的值。

    所以如果是這些特殊按鍵. 還要再多加上覆寫 IsInpurKey方法才可以.
    像以下程式碼
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

          

            private void button1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("click");
            }

         

            private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show(sender.ToString ());
               e.Handled  = true;
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                this.KeyPreview = true;
            }
                  
        }
    當按 英文或數字鍵時它會正確回應由Form1引發, 但按 "TAB", "Enter"等等非字元輸入時不會回應. 因為要另外覆寫button的 IsInputKey方法.
    另請參閱MSDN文件庫[Control. IsInputKey 方法 ] .
    還有一個建議, 當有人回答你一個提示的時候, 你應該就那個提示去查一下資料 (ex: MSDN文件庫), 會比較容易瞭解更多的東西,
    因為我們也不可能長篇大論地回答你問題, 更何況, 自己動手查能體會的更深.


    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月14日 上午 04:20
    版主
  • 需觸發的按鍵分別是R,S,Enter與上下左右,照MSDN上所述應該得覆寫
    ...

    但MSDN內容this.SelectedText = "    ";不是很懂

    2009年12月14日 上午 05:19
  • 你指的是範例的這一段嗎?
    class TabTextBox : TextBox
    {
        protected override bool IsInputKey(Keys keyData)
        {
            if (keyData == Keys.Tab)
            {
                return true;
            }
            else
            {
                return base.IsInputKey(keyData);
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (e.KeyData == Keys.Tab)
            {
                this.SelectedText = "    ";                
            }
            else
            {
                base.OnKeyDown(e);
            }
        }
    }

    既然它是繼承TextBox, 又沒有覆寫這個屬性, 當然就是查它父系類別的同名屬性囉.
    [TextBoxBase. SelectedText 屬性 ]
    其實學會怎麼查正確的資料, 比抄Code來的重要.

    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月14日 上午 05:28
    版主
  • 恩,那部分我懂了,謝謝:)
    但覆寫控制項我想我的做法還是有問題
    private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                    switch (e.KeyCode)
                    {
                        case Keys.Left:
                            view.Text = "left";
                            break;
                        case Keys.Right:
                            view.Text = "right";
                            break;
                        case Keys.Down:
                            view.Text = "down";
                            break;
                        case Keys.Space:
                            view.Text = "space";
                            break;
                        case Keys.R:
                            view.Text = "R";
                            break;
                        case Keys.S:
                            view.Text = "S";
                            break;
                        case Keys.Enter:
                            view.Text = "Enter";
                            break;
                        default:
                            break;
                    }
                    e.Handled = true;
            }
    class Button1 : Button//其中一個控制項
            {
                protected override bool IsInputKey(Keys keyData)
                {
                    if ((keyData == Keys.Down) || (keyData == Keys.Right) || (keyData == Keys.Left)
                     || (keyData == Keys.Enter))
                    {
                        return true;
                    }
                    else
                    {
                        return base.IsInputKey(keyData);
                    }
                }
            }
    .....
    想請問問題是在哪邊
    2009年12月14日 上午 05:53
  • 你在畫面上的Button是繼承自Button1 Class 還是 Button Class ?
    要繼承Button1 Class 才會正確. 因為Button Class中的 IsInputKey並沒有被改變.
    以下是個例子: (我只做了Up鍵)
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_KeyDown(object sender, KeyEventArgs e)
            {
                MessageBox.Show(sender.ToString () + "--" +e.KeyCode .ToString ());
               e.Handled  = true;
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                this.KeyPreview = true;
                btn btn1 = new btn();
                this.Controls.Add(btn1);
            }

            private class btn : Button
            {
                protected override bool IsInputKey(Keys keyData)
                {
                    if (keyData == Keys.Up)
                    { return true; }
                    else
                    {
                        return base.IsInputKey(keyData);
                    }
                }

            }

                  
        }

    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月14日 上午 07:56
    版主
  • 按下空白鍵時,會同時觸發Button與KeyDown,這是不可避免的嗎?
    2009年12月14日 上午 09:47
  • 有觸發Button嗎 ?
    Space是屬於字元鍵. 並不會觸發Button.Click事件吧 ?

    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月14日 上午 10:03
    版主
  • private class btn : Button
    {
                protected override bool IsInputKey(Keys keyData)
                {
                    if (keyData == Keys.Left || keyData == Keys.Right || keyData == Keys.Down
                        || keyData == Keys.Space)
                    { return true; }
                    else
                    {
                        return base.IsInputKey(keyData);
                    }
                }

    }
    我的覆寫有包含Space,且方向鍵問題也解決了:)
    但是按下Space 與enter時,會同時觸發KeyDown 與Click


    ....解決了,少了e.Handled  = true; 只有space觸發出問題@@
    謝謝你的熱心教學^^  感激不盡~
    2009年12月14日 上午 11:14
  • Space應該是不用在 IsInputKey覆寫中特別處理才對.
    學而不思則罔, 思而不學則殆.
    如果你一直都看不懂、不想學習看懂、抗拒看懂MSDN Library的話,那你最好放棄想要寫好程式這件事
    如果你自私地不肯回饋與分享,那別人為何要花時間回答你的問題?
    2009年12月14日 下午 01:06
    版主
  • 恩,是的,剛剛發現了 :)
    感謝回應! 真的獲益良多
    2009年12月14日 下午 03:14