LoginSignup
1
0

More than 5 years have passed since last update.

ReadOnly 可能な Combobox

Last updated at Posted at 2015-11-03

ReadOly 可能なCombobox

Enabled を False にするとグレーアウトしてしまうため、ReadOnly 可能にしました。
いろいろ余計なことしてますが、これで対応しました。

ReadOnlyに不要なコードを削除しました。

ReadOnlyCombobox.vb
''' <summary>
''' コンボボックス
''' </summary>
''' <remarks>
''' </remarks>
Public Class ComboBox
    Inherits System.Windows.Forms.ComboBox

    Protected _readOnly As Boolean
    Protected _unenabledBackColor As System.Drawing.Color = System.Drawing.SystemColors.Control
    Protected _components As System.ComponentModel.IContainer
    Protected _keyPressHandled As Boolean

    Protected _readOnlyBackColor As System.Drawing.Color = Me.BackColor
    Protected _readOnlyForeColor As System.Drawing.Color = Me.ForeColor
    Protected _notReadOnlyBackColor As System.Drawing.Color = Me.BackColor
    Protected _notReadOnlyForeColor As System.Drawing.Color = Me.ForeColor

    Protected _unenabledForeColor As System.Drawing.Color = Nothing

    ''' <summary>
    ''' EnabledプロパティがFalseのときに表示されるForeColor
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <System.ComponentModel.Description("EnabledプロパティがFalseの時に表示される文字色です。")>
    Public Property UnenabledForeColor() As System.Drawing.Color
        Get
            Return Me._unenabledForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            Me._unenabledForeColor = value
        End Set
    End Property


    <System.ComponentModel.Description("文字列を変更できるかどうかを設定します。")>
    Public Property [ReadOnly] As Boolean
        Get
            Return Me._readOnly
        End Get
        Set(value As Boolean)

            If value = Me._readOnly Then Return

            Me._readOnly = value

            If value Then
                Me.ContextMenu = New System.Windows.Forms.ContextMenu
                Me.BackColor = _readOnlyBackColor
                Me.ForeColor = _readOnlyForeColor
                Me.SetStyle(ControlStyles.UserMouse, True)
            Else
                Me.ContextMenu = Nothing
                Me.BackColor = _notReadOnlyBackColor
                Me.ForeColor = _notReadOnlyForeColor
                Me.SetStyle(ControlStyles.UserMouse, False)
            End If

        End Set
    End Property

    <System.ComponentModel.Description("ReadOnlyプロパティがTrueの時に表示される背景色です。")>
    Public Property ReadOnlyBackColor() As System.Drawing.Color
        Get
            Return Me._readOnlyBackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            Me._readOnlyBackColor = value
        End Set
    End Property

    <System.ComponentModel.Description("ReadOnlyプロパティがTrueの時に表示される文字色です。")>
    Public Property ReadOnlyForeColor() As System.Drawing.Color
        Get
            Return Me._readOnlyForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            Me._readOnlyForeColor = value
        End Set
    End Property

    <System.ComponentModel.Description("ReadOnlyプロパティがFalseの時に表示される背景色です。")>
    Public Property NotReadOnlyBackColor() As System.Drawing.Color
        Get
            Return Me._notReadOnlyBackColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            Me._notReadOnlyBackColor = value
        End Set
    End Property

    <System.ComponentModel.Description("ReadOnlyプロパティがFalseの時に表示される文字色です。")>
    Public Property NotReadOnlyForeColor() As System.Drawing.Color
        Get
            Return Me._notReadOnlyForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            Me._notReadOnlyForeColor = value
        End Set
    End Property

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()

        InitializeComponent()
        Me._components = New System.ComponentModel.Container
    End Sub

    ''' <summary>
    ''' コンボボックスのキーダウン時処理
    ''' </summary>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)

        If Not Me.ReadOnly Then
            Return
        End If

        If e.KeyCode = Keys.Delete Then
            e.Handled = True
            Return
        End If

        If e.KeyCode = Keys.Back Then
            Me._keyPressHandled = True
            Return
        End If

        If e.Control Then
            Select Case e.KeyCode
                Case Keys.V, Keys.X
                    Me._keyPressHandled = True
                    Return
            End Select
        End If

        If e.KeyCode = Keys.Up OrElse e.KeyCode = Keys.PageUp OrElse e.KeyCode = Keys.Down OrElse e.KeyCode = Keys.PageDown Then
            e.Handled = True
            Return
        End If

        Me._keyPressHandled = False

    End Sub

    Protected Overrides Sub Dispose(disposing As Boolean)
        If disposing Then
            If Not Me._components Is Nothing Then
                Me._components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub



    Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)

        If Not Me.ReadOnly Then
            Me._keyPressHandled = False
            Return
        End If

        If Me._keyPressHandled Then
            e.Handled = True
            Me._keyPressHandled = False
            Return
        End If

        If Not Char.IsControl(e.KeyChar) Then
            e.Handled = True
        End If

        Me._keyPressHandled = False


    End Sub

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
        MyBase.OnTextChanged(e)

        '項目全削除の場合、前回選択していた内容が残る不具合の処置
        If String.IsNullOrEmpty(Me.Text) Then
            If TypeOf Me.DataSource Is DataTable Then
                Dim dt As DataTable = DirectCast(Me.DataSource, DataTable)
                Dim rows As DataRow() = dt.Select(Me.DisplayMember + "=''")

                If 0 < rows.Length Then
                    Me.SelectedValue = rows(0)(Me.ValueMember)
                Else
                    Me.SelectedIndex = -1
                End If
            End If
        End If

    End Sub

    <SecurityPermission(SecurityAction.Demand,
        Flags:=SecurityPermissionFlag.UnmanagedCode)>
    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean

        If ((keyData And Keys.Control) = Keys.Control AndAlso
            (keyData And Keys.KeyCode) = Keys.V) OrElse
            ((keyData And Keys.Shift) = Keys.Shift AndAlso
             (keyData And Keys.KeyCode) = Keys.Insert) Then
            If Me.ReadOnly Then
                Return True
            Else
                Return MyBase.ProcessCmdKey(msg, keyData)
            End If
        Else
            Return MyBase.ProcessCmdKey(msg, keyData)
        End If

    End Function

End Class

ReadOnlyCombobox.Designer.vb
    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class ComboBox
        Inherits System.Windows.Forms.ComboBox

        'コントロール デザイナで必要です。
        Private components As System.ComponentModel.IContainer

        ' メモ: 以下のプロシージャはコンポーネント デザイナで必要です。
        ' コンポーネント デザイナを使って変更できます。
        ' コード エディタを使って変更しないでください。
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            components = New System.ComponentModel.Container()
        End Sub

    End Class

1
0
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0