ComboBoxを読み取り専用にして、表示を見られるようにしたい [コントロール]
----------------------------------------------------------
(開発・実行環境)
Microsoft Visual Studio 2005 Tools for Applications
Microsoft Visual Basic 2005
----------------------------------------------------------
取得したデータをComboBoxに表示したいけど変更はかけたくない。
要はReadOnly=Trueな状態にしたい。
でもReadOnlyプロパティは無いし、Enabled=Falseにしたら文字読みにくいし。。
ってわけで先輩が素敵な関数(イベントのサブルーチン)を与えてくれた♪
ComboBoxをEnabled=Falseのときに、ComboBox内の要素を指定した色に描画してくれるイベント。
Private Sub cboAssetsDiv_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles cboAssetsDiv.DrawItem
If Me.cboAssetsDiv.Enabled = True Then
'Me.cboAssetsDiv.DrawMode = DrawMode.Normal
Exit Sub
End If
'背景を描画する
'項目が選択されている時は強調表示される
e.DrawBackground()
Dim cmb As ComboBox = CType(sender, ComboBox)
'項目に表示する文字列
Dim txt As String
If cmb.FindString(cmb.Text) < 0 Then
cmb.Items.Add(cmb.Text)
'cmb.Items.Add(dt)
cmb.DropDownStyle = ComboBoxStyle.DropDown
End If
txt = cmb.Text
'使用するブラシ
Dim b As Brush = New SolidBrush(SET_COLOR)
'文字列を描画する
Dim ym As Single = (e.Bounds.Height - _
e.Graphics.MeasureString(txt, cmb.Font).Height) / 2
e.Graphics.DrawString(txt, cmb.Font, b, _
e.Bounds.X, e.Bounds.Y + ym)
b.Dispose()
End Sub
SET_COLORに文字色をセット。
DrawItemイベントは、DrawModeプロパティがNormalじゃないときに発生する。(デフォルトはNormal)
制御したいタイミングで、Enabled と DrawMode を切り替えて、上記のDrawItemイベントを走らせることで、表題の件を実現できるかと。
Enabled=Trueでは走らないようにしましょう。面白いことになるから・・・w
まぁ、ここまですんの?って感じだけど。
ComboBoxの読み取り専用制御、色々やり方はあるかと思いますが、一つありがたいソースをGet。
TextBox に数字しか入力できないようにしたい ~AddHandlerでイベント追加~ [コントロール]
----------------------------------------------------------
(開発・実行環境)
Microsoft Visual Studio 2005 Tools for Applications
Microsoft Visual Basic 2005
----------------------------------------------------------
DBのデータ型が数値型なのに、文字列が入力できたり、数値で集計するデータに文字列が入るとマズいわけで。
TextBoxに数字以外の入力制限をかけたいわけです。
TextBoxのKeyPress イベントにて、
数値であるか否か
http://jeanne.wankuma.com/tips/vb.net/char/isdigit.html
制御文字であるか否か(EnterとかTabとか)
を判断し、数値と制御文字でなければ、処理をキャンセルします。
以下、ソース。
If (Not (Char.IsDigit(e.KeyChar) _
Or Char.IsControl(e.KeyChar) _
Or (e.KeyChar = Chr(46)))) Then
e.Handled = True
End If
chr(46)は「.」。
http://higasumi.blog100.fc2.com/blog-category-17.html
今回は整数だけど、小数点使うなら、
「.」が文字の中に存在するか否か(二個以上「.」を出したくない)
先頭が「.」じゃないか
の制御も必要になってきますね。
e.Handled = True で、イベントのキャンセル。
http://d.hatena.ne.jp/annin102/20070303/1172936508
さて、実装。
自分、今までは作業をするたびにイベントを実行していたのですが。。。
イベントプロシージャのHandles以下を消去してあげる。
Private Sub TextBox_KeyPress( _
ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.KeyPressEventArgs)
こいつを、AddHandlerステートメントをFormのLoadイベント等で追加してあげる。
AddHandler TextBox1.KeyPress, AddressOf TextBox_KeyPress
こうすると、Load時にイベントプロシージャを通るだけで、イベントごとにいちいち処理を通さない。
なんかよさげ☆
(追記:勘違いだったっぽい。。普通のサブルーチンと同じような扱い方ができる、ってメリットがあるかな。)
そして、AddHandlerステートメントを呼び出す関数をグローバルで(共通モジュール等で)もってあげれば、
イベントをグローバル(共通)関数として、色んな場所から同じ処理を呼んであげられる。
今までイベントは全部ローカルでやっていたので。。。
これからはもう少しサクサク作れるようになるぞぃ♪
以下、参考。
http://dobon.net/vb/dotnet/beginner/eventhandle.html
こんなんもあったけど、はてさて。。。?
http://dobon.net/vb/dotnet/control/numerictextbox.html
FormとDialog [コントロール]
----------------------------------------------------------
(開発・実行環境)
Microsoft Visual Studio 2005 Tools for Applications
Microsoft Visual Basic 2005
----------------------------------------------------------
プロジェクトに新しい項目を追加する画面には、Windowsフォームとダイアログがありますが、
大元は同じもののようですね。
ダイアログの方は初めからDialogとして使いやすい(?) ような設定がされているようですが、
なんにしてもあのボタンをそのまま流用しにくい。。
てことで結局WindowsフォームからDialog作るんだよねw
唯一つ注意が。
今回、DialogがActiveなときにEscキーで呼び出し元に戻るように、FormのCancelButtonプロパティに、
「戻る」ボタンを設定しておいたんです(これでEscキーで画面を閉じれます) 。
これを当初の仕様と少し変えたんです。
「戻る」ボタン押下時に「戻ってよいか?」メッセージを出すことにしたので、当然Escキーでの画面Close処理は不要となり、
CancelButtonプロパティから「戻る」ボタンを外したんです。
でも。。
「戻ってよいか?」メッセージ で「いいえ」を選択しても画面が閉じてしまう!!
頑張って探してやっとわかった。
一度CancelButtonプロパティに設定したButtonコントロールは、DialogResultプロパティが勝手にCancelになってしまうみたい。
CancelButton プロパティから外してもそのまま残るため、そのボタンを押すと、Clickイベントを抜けた後に画面を閉じてしまう。。
試してないから確かなことは言えないが、AcceptButtonプロパティも多分同様の挙動を示すんだろうな。
不毛な時間を過ごすから、注意しないといけませんね。
画面Load時、controlへのFocus [コントロール]
----------------------------------------------------------
(開発・実行環境)
Microsoft Visual Studio 2005 Tools for Applications
Microsoft Visual Basic 2005
----------------------------------------------------------
(課題)
画面Load時、
(control).Focus
してもFocusしてくれない!
(解決法)
同じ悩みを持った人、割と多い気がするんだけど。
(オレだけ?)
初期化するときとか。
(前開いたときの情報が残ってたり。。ちょっと古い?作り方してるもんで。。)
以下のようにすればFocusしてくれます。
Me.ActiveControl = Me.(control)
LoadされるまではControlがアクティブになってないのかしらね~。
ちなみにMeはいらないけど、あった方がコーディングしやすいでしょ。
タブオーダー [コントロール]
----------------------------------------------------------
(開発・実行環境)
Microsoft Visual Studio 2005 Tools for Applications
Microsoft Visual Basic 2005
----------------------------------------------------------
GroopBoxやDataGridViewを用いた画面開発で、なぜかTabが
プロパティのTabIndexで設定した順番に遷移してくれず。。。
どうやらGroopBoxやDataGridViewを用いた場合は、まず大きい枠のTab遷移順を決めて、
その枠の中での遷移順を決めるらしい。
開発画面上部の[表示]→タブオーダーを選び、
遷移していく順にクリックして設定。
これでTabIndex設定がらっくちん♪