- PR -

ComboBoxの文字列が選択状態に

投稿者投稿内容
さくら
常連さん
会議室デビュー日: 2005/09/12
投稿数: 31
投稿日時: 2005-11-02 14:01
ComboBox.TextがComboBox.Itemsに含まれる文字列と同じだった場合、EnabledのTrue/Falseを切り替えた瞬間に文字列が選択状態になる現象に悩まされています。

<再現方法>
フォームにComboBoxを2つ置き、両方に
aaa
bbb
ccc
などとItemsの文字列を設定し、ボタンのクリックで

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ComboBox1.TabStop = Not ComboBox1.TabStop
ComboBox2.TabStop = Not ComboBox2.TabStop
End Sub

としてComboのEnabledが切り替わるようにしておきます。
実行して、片方のComboはTextを空かリストにない文字列を適当に入力し、もう片方は「aaa」をリストから選択するか手入力した状態でボタンをクリックします。

そうすると、「aaa」と選択したほうのComboのTextが全て選択状態になってしまうのです。
両方のComboでリストにある文字列を選んだ状態だと、両方のComboの文字列がSelectAll状態になり、困っています。
実際にはフォーム上にはもっとたくさんComboがあるので、大変なことになります…

Webで探してみたのですが同じような事例が見つかりませんでした。
どなたかこういうケースをご存知ではないでしょうか?
何か環境が悪かったりするのでしょうか?

使用しているのはVB.Net、WindowsXP Proです。

[ メッセージ編集済み 編集者: さくら 編集日時 2005-11-02 14:01 ]

[ メッセージ編集済み 編集者: さくら 編集日時 2005-11-02 14:09 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-02 14:20
引用:

さくらさんの書き込み (2005-11-02 14:01) より:

コード:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    ComboBox1.TabStop = Not ComboBox1.TabStop
    ComboBox2.TabStop = Not ComboBox2.TabStop
End Sub


としてComboのEnabledが切り替わるようにしておきます。


このコードに "Enabled" プロパティが変更される余地なんてないと思います...
多分、書き間違えですよね? (TabStopChanged イベントで、何てこともないと思いますし)

TabStop を False にした場合は、この現象は再現すると思います。
回避方法としては、TabStop が変わる前に別にフォーカスを移すことです。
ActiveControl に Null を設定しておいても良いでしょう。

コード:

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click    
        Me.ActiveControl = Nothing
        Me.ComboBox1.TabStop = Not Me.ComboBox1.TabStop
        Me.ComboBox2.TabStop = Not Me.ComboBox2.TabStop
    End Sub


引用:

Webで探してみたのですが同じような事例が見つかりませんでした。
どなたかこういうケースをご存知ではないでしょうか?


同じような事例とは言えないですが、Focus メソッド以外のフォーカス遷移などで起こることを確認しています。
要するに、フォーカスを抜けたというコトがうまく伝わってない時に起きるようです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
さくら
常連さん
会議室デビュー日: 2005/09/12
投稿数: 31
投稿日時: 2005-11-02 15:26
じゃんぬねっとさん、お世話になります。

引用:

じゃんぬねっとさんの書き込み (2005-11-02 14:20) より:
多分、書き間違えですよね? (TabStopChanged イベントで、何てこともないと思いますし)


ありゃ、そうでした。失礼いたしました。
ご指摘の通り、TabStopの切り替えのことです。

引用:

TabStop を False にした場合は、この現象は再現すると思います。
回避方法としては、TabStop が変わる前に別にフォーカスを移すことです。
ActiveControl に Null を設定しておいても良いでしょう。


アドバイスありがとうございます。
ActiveControl=Nothingだと何故かうまくいかなかったので、とりあえずの回避策ですがTabStopを切り替えた後に
ComboBox1.SelectionLength = 0
で明示的に選択を解除してやることにしました。(面倒ですが…)

引用:

同じような事例とは言えないですが、Focus メソッド以外のフォーカス遷移などで起こることを確認しています。
要するに、フォーカスを抜けたというコトがうまく伝わってない時に起きるようです。


なるほど、だから選択されてしまうんですね。
追加情報ですが、ComboBox.DropDownStyle=DropDownのときにだけこの現象が起こるようです。
FocusedはFalseなのに、どこかで「フォーカスを持ってる」と思い込んでいるんでしょうか…

ともあれ、他に似た事例の方がいらしてちょっと安心しました。
今回はSelectionLengthで逃げますが、余力があればもう少し追ってみたいです。
どうもありがとうございました。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-02 15:49
引用:

さくらさんの書き込み (2005-11-02 15:26) より:

ComboBox1.SelectionLength = 0
で明示的に選択を解除してやることにしました。(面倒ですが…)


それだと、TabStopChanged イベントで実装してみるとかくらいしか回避できないですね。

引用:

追加情報ですが、ComboBox.DropDownStyle=DropDownのときにだけこの現象が起こるようです。


そうみたいですね。

引用:

ともあれ、他に似た事例の方がいらしてちょっと安心しました。
今回はSelectionLengthで逃げますが、余力があればもう少し追ってみたいです。
どうもありがとうございました。


そもそも、TabStop プロパティで動的にフォーカス制御するのは、あまり好ましくないと思っています。
実行時に 1 度だけ決められるプロパティであるべきだと思っています。

勝手な予想ですが、Enabled = False だとグレーダウンしてしまうので、
ReadOnly な ComboBox があればなぁ... といったところではないですか?
そうであれば、やれないことはないです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
さくら
常連さん
会議室デビュー日: 2005/09/12
投稿数: 31
投稿日時: 2005-11-02 16:49
引用:

じゃんぬねっとさんの書き込み (2005-11-02 15:49) より:

勝手な予想ですが、Enabled = False だとグレーダウンしてしまうので、
ReadOnly な ComboBox があればなぁ... といったところではないですか?
そうであれば、やれないことはないです。


はい、お察しの通りです。
データの状態によって編集可否の項目が決まるところがあるためComboBoxを触れたり触れなかったりの切り替えをしたいのですが、Enabled = Falseはグレーダウンしてしまうので、先の方法になりました。
ReadOnlyライクな挙動、できるものなのですか?
ポインタだけでも結構ですので、教えていただけると嬉しいです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-02 17:07
引用:

さくらさんの書き込み (2005-11-02 16:49) より:

ReadOnlyライクな挙動、できるものなのですか?
ポインタだけでも結構ですので、教えていただけると嬉しいです。


安易な方法としては、
ComboBox を継承したコントロール (RoComboBox とします) を作ります。
その RoComboBox は ReadOnly プロパティを実装しています。
次に、Form の DefaultUpdateButton メソッドをオーバーライドし、
ActiveControl の変化を捕捉し、ActiveControl が RoComboBox でかつ、
ReadOnly であったら直前のコントロールへ戻すという処理を加えます。
もちろん、直前のコントロールは UpdateDefaultButton メソッドで毎回更新します。

他にも色んな方法があります。
この方法の弱点は、ComboBox で実装されているプロパティが、Form の挙動に依存していることですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ぼのぼの
ぬし
会議室デビュー日: 2004/09/16
投稿数: 544
投稿日時: 2005-11-02 17:36
こんにちは。更に安易な方法ですが。

引用:

追加情報ですが、ComboBox.DropDownStyle=DropDownのときにだけこの現象が起こるようです。


ってことですので、DropDownStyleを動的に切り替えちゃえば良いのでは?

更に

引用:

さくらさんの書き込み (2005-11-02 16:49) より:
引用:

じゃんぬねっとさんの書き込み (2005-11-02 15:49) より:

勝手な予想ですが、Enabled = False だとグレーダウンしてしまうので、
ReadOnly な ComboBox があればなぁ... といったところではないですか?
そうであれば、やれないことはないです。


はい、お察しの通りです。



ってことですが、以下のようにすればReadOnlyライクにならんですか?

コード:

ComboBox1.Items.Clear()
ComboBox1.Items.Add("aaa")
ComboBox1.Text = "aaa"
ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
ComboBox1.SelectionLength = 0

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-11-02 17:56
引用:

ぼのぼのさんの書き込み (2005-11-02 17:36) より:

ってことですが、以下のようにすればReadOnlyライクにならんですか?


TextBox に倣うと DropDown をしないようにする工夫が要りますよね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

スキルアップ/キャリアアップ(JOB@IT)