2011年2月9日水曜日

【VB.NET】Formの自動TabIndex設定

フォームのコントロールのタブインデックス設定は結構面倒です。
自分的には決まり切った規則があるにも関わらず、
同じ作業の繰り返しなのでかなり面倒です。

決まり切った規則とは以下の通りです。
-----------------------------------------------------
第1条件 Top値の少ないコントロール
第2条件 Left値の少ないコントロール
※子コントロールを持つコントロールは内部も設定する
-----------------------------------------------------
この並び順でTabIndexを自動で設定してあげれば解決するんでないの、ということです。

ということで、以下の関数とプロパティを作成しました。
継承元のFormに設置してみてください。

  1. #Region "自動タブインデックス設定"  
  2.   
  3.     Private _SetAutoTabIndex As Boolean  
  4.     <System.ComponentModel.Category("追加プロパティ")> _  
  5.     <System.ComponentModel.DefaultValue(GetType(Boolean), "False")> _  
  6.     <System.ComponentModel.Description("Trueにすると画面の全コントロールのタブインデックスを自動で設定します。")> _  
  7.     Public Property SetAutoTabIndex() As Boolean  
  8.         Get  
  9.             Return _SetAutoTabIndex  
  10.         End Get  
  11.         Set(ByVal value As Boolean)  
  12.             _SetAutoTabIndex = value  
  13.             If _SetAutoTabIndex Then  
  14.                 Dim UpdateCount As Integer  
  15.                 UpdateCount = SettingAutoTabIndex(Me)  
  16.                 MessageBox.Show(UpdateCount & "件のタブインデックスを自動設定しました。""自動設定", MessageBoxButtons.OK, MessageBoxIcon.Information)  
  17.                 _SetAutoTabIndex = False  
  18.             End If  
  19.         End Set  
  20.     End Property  
  21.   
  22.   
  23.     ''' <summary>  
  24.     ''' タブインデックスを自動で設定します。  
  25.     ''' </summary>  
  26.     ''' <param name="ControlsInObject">引数で渡されたコントロール(省略した場合はフォーム)</param>  
  27.     ''' <remarks></remarks>  
  28.     Public Function SettingAutoTabIndex(Optional ByVal ControlsInObject As Control = NothingAs Integer  
  29.         If ControlsInObject Is Nothing Then  
  30.             ControlsInObject = Me  
  31.         End If  
  32.         Dim UpdateCount As Integer = 0  
  33.         Dim sl As New System.Collections.SortedList()  
  34.   
  35.         ' ポジションが左上に近いコントロールから順にタブインデックスを設定する.優先順位は上、左の順  
  36.         For Each Ctrl As Control In ControlsInObject.Controls  
  37.             Try  
  38.                 Select Case True  
  39.                     ' 子コントロールを持てるコントロール(タブ、パネル、グループボックス...)  
  40.                     Case HasChildControls(Ctrl)  
  41.                         sl.Add(Ctrl.Top.ToString.PadLeft(10, "0") & Ctrl.Left.ToString.PadLeft(10, "0"), Ctrl)  
  42.                         UpdateCount += SettingAutoTabIndex(Ctrl)  
  43.   
  44.                     Case Else  
  45.                         sl.Add(Ctrl.Top.ToString.PadLeft(10, "0") & Ctrl.Left.ToString.PadLeft(10, "0"), Ctrl)  
  46.   
  47.                 End Select  
  48.             Catch ex As Exception  
  49.   
  50.             End Try  
  51.         Next Ctrl  
  52.         ' タブインデックスを設定する  
  53.         For Idx As Integer = 0 To sl.Count - 1  
  54.             If CType(sl.GetByIndex(Idx), Control).TabIndex <> Idx Then  
  55.                 CType(sl.GetByIndex(Idx), Control).TabIndex = Idx  
  56.                 UpdateCount += 1  
  57.             End If  
  58.         Next Idx  
  59.   
  60.         Return UpdateCount  
  61.     End Function  
  62. #End Region  
  63. #Region "子コントロールを持てるコントロールかどうかチェック"  
  64.     ''' <summary>  
  65.     ''' 子コントロールを持てるコントロールかどうかチェック  
  66.     ''' </summary>  
  67.     ''' <param name="Ctrl"></param>  
  68.     ''' <returns></returns>  
  69.     ''' <remarks>子コントロールを持てる場合、True。持てない場合、False</remarks>  
  70.     Public Function HasChildControls(ByVal Ctrl As Control) As Boolean  
  71.         Select Case True  
  72.             Case TypeOf Ctrl Is Panel, TypeOf Ctrl Is GroupBox, TypeOf Ctrl Is TabControl, TypeOf Ctrl Is UserControl  
  73.                 Return True  
  74.             Case Else  
  75.                 Return False  
  76.         End Select  
  77.     End Function  
  78. #End Region  

-----------------------------------------------------
・SettingAutoTabIndex
タブインデックスを設定します。引数としてGroupBoxなど渡せばその内部のみTabIndexを設定します。

・HasChildControls
子コントロールを持っているコントロールかどうかチェックします。

・SetAutoTabIndex
プロパティとして実装しました。Booleanで持っていることに特に意味はありませんが、
Trueにしてみるとタブインデックスを自動設定し、Falseに戻ります。
(本当はプロパティグリッドにボタンを置きたいです)
-----------------------------------------------------



FormのSetAutoTabIndex のプロパティをいじくるだけで自動でタブインデックスがデザイナ上で設定します。

0 件のコメント:

コメントを投稿