- 題名: 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 で変更した場合、そのページ内のコントロールにフォーカスが移動してしまいます。
フォーカスを移動させずにページのみ変更させる方法はないのでしょうか?