ComboBoxコントロールで、マウスだけで項目を選択でき、上下矢印キーによる選択ができないようにする方法について説明します。
簡単な方法としては、ComboBoxのKeyDownイベントハンドラで上下矢印キーが押された時にKeyEventArgsオブジェクトのHandledプロパティをTrueにして、キー入力を無効にする方法があります。
'ComboBox1のKeyDownイベントハンドラ Private Sub ComboBox1_KeyDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.KeyEventArgs) _ Handles ComboBox1.KeyDown If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then e.Handled = True End If End Sub
//ComboBox1のKeyDownイベントハンドラ private void ComboBox1_KeyDown( object sender, System.Windows.Forms.KeyEventArgs e) { if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up) e.Handled = true; }
残念ながら上記のような方法は、.NET Framework 1.0では正常に働きません(1.1ではこのバグが修正されています)。.NET Framework 1.0では、ComboBoxの派生クラスを作成し、WndProcやPreProcessMessageメソッドをオーバーライドすることにより、上下矢印キーを無視するなどの方法を使用する必要があります。
次にPreProcessMessageメソッドをオーバーライドすることにより上下矢印キーでの操作を無効にしたComboBoxの派生クラス(MyComboBoxクラス)のサンプルを示します。このクラスを実際に使用するには、"System.Windows.Forms.ComboBox"の代わりに"MyComboBox"を使うようにします。
注意:新しく作成したクラスを、基のコントロールクラスの代わりに使用するという意味が分からないという方は、こちらをご覧ください。
Imports System.Windows.Forms Imports System.Security.Permissions ''' <summary> ''' 上下矢印キーで項目を変更できないComboBox ''' </summary> Public Class MyComboBox Inherits ComboBox Private Const WM_KEYDOWN As Integer = &H100 <SecurityPermission(SecurityAction.Demand, _ Flags:=SecurityPermissionFlag.UnmanagedCode)> _ Public Overrides Function PreProcessMessage(ByRef msg As Message) As Boolean If msg.Msg = WM_KEYDOWN Then '上下矢印キー操作を無効にする Dim keyCode As Keys = CType(CInt(msg.WParam), Keys) And Keys.KeyCode If keyCode = Keys.Up OrElse keyCode = Keys.Down Then Return True End If End If Return MyBase.PreProcessMessage(msg) End Function End Class
using System; using System.Windows.Forms; using System.Security.Permissions; /// <summary> /// 上下矢印キーで項目を変更できないComboBox /// </summary> public class MyComboBox : ComboBox { private const int WM_KEYDOWN = 0x100; [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override bool PreProcessMessage(ref Message msg) { if (msg.Msg == WM_KEYDOWN) { //上下矢印キー操作を無効にする Keys keyCode = (Keys)(int)msg.WParam & Keys.KeyCode; if (keyCode == Keys.Up || keyCode == Keys.Down) return true; } return base.PreProcessMessage(ref msg); } }
(この記事は「.NETプログラミング研究 第35号」で紹介したものです。)