DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DOBON.NET

ComboBoxが上下矢印キーで項目を変更できないようにする

ComboBoxコントロールで、マウスだけで項目を選択でき、上下矢印キーによる選択ができないようにする方法について説明します。

KeyDownイベントでキャンセルする方法

簡単な方法としては、ComboBoxのKeyDownイベントハンドラで上下矢印キーが押された時にKeyEventArgsオブジェクトのHandledプロパティをTrueにして、キー入力を無効にする方法があります。

[VB.NET]
'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
[C#]
//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;
}

PreProcessMessageをオーバーライドする方法

残念ながら上記のような方法は、.NET Framework 1.0では正常に働きません(1.1ではこのバグが修正されています)。.NET Framework 1.0では、ComboBoxの派生クラスを作成し、WndProcやPreProcessMessageメソッドをオーバーライドすることにより、上下矢印キーを無視するなどの方法を使用する必要があります。

次にPreProcessMessageメソッドをオーバーライドすることにより上下矢印キーでの操作を無効にしたComboBoxの派生クラス(MyComboBoxクラス)のサンプルを示します。このクラスを実際に使用するには、"System.Windows.Forms.ComboBox"の代わりに"MyComboBox"を使うようにします。

注意:新しく作成したクラスを、基のコントロールクラスの代わりに使用するという意味が分からないという方は、こちらをご覧ください。

[VB.NET]
''' <summary>
''' 上下矢印キーで項目を変更できないComboBox
''' </summary>
Public Class MyComboBox
    Inherits System.Windows.Forms.ComboBox

    Private WM_KEYDOWN As Integer = &H100

    Public Overrides Function PreProcessMessage( _
        ByRef msg As Message) As Boolean
        If msg.Msg = WM_KEYDOWN Then
            '上下矢印キー操作を無効にする
            Dim keyCode As Keys = _
                CType(msg.WParam.ToInt32(), Keys) And Keys.KeyCode
            If keyCode = Keys.Up Or keyCode = Keys.Down Then
                Return True
            End If
        End If
        Return MyBase.PreProcessMessage(msg)
    End Function
End Class
[C#]
/// <summary>
/// 上下矢印キーで項目を変更できないComboBox
/// </summary>
public class MyComboBox : System.Windows.Forms.ComboBox
{
    private const int WM_KEYDOWN = 0x100;

    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);
    }
}

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • イベントハンドラの意味が分からない、C#のコードをそのまま書いても動かないという方は、こちらをご覧ください。