- 題名: タブコントロールのタブの選択について
- 日時: 2005/01/12 14:26:54
- ID: 8361
- この記事の返信元:
- (なし)
- この記事への返信:
- [8364] Re[1]: タブコントロールのタブの選択について2005/01/12 18:41:22
- ツリーを表示
こんにちは、じゃんぬねっと です。 申し訳ありませんが、横槍しちゃいます。 ■No8381に返信(rikiさんの記事) > If msg.Msg = Me.WM_KEYDOWN Then > If keyData = Keys.Left Then > '移動できないTabIndex > If Me.canNotSelectTabIndex = Me.SelectedIndex Then > Return True > End If > End If > End If > Return False このコードですと、TabPage 内に属する子コントロールにフォーカスがある場合でも実行されちゃいますよね? 現在 Active なコントロールが、この TabControl であるという条件を入れないと (^-^;) > OnMouseUpとかで、選択されたTabControlのTabPageを座標から割り出して TabPage が決定されるのは、MouseUp ではないですね。 ちなみに、OnMouseDown だろうと OnMouseUp だとうと、 タイミングとしては既に遅いのです。(^-^;)
こんにちは、じゃんぬねっと です。
■No8383に返信(rikiさんの記事)
> あっ!本当ですね。すいません・・・(´・ω・`)ショボーン
嗚呼、気になさらないでくださいね。(^-^*)
ちなみに、Enabled プロパティを利用して、汎用性を高めるとこんなメソッドになりそうですね。
Source:--------------------------------------------------------------------
Private _iSelectedIndex As Integer = 0
Protected Overrides Function ProcessCmdKey(ByRef m As Message, ByVal keyData As Keys) As Boolean
Dim iTarget As Integer
Dim hParent As Form
Select Case keyData
Case Keys.Left
iTarget = Me.SelectedIndex - 1
If iTarget >= 0 Then
If IsCancelForDisable(iTarget) = True Then
Return True
End If
End If
Case Keys.Right
iTarget = Me.SelectedIndex + 1
If iTarget <= Me.TabPages.Count - 1 Then
If IsCancelForDisable(iTarget) = True Then
Return True
End If
End If
End Select
Return MyBase.ProcessCmdKey(m, keyData)
End Function
---------------------------------------------------------------------------
Private Function IsCancelForDisable(ByVal iTarget As Integer) As Boolean
Dim hParentForm As Form = Me.FindForm()
If hParentForm Is Nothing = False Then
If hParentForm.ActiveControl Is Me Then
Return Not Me.TabPages(iTarget).Enabled
End If
End If
End Function
---------------------------------------------------------------------------
> となると、WinProcとかPreProcessMessageで判断するのでしょうか?
> (ピンときませんが・・・)
s/WinProc/WndProc (^-^;)
ただ、WM_LBUTTON のメッセージをキャッチして、
GetChildAtPoint() メソッドを使っても、TabPage ではなく、
TabControl 自体が返ってきてしまいますのでご注意くださいね。
■No8361に返信(Snowさんの記事)
> タブを選択できないようにしたいのですが、できません。
そもそも、TabPage を無効にすればページ内すべてが無効になりますから、
わざわざ移動までさせなくする意味がわかりません。
ユーザーのアクセシビティも考えると、見ることはできた方が良いかと。
ですから、「Tabbed Dialog」より「TabControl」の方が、ユーザーフレンドリですね。
/***************************************************
* @Remarks じゃんぬねっと
* @Homepage http://f57.aaa.livedoor.jp/~jeanne/
* @Blog http://www.ailight.jp/blog/jeanne/
***************************************************/
#ちょっと今更かなぁと思いつつ(汗)
私もじゃんぬねっとさんが No8390 で仰った
> そもそも、TabPage を無効にすればページ内すべてが無効になりますから、
> わざわざ移動までさせなくする意味がわかりません。
と同意見です。移動させたくないなら非表示にしてしまったほうが良いのでは?とも思います。
‥‥が、それはそれとして。
> キー(←や→キー)での制御は要望通りに行くのですが
> マウスを使った場合が、どうすればよいかわかりません。
タブの切り替えは Ctrl ( + Shift ) + Tab キーでも行えますので、もし実装するのであれば
その備えも必要になるでしょう。また、 SelectedIndex もしくは SelectedTab を直接変更したときの
ことも考慮しておいたほうが良いかも知れません。
<そういうコーディングをしないのが確実であれば不要でしょうけど。
で、言いっぱなしもなんなので TabControl を継承したクラスを作成するという方向から考えてみました。
TabPage の Enabled が False になっているタブは選択できなくなっていると思います。
改善の余地は多分にありますが参考まで。
Public Class TabControlCustom
Inherits System.Windows.Forms.TabControl
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Dim index As Integer
Select Case m.Msg
Case &H130C 'TCM_SETCURSEL
If Not Me.TabPages(m.WParam.ToInt32()).Enabled Then Return
Case &H100 'WM_KEYDOWN
index = Me.SelectedIndex
If m.WParam.ToInt32() = &H25 Then 'VK_LEFT
index -= 1
If index < 0 Then Exit Select
ElseIf m.WParam.ToInt32() = &H27 Then 'VK_RIGHT
index += 1
If index >= Me.TabCount Then Exit Select
Else
Exit Select
End If
If Not Me.TabPages(index).Enabled Then Return
Case &H84 'WM_NCHITTEST
Dim p As Point = Me.PointToClient(New Point(m.LParam.ToInt32()))
For index = 0 To Me.TabCount - 1
If Me.GetTabRect(index).Contains(p) Then
If Me.TabPages(index).Enabled Then
m.Result = New IntPtr(1)
Return
Else
Exit For
End If
End If
Next
m.Result = New IntPtr(-1)
Return
End Select
MyBase.WndProc(m)
End Sub
'------------------------------------------
'以下蛇足:選択できないタブは表示も変わってたほうが良いかなぁと強引に
Public Sub New()
MyBase.New()
Me.DrawMode = TabDrawMode.OwnerDrawFixed
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
'こちらのサイトの Tips 『TabControlのタブを自分で描画する』のコードを
'ほぼそのまま流用させて頂いてます↓
'StringFormatを作成
Dim sf As New StringFormat()
'中央に表示する
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
'背景の描画
e.Graphics.FillRectangle(New SolidBrush(SystemColors.Control), e.Bounds)
'Textの描画
Dim tp As TabPage = Me.TabPages(e.Index)
Dim rectf As New RectangleF( _
e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)
Dim brush As Brush = New SolidBrush( _
IIf(tp.Enabled, SystemColors.WindowText, SystemColors.GrayText))
e.Graphics.DrawString(tp.Text, e.Font, brush, rectf, sf)
MyBase.OnDrawItem(e)
End Sub
End Class
分類:[.NET]
【解決したい問題】
タブコントロールについて質問です。
3つのタブをつくり処理を切り替えているのですが、
3つ目のタブを選択したとき2番目のタブを選択できないように
したいのですが、できません。
以前 VBでSSTab コントロールを使用していたときは、
SSTab1.TabEnable(1) = False
で使用できなくすることができました。
今回も同じように、
TabControl1.TabPages(1).Enable = False
としても変化なく選択できてしまいます。
選択できないようにすることは可能なのでしょうか?