- 題名: SelectTab後のフォーカス
- 日時: 2014/09/03 11:59:11
- ID: 32585
- この記事の返信元:
- (なし)
- この記事への返信:
- [32589] Re[1]: SelectTab後のフォーカス2014/09/04 17:26:26
- [32592] Re[1]: SelectTab後のフォーカス2014/09/05 15:35:40
- ツリーを表示
■No32585に返信(おまつさんの記事) > TabControl のページを SelectTab や SelectedIndex で変更した場合、そのページ内のコントロールにフォーカスが移動してしまいます。 > フォーカスを移動させずにページのみ変更させる方法はないのでしょうか? タブを切り替える前に、ページ上のコントロール群の TabStop あるいは Enabled を False にしておき、 切り替えた後で、それらを復元することで対応できないでしょうか。 実験的に、『PabPage3.Activate()』の形式で利用可能な 拡張メソッドを用意してみました。 Module TabControlExtension <System.Runtime.CompilerServices.Extension()> _ Public Sub Activate(page As TabPage) For Each c In page.Controls.OfType(Of Control)() c.Tag = c.TabStop c.TabStop = False Next DirectCast(page.Parent, TabControl).SelectTab(page) For Each c In page.Controls.OfType(Of Control)() If TypeOf c.Tag Is Boolean Then c.TabStop = CBool(c.Tag) End If Next End Sub End Module
■No32592に追記(魔界の仮面弁士の記事) > c.Tag = c.TabStop 手抜きで Tag プロパティに管理させてしまいましたが、これだと Tag プロパティを別の目的で使っている場合に競合しますね…。 ということで修正版。 TabStop の一時保存先を、そのコントロールの Tag プロパティに 置いておくのではなく、ローカル変数(Dictionary)に溜め込むように 修正してみました。 <System.Runtime.CompilerServices.Extension()> _ Public Sub Activate(page As TabPage) Dim cache As New Dictionary(Of Control, Boolean)() For Each c As Control In page.Controls cache(c) = c.TabStop c.TabStop = False Next DirectCast(page.Parent, TabControl).SelectTab(page) For Each x In cache x.Key.TabStop = x.Value Next End Sub 提示のサンプルでは、拡張メソッドを TabPage 側に追加していますが、 もしも使いにくいようであれば TabControl 側に実装してみてください。 思いつきで組んだだけで、さほどテストはしていません。 一応、手元の環境では TabPage 直下のコントロールに対する TabStop だけでうまく切り替えられているように見えますが、 もしもそれでは不足だった場合には、Enabled を使うなど、 適宜調整してみてください。 -- 以下余談 -- 今回の処理は元々、Selecting / Selected イベントで処理させようと したのですが、コードで TabPage を切りかえた場合は、このイベントが 発生しなかったため、ページ切替処理ごと作りこむ実装としています。 そこでまずは、継承して作りこみはじめたのですが、残念ながら SelectTab メソッドは Overridable では無かったので、実装しようにも シャドウイングするか、別メソッドにするしかありませんでした。 で、どうせ別メソッドにするなら、継承せずとも拡張メソッドで 十分だろうということで、今回の形にしています。
分類:[.NET]
TabControl のページを SelectTab や SelectedIndex で変更した場合、そのページ内のコントロールにフォーカスが移動してしまいます。
フォーカスを移動させずにページのみ変更させる方法はないのでしょうか?