マウスクリック時にTextBoxの文字列反転表示をするには?

解決


K4R  2005-01-31 20:35:43  No: 119292

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

すいませんが、よろしくお願いします。


じゃんぬねっと  URL  2005-01-31 21:41:32  No: 119293

全く同じ質問が過去にありました。


K4R  2005-02-01 00:40:43  No: 119294

質問する前に、「反転」で検索して、TextBoxの文字列反転表示に関する質問はいくつかあったのは
確認したのですが、同じものは見つからなかったので質問しました。

すいませんです。もう少しキーワードを変えて検索してみます。


K4R  2005-02-01 04:24:13  No: 119295

「TextBox」「テキストボックス」で検索して全てチェックしましたが、やはり同じ質問はないです。
似ているものはいくつもありますが「全く同じ」は見当たらないです・・・見落としですかね〜。

私の質問の重点は「VB.NET」でテキストボックスを「マウスクリック時」に反転表示です。
(よくあるVBの反転表示(GotFocusイベントで.SelStart〜length)のベタ移植ではVB.NETだと
  期待した動きにはなりませんので)

すいませんが、該当スレが解る人、または上記の問題が解る人はお教え願えますでしょうか。


特攻隊長まるるう  2005-02-02 01:59:05  No: 119296

う〜ん。ボクも過去ログではよく分からなかったのですが、
…どうしよう。とりあえず丸付き数字は機種依存なので置き換えます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 イベントのみで処理できるんじゃないかと。


じゃんぬねっと  URL  2005-02-02 02:32:26  No: 119297

じゃんぬねっと です。

今回の仕様は、そもそもお勧めできないんですよね。
マウスで選択した時にも、全選択する 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() イベントを使わないでください。


K4R  2005-02-02 04:31:46  No: 119298

いろいろ有難うございます。参考になりました。

VB版のシステムのベタ移植を行っているので、VB版と同じように(最初の発言の(1)(2)の動き)に
するにはどうすればいいか解らなかったので質問させて頂きました。

カスタムコントロール作成に消極的だったのは、画面数が膨大に多すぎて全てのコントロールを貼り
変えるとなってしまうと修正の許可が下りないかもしれないからという理由でしたが、やはり
カスタムコントロールを作るのが一番良い方法みたいですね。

タイマーイベント or Tagプロパティを使用してみます。また、LostFocus() イベントのご忠告有難う
ございました。


特攻隊長まるるう  2005-02-02 18:17:39  No: 119299

>カスタムコントロールを作るのが一番良い方法みたいですね。
いや、そんな事は言ってませんが…。オブジェクト指向と[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


特攻隊長まるるう  2005-02-02 18:22:35  No: 119300

…あ、案2の
        TextBoxX.SelectAll() 'キーボード Enter 対応
イラナイや…(汗)


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加