VB.NETでTextBoxをマウスクリックした時に文字列を反転表示させる方法が解りません。
ちなみに以下のような動作をするのが理想です。
①1回目のクリック時は文字列反転表示
②2回目のクリック時はクリックした文字の箇所にカーソルが移動して、その箇所から文字列が編集可能
Enterイベントで.SelectAllを使用しても反応がありませんでした。
MouseDownイベントで.SelectAllを使用すると一応文字列が反転表示されますが、クリック
する度に必ず反応表示してしまい、②の動作が実現しません。
ちなみに、以下のようにフラグで制御すると理想の動きにはなるのですがあまり綺麗ではない気がします。。。
(そういうカスタムコントロールを作成すればいいんですが、、、)
もっとスマートな方法がありませんでしょうか?
'反転表示フラグ作成
Private blnSelectAll As Boolean = False
'マウスクリック時反転表示&反転表示フラグON
Private Sub TextBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox.MouseDown
If Not blnSelectAll Then
TextBox.SelectAll()
blnSelectAll = True
End If
End Sub
'フォーカスを失った時に反転表示フラグOFF
Private Sub TextBox_LostFocus(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox.LostFocus
blnSelectAll = False
End Sub
すいませんが、よろしくお願いします。
全く同じ質問が過去にありました。
質問する前に、「反転」で検索して、TextBoxの文字列反転表示に関する質問はいくつかあったのは
確認したのですが、同じものは見つからなかったので質問しました。
すいませんです。もう少しキーワードを変えて検索してみます。
「TextBox」「テキストボックス」で検索して全てチェックしましたが、やはり同じ質問はないです。
似ているものはいくつもありますが「全く同じ」は見当たらないです・・・見落としですかね〜。
私の質問の重点は「VB.NET」でテキストボックスを「マウスクリック時」に反転表示です。
(よくあるVBの反転表示(GotFocusイベントで.SelStart〜length)のベタ移植ではVB.NETだと
期待した動きにはなりませんので)
すいませんが、該当スレが解る人、または上記の問題が解る人はお教え願えますでしょうか。
う〜ん。ボクも過去ログではよく分からなかったのですが、
…どうしよう。とりあえず丸付き数字は機種依存なので置き換えますw(質問に関係ない。
>(1)1回目のクリック時は文字列反転表示
>(2)2回目のクリック時はクリックした文字の箇所にカーソルが移動して、その箇所から文字列が編集可能
まず最初に、原因が何かは分かってるのかな?各イベントに
Debug.WriteLine("TextBox1_Enter")
とか書いてちゃんとデバッグしてみて下さい。分かるはずですよ?
>Enterイベントで.SelectAllを使用しても反応がありませんでした。
…なんて事はウソで、イベントの発生する順番が原因みたい。
Enter
GotFocus
MouseDown
の順で発生するから Enter や GotFocus で全選択しても MouseDown
でカーソル位置が変更されて終了ーなだけだねぇ。
で、MouseDown に限って言えば(2)の処理と全く同じだからこの中だけ
で判別して処理を分岐するのは難しいのかも(?)
ボクがやるとしたら Enter イベントからタイマー使って MouseDown の
後で全選択処理を入れるかなぁ?…まぁ、引数にテキストボックス
渡しのクラス化を考えます。フラグでの処理でもいいと思います。ただ、
モジュールレベルの変数にはしません。下手するとテキストボックスの
数だけ用意しないといけなくなりますから。でもクラス化はカスタム
コントロールを作成するのと根本的な考え方が同じだと思います…。
>(そういうカスタムコントロールを作成すればいいんですが、、、)
何か不満がありそうなので没ですかね。今のところ思い付いた処理は
2つ以上のイベントが関係してしまうので Enter イベントのみに
関数呼び出しを書くとして、すっきり書くにはクラス化必須ですねぇ。
案外 TextBox1.Tag にフラグ設定するのが一番簡単かも?。Enter と
MouseDown イベントのみで処理できるんじゃないかと。
じゃんぬねっと です。
今回の仕様は、そもそもお勧めできないんですよね。
マウスで選択した時にも、全選択する TextBox は、
Windows 内のどこを探してもありませんから。
(Tab で移動した時だけ、全選択)
# ユーザーのアクセシビリティ的にも如何なものでしょう?
# きっと「マウスでクリックした位置をすぐ編集可能させろ!!」なんて思います。
ということで、私はフォーカス取得系のイベントが厳格になって喜んでる人間です。
http://f57.aaa.livedoor.jp/~jeanne/tips/textbox/06-onselectall.html#vb6
それはそれとして、これと逆のことをやってあげるわけですが...
問題は、現在のフォーカス中の TextBox がクリックした TextBox と同一なら、
全選択にしないという処理を入れるのが面倒なのですよね。
カスタム コントロール内で、FindForm().ActiveControl 何かを使って
親を意識しなきゃいけないような作りになってしまいます。
それと、
> Private Sub TextBox_LostFocus(...) Handles TextBox.LostFocus
VB.NET では 低水準イベントである LostFocus() イベントを使わないでください。
いろいろ有難うございます。参考になりました。
VB版のシステムのベタ移植を行っているので、VB版と同じように(最初の発言の(1)(2)の動き)に
するにはどうすればいいか解らなかったので質問させて頂きました。
カスタムコントロール作成に消極的だったのは、画面数が膨大に多すぎて全てのコントロールを貼り
変えるとなってしまうと修正の許可が下りないかもしれないからという理由でしたが、やはり
カスタムコントロールを作るのが一番良い方法みたいですね。
タイマーイベント or Tagプロパティを使用してみます。また、LostFocus() イベントのご忠告有難う
ございました。
>カスタムコントロールを作るのが一番良い方法みたいですね。
いや、そんな事は言ってませんが…。オブジェクト指向と[VB.NET]
の構造にまだ十分な知識をお持ちでないからでしょうが、クラス
という単位で考える必要があります。この場合、カスタムコント
ロールも、フォームもクラスなのです。ユーザ定義のカスタム
コントロールを作るのに何か問題がある場合、普通にクラス化
する…つまりユーザ定義のクラスを作るのにも問題がある可能性
が高い…というか同じ意味だと言ったのです。まぁ、それが
ダメとか言われるとオブジェクト指向そのものがダメな感じも
しますが。
クラス化はただクラスを作るだけなのでデザイン画面に影響する
場合はまずありませんが?…というか影響するように書かなければ
良いだけの話です。
案1:Tag にフラグ設定型
[VB.NET]
Private Sub TextBox1_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Enter
Debug.WriteLine("TextBox1_Enter")
TextBox1.Tag = True
End Sub
Private Sub TextBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseDown
Debug.WriteLine("TextBox1_MouseDown")
If CBool(TextBox1.Tag) Then
TextBox1.SelectAll()
TextBox1.Tag = False
End If
End Sub
案1(共通関数化)
[VB.NET]
Private Sub TextBox1_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Enter
Call Me.SetTextBoxSelectAll(DirectCast(sender, TextBox))
End Sub
Private Sub TextBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox1.MouseDown
Call Me.CheckTextBoxSelectAll(DirectCast(sender, TextBox))
End Sub
Public Sub SetTextBoxSelectAll(ByVal TextBoxX As TextBox)
With TextBoxX
.Tag = True
.SelectAll() 'キーボード Enter 対応
End With
End Sub
Public Sub CheckTextBoxSelectAll(ByVal TextBoxX As TextBox)
With TextBoxX
If CBool(.Tag) Then
.SelectAll()
.Tag = False
End If
End With
End Sub
案2:Timer 使用クラス呼び出し型
[VB.NET]
Option Strict On
Public Class Form1
Inherits System.Windows.Forms.Form
[省略]" Windows フォーム デザイナで生成されたコード "
Private Sub TextBox1_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Enter
Debug.WriteLine("TextBox1_Enter")
Call Me.TextBoxSelectAll(DirectCast(sender, TextBox))
End Sub
Private Sub TextBoxSelectAll(ByVal TextBoxX As TextBox)
Dim wEventClass As New TextBoxEventClass(TextBoxX)
TextBoxX.SelectAll() 'キーボード Enter 対応
Call wEventClass.SelectAllTimerRun()
End Sub
End Class
Public Class TextBoxEventClass
Private mTextBox As TextBox
Private WithEvents mTimer As New Timer
'Public Event GotFocus(ByVal TextBoxX As TextBox)
Public Sub New(ByVal TextBoxX As TextBox)
Me.mTextBox = TextBoxX
'Call Me.SelectAllTimerRun()
End Sub
Public Sub SelectAllTimerRun()
With Me.mTimer
.Interval = 1
.Start()
End With
End Sub
Private Sub mTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles mTimer.Tick
Me.mTimer.Stop()
Debug.WriteLine("mTimer_Tick")
Me.mTextBox.SelectAll()
End Sub
End Class
…あ、案2の
TextBoxX.SelectAll() 'キーボード Enter 対応
イラナイや…(汗)
ツイート | ![]() |