How to make Combobox in winforms readonly

后端 未结 18 1942
攒了一身酷
攒了一身酷 2020-12-08 09:40

I do not want the user to be able to change the value displayed in the combobox. I have been using Enabled = false but it grays out the text, so it is not very

相关标签:
18条回答
  • 2020-12-08 10:00

    Simplest way in code:

    instead of adding methods for KeyPress or KeyDown, add this code on 'Form1_Load' method:

    comboBox1.KeyPress += (sndr, eva) => eva.Handled = true;

    or

    comboBox1.KeyDown += (sndr, eva) => eva.SuppressKeyPress = true;

    (sndr, eva) is for (object sender, EventArgs e)

    0 讨论(0)
  • 2020-12-08 10:01

    I know that I'm a little late to the party, but I was researching this exact question and I knew that there had to be some way to make the combobox readonly as if it were a textbox and disabled the list popping up. It's not perfect, but it is definitely better than all of the answers I've been finding all over the internet that don't work for me. After the button is pressed and the OnDropDown is called, a new thread is created that will set the DroppedDown property to false, thus creating the effect of "nothing happening." The mouse wheel is consumed and key events are consumed as well.

    using System;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace Test_Application
    {
        class ReadOnlyComboBox : ComboBox
        {
            private bool _readOnly;
            private bool isLoading;
            private bool indexChangedFlag;
            private int lastIndex = -1;
            private string lastText = "";
    
            public ReadOnlyComboBox()
            {
            }
    
            public bool ReadOnly
            {
                get { return _readOnly; }
                set { _readOnly = value; }
            }
    
            protected override void OnDropDown(EventArgs e)
            {
                if (_readOnly)
                {
                    DropDownHeight = 1;
                    var t = new Thread(CloseDropDown);
                    t.Start();
                    return;
                }
                base.OnDropDown(e);
            }
    
            private delegate void CloseDropDownDelegate();
            private void WaitForDropDown()
            {
                if (InvokeRequired)
                {
                    var d = new CloseDropDownDelegate(WaitForDropDown);
                    Invoke(d);
                }
                else
                {
                    DroppedDown = false;
                }
            }
            private void CloseDropDown()
            {
                WaitForDropDown();
            }
    
            protected override void OnMouseWheel(MouseEventArgs e)
            {
                if (!_readOnly) 
                    base.OnMouseWheel(e);
            }
    
            protected override void OnKeyDown(KeyEventArgs e)
            {
                if (_readOnly)
                {
                    switch (e.KeyCode)
                    {
                        case Keys.Back:
                        case Keys.Delete:
                        case Keys.Up:
                        case Keys.Down:
                            e.SuppressKeyPress = true;
                            return;
                    }
                }
                base.OnKeyDown(e);
            }
    
            protected override void OnKeyPress(KeyPressEventArgs e)
            {
                if (_readOnly)
                {
                    e.Handled = true;
                    return;
                }
                base.OnKeyPress(e);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 10:03

    make DropDownStyle property to DropDownList instead of DropDown then handle the TextChanged event to prevent user changing text.

    0 讨论(0)
  • 2020-12-08 10:04

    If you've already populated it, and selected the appropriate item, and made it a DropDownList, then you can use an extension method like this to quickly reduce the selection list down to just the selected item:

    public static void MakeReadOnly(this ComboBox pComboBox) {
       if (pComboBox.SelectedItem == null)
          return;
    
       pComboBox.DataSource = new List<object> {
          pComboBox.SelectedItem
       };
    }
    
    0 讨论(0)
  • 2020-12-08 10:05

    Actually, its rather simple:

    Private Sub combobox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles combobox1.KeyDown
        ' the following makes this the combobox read only    
        e.SuppressKeyPress = True    
    End Sub
    
    0 讨论(0)
  • 2020-12-08 10:06

    I've handled it by subclassing the ComboBox to add a ReadOnly property that hides itself when set and displays a ReadOnly TextBox on top containing the same Text:

    class ComboBoxReadOnly : ComboBox
    {
        public ComboBoxReadOnly()
        {
            textBox = new TextBox();
            textBox.ReadOnly = true;
            textBox.Visible = false;
        }
    
        private TextBox textBox;
    
        private bool readOnly = false;
    
        public bool ReadOnly
        {
            get { return readOnly; }
            set
            {
                readOnly = value;
    
                if (readOnly)
                {
                    this.Visible = false;
                    textBox.Text = this.Text;
                    textBox.Location = this.Location;
                    textBox.Size = this.Size;
                    textBox.Visible = true;
    
                    if (textBox.Parent == null)
                        this.Parent.Controls.Add(textBox);
                }
                else
                {
                    this.Visible = true;
                    this.textBox.Visible = false;
                }
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题