自作ContextMenuStrip
自作ContextMenuStripを自作する機会があり、
上のメニューから
元に戻す、切り取り、コピー、貼り付け、削除、すべて選択
を実装したContextMenuStripを作成した。
参考:TextBox(またはRichTextBox)でコピー、切り取り、貼り付け、元に戻すを行う: .NET Tips: C#, VB.NET
から「元に戻す、切り取り、コピー、貼り付け」をそのまま使用。
削除、すべて選択は以下。
'削除
Private Sub deleteMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles deleteMenu.Click
TextBox1.Text = TextBox1.Text.Remove(TextBox1.SelectionStart,TextBox1.SelectionLength)
End Sub
’すべて選択
Private Sub selectMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles selectMenu.Click
TextBox1.SelectAll()
End Sub
これをテキストボックス上で使うとき、
まず、マウスダウンイベントで、標準のContextMenuを使えなくし、
今回作ったContextMenuStrip(cmsDisp)を使用する。
Private Sub TextBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseDown
Dim mp As Point
If e.Button = Windows.Forms.MouseButtons.Right Then
'右クリックコントロール外、無効処理
TextBox1.Capture = False
TextBox1.ContextMenuStrip = cmsDisp
mp = Windows.Forms.Control.MousePosition
'ContextMenuStripをマウスカーソルの位置に表示
Me.cmsDisp.Show(mp)
If TextBox1.Text.Length = 0 Then
MenuEnabled(EnableMode.StrNo)
ElseIf TextBox1.SelectionLength = 0 Then
Call MenuEnabled(EnableMode.SelectNo)
ElseIf TextBox1.SelectionLength = TextBox1.Text.Length Then
Call MenuEnabled(EnableMode.SelectAll)
ElseIf TextBox1.SelectionLength > 0 Then
Call MenuEnabled(EnableMode.Normal)
End If
End If
End Sub
「TextBox1.Capture = False」は
テキストフィールド上で右クリックして、テキストフィールド外で
右クリックを離したときに標準のContextMenuが表示されるのを防いだもの。
最初、このミスに気付かなかったので、危なかった。
MenuEnabledでContextMenuStripのメニューの選択可否を切り替える
以下の変数はあらかじめ宣言済みとする。
Enum EnableMode
StrNo = 0 '文字列無し
SelectNo = 1 '選択文字列無し
SelectAll = 2 '文字列戦選択
Normal = 3 '文字列選択あり
End Enum
Private Sub MenuEnabled(ByVal strEnable As EnableMode)
Dim data As IDataObject
'テキストボックスの文字列の状態から
'ContextMenuのメニュー表示切替を行う
Select Case strEnable
Case EnableMode.StrNo
'文字列なし
cutMenu.Enabled = False
copyMenu.Enabled = False
deleteMenu.Enabled = False
selectMenu.Enabled = False
Case EnableMode.SelectNo
'文字列あり、選択なし
cutMenu.Enabled = False
copyMenu.Enabled = False
deleteMenu.Enabled = False
selectMenu.Enabled = True
Case EnableMode.SelectAll
'文字列全選択
cutMenu.Enabled = True
copyMenu.Enabled = True
deleteMenu.Enabled = True
selectMenu.Enabled = False
Case EnableMode.Normal
'文字列あり、選択有り(全て選択していない)
cutMenu.Enabled = True
copyMenu.Enabled = True
deleteMenu.Enabled = True
selectMenu.Enabled = True
End Select
If TextBox1.CanUndo = True Then
'元に戻すことができるか調べる
undoMenu.Enabled = True
Else
undoMenu.Enabled = False
End If
data = Clipboard.GetDataObject()
If (IsNothing(data) = False) AndAlso (data.GetDataPresent(DataFormats.Text) = True) Then
'クリップボードにテキストデータがあるときは貼り付けメニュー有効
pasteMenu.Enabled = True
Else
pasteMenu.Enabled = False
End If
End Sub
(上の処理にReadOnly時の時の処理も必要・今回は省略)