none
請問控件 TabIndex 及TabStop 設定後的 Focus 順序問題 RRS feed

  • 問題

  • 各位前輩好, 

    目前在設定控件的TabIndex屬性時遇到一個問題, 表單的布置如下圖:

    1. splitContainer1.Panel1 包含了三個控件(dateTimePicker1, comboBox1, textBox1)且 TabStop = true, TabIndex 依序為 1, 2, 3

    2. splitContainer1.Panel2 包含了splitContainer2 

    3. splitContainer1 與 splitContainer2 這兩件控件的 TabStop = false

    執行後我按鍵盤 Tab 鍵後得到的 Focus 順序分別是:dateTimePicker1 > comboBox1 > textBox1 > 持續停留在 textBox1

    請問要如何做才能再從 textBox1 跳回 dateTimePicker1 呢? 謝謝!


    2011年4月20日 上午 02:43

解答

  • 我剛剛多測了一下開了一個C#, 用.Net Framework 3.5的專案

    的確會出現你所說的狀況, 然後我把目標框架換成.Net Frameowrk 4.0 Client Profile, 它就正常了.

     


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    • 已標示為解答 weilin_ 2011年4月20日 上午 07:08
    2011年4月20日 上午 04:11
    版主
  • Hi,

    你搞錯我的用意了

    你提到了...

    "這樣的話是可以達到一樣的效果, 但是因為專案裡面需要這個功能的表單非常多, 每個表單開頭跟最後的控件也都不一定,

    所以想請問有沒有方法可以得知目前表單內 TabStop=true 且 TabIndex 為最大值(或最小值)的控件名稱呢? 謝謝!"

    會給你這篇是因為他可以Form的事件統一處理教點的移動~以ActiveControl偵測到當前焦點的控制項~~SelectNextControl可以控制往下一個焦點移動

    若要自己處理可能會能找出比較輕鬆的改法

    可能像是下面這樣去撰寫個方法~再透過迴圈或是搭配擴充方法輔助~將需要處理的表單事件繫上

            Dim oldControl As Control = SplitContainer1.ActiveControl
            SelectNextControl(SplitContainer1.ActiveControl, TrueTrueTrueTrue)
            If oldControl Is SplitContainer1.ActiveControl Then
                DateTimePicker1.Focus()
                oldControl = SplitContainer1.ActiveControl
            End If


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 weilin_ 2011年4月20日 上午 07:08
    2011年4月20日 上午 06:53

所有回覆

  • 我測試了一下, 你的設定應該是正確的, 我可以從textBox1回到dateTimepicker1

    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2011年4月20日 上午 03:24
    版主
  • 先謝謝Bill前輩的回應!!

    不好意思可以請問 Bill 前輩是否也有在 splitContainer1.Panel2 中加入一個 splitContainer2 嗎?

    因為我再試著把 splitContainer1.Panel2 裡的 splitContainer2 刪除就可以從 textBox1 回到 dateTimepicker1,

    但是在 splitContainer1.Panel2 內若放置了 splitContainer2 (且其TabStop=false) 後就又會變成持續停留在 textBox1 控件上 @@a

    2011年4月20日 上午 03:39
  • 我照著你的格式做的, 有兩個SplitContainer

    請到下列網址下載該專案

    http://files.dotblogs.com.tw/billchung/1104/2011420114830233.zip


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    2011年4月20日 上午 03:49
    版主
  • 感謝前輩!! 

    但因為我目前開發工具是Visual Studio 2008, 我馬上至微軟下載免費版的 2010 來測試看看!

    2011年4月20日 上午 03:55
  • 我剛剛多測了一下開了一個C#, 用.Net Framework 3.5的專案

    的確會出現你所說的狀況, 然後我把目標框架換成.Net Frameowrk 4.0 Client Profile, 它就正常了.

     


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。
    • 已標示為解答 weilin_ 2011年4月20日 上午 07:08
    2011年4月20日 上午 04:11
    版主
  • 使用 VS 2008 Express (C# / VB) 測試 會跟原發問者有相同狀況
    先查MSDN文件庫
    再用GOOGLE搜尋
    才到論壇來發問

    這是論壇不是技術支援中心
    沒有人得無償解答你的問題

    在標題或文章註明很急
    不會增加網友回覆速度
    2011年4月20日 上午 04:12
  • 謝謝兩位前輩的協助測試!

    我也使用VS 2010 express 後就像 Bill 前輩所述是正常可以從 textBox1 返回 dateTimePicker1,

    想請教有可能在不改變開發工具版本情況下改善這個問題嗎?

    目前可以想到的程式作法是透過 protected override void OnKeyPress(KeyPressEventArgs e)

    來抓使用者按下 Tab 鍵的時機再來判斷 if(textBox1.Focused) dateTimerPicker1.Focus();

    這樣的話是可以達到一樣的效果, 但是因為專案裡面需要這個功能的表單非常多, 每個表單開頭跟最後的控件也都不一定,

    所以想請問有沒有方法可以得知目前表單內 TabStop=true 且 TabIndex 為最大值(或最小值)的控件名稱呢? 謝謝!

    2011年4月20日 上午 05:30
  • Hi,

    參閱下面這篇看看有沒有幫助

    [新手問題]如何按enter鍵到下一個textBox

    http://social.msdn.microsoft.com/forums/zh-TW/233/thread/333c509e-b763-4de9-aa83-f817092ed027/


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    2011年4月20日 上午 05:52
  • Hi,

    參閱下面這篇看看有沒有幫助

     

    [新手問題]如何按enter鍵到下一個textBox

     

    http://social.msdn.microsoft.com/forums/zh-TW/233/thread/333c509e-b763-4de9-aa83-f817092ed027/


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    謝謝您的回應! 

    但以目前的例子執行下述程式時,

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
         if (e.KeyChar == 13)
         {
              this.SelectNextControl(splitContainer1.ActiveControl, true, true, true, true); //跳下一個元件
         }
    }

     還是會卡在最後一個控件(textBox1) @@


    2011年4月20日 上午 06:12
  • Hi,

    你搞錯我的用意了

    你提到了...

    "這樣的話是可以達到一樣的效果, 但是因為專案裡面需要這個功能的表單非常多, 每個表單開頭跟最後的控件也都不一定,

    所以想請問有沒有方法可以得知目前表單內 TabStop=true 且 TabIndex 為最大值(或最小值)的控件名稱呢? 謝謝!"

    會給你這篇是因為他可以Form的事件統一處理教點的移動~以ActiveControl偵測到當前焦點的控制項~~SelectNextControl可以控制往下一個焦點移動

    若要自己處理可能會能找出比較輕鬆的改法

    可能像是下面這樣去撰寫個方法~再透過迴圈或是搭配擴充方法輔助~將需要處理的表單事件繫上

            Dim oldControl As Control = SplitContainer1.ActiveControl
            SelectNextControl(SplitContainer1.ActiveControl, TrueTrueTrueTrue)
            If oldControl Is SplitContainer1.ActiveControl Then
                DateTimePicker1.Focus()
                oldControl = SplitContainer1.ActiveControl
            End If


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/
    • 已標示為解答 weilin_ 2011年4月20日 上午 07:08
    2011年4月20日 上午 06:53
  • 不好意思是我誤會了!

    謝謝前輩的舉例, 我來試試看! 非常感謝!

     

    2011年4月20日 上午 07:08
  • 最後參考蹂躪前輩的提示範例後修改部份如下:

     

        Control oldControl = splitContainer1.ActiveControl;
        SelectNextControl(splitContainer1.ActiveControl, true, true, true, true);
    
        if (oldControl == splitContainer1.ActiveControl)
        {
         Control firstControl = null;
         foreach(Control ctl in splitContainer1.Panel1.Controls )
         {
          if (ctl.TabStop)
          {
           if (firstControl == null)
           { firstControl = ctl; }
           else
           { if (firstControl.TabIndex > ctl.TabIndex) firstControl = ctl; }
          }
         }
         firstControl.Focus();
         oldControl = splitContainer1.ActiveControl;
        }
    

    謝謝!


    2011年4月20日 上午 07:42