Подтвердить что ты не робот

Как сделать Combobox в winforms readonly

Я не хочу, чтобы пользователь мог изменить значение, отображаемое в поле со списком. Я использовал Enabled = false, но он выделяет текст, поэтому он не очень читаем. Я хочу, чтобы он вел себя как текстовое поле с ReadOnly = true, где текст отображается нормально, но пользователь не может его редактировать.

Есть ли способ выполнить это?

4b9b3361

Ответ 1

В статье ComboBox-with-read-only-behavior предлагается интересное решение:

Создайте текстовое поле только для чтения и выпадающее поле в том же месте. Когда вы хотите режим readonly, отобразите текстовое поле, когда вы хотите, чтобы оно редактировалось, отобразите выпадающие списки.

Ответ 2

введите DropDownStyle свойство DropDownList вместо DropDown затем обработайте событие TextChanged, чтобы пользователь не менял текст.

Ответ 3

Лучшее, что я могу предложить, - заменить combo-box текстовым полем только для чтения (или, возможно, ярлыком), - таким образом пользователь все равно может выбрать/скопировать значение и т.д.

Конечно, другой назойливой тактикой было бы установить DropDownStyle на DropDownList и просто удалить все остальные параметры - тогда пользователю больше нечего выбирать; -p

Ответ 4

Не уверен, что это то, что вы ищете, но...

Установите DropDownStyle = DropDownList

Затем в событии SelectedIndexChanged

If (ComboBox1.SelectedIndex <> 0)
{
    ComboBox1.SelectedIndex = 0
}

Эта уродливая часть состоит в том, что они будут "чувствовать", как они могут ее изменить. Они могут подумать, что это ошибка, если вы не сообщите им предупреждение о том, почему они не могут изменить значение.

Ответ 5

введите описание ссылки здесь

Просто измените DropDownStyle на DropDownList. Или, если вы хотите, чтобы он был полностью доступен только для чтения, вы можете установить Enabled = false, или, если вам не нравится внешний вид, у меня иногда есть два элемента управления, одно текстовое поле только для чтения и один комбинированный список, а затем скрыть комбо и показать текстовое поле, если это необходимо. быть полностью прочитанным и наоборот.

Ответ 6

Я обработал его, выполнив подкласс ComboBox, чтобы добавить свойство ReadOnly, которое скрывается при установке и отображает текстовое поле ReadOnly сверху, содержащее тот же текст:

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

Ответ 7

Вот лучшее решение для ReadOnly Combo.

private void combo1_KeyPress(object sender, KeyPressEventArgs e)
{
    e.KeyChar = (char)Keys.None;
}

Отбросит нажатие клавиши Combo.

Ответ 8

Вы можете изменить цвета forecolor и backcolor на цвета системы для включенного поля со списком, хотя это может смутить пользователей (почему бы им не изменить их), это будет выглядеть лучше.

Ответ 10

Код Майкла Р работает, но...
DropDownHeight = 1; должен быть возвращен к значению по умолчанию, когда свойство ReadOnly установлено в false. Итак, вставьте перед base.OnDropDown(e): DropDownHeight = 106;

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;
            }
            DropDownHeight = 106; //Insert this line.
            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);
        }
    }
}

Чтобы завершить этот ответ:

Файл → Создать → Проект... Visual С# → Windows → Классический рабочий стол → Библиотека элементов управления Windows Forms

введите Имя вашего элемента управления - ОК и вставьте этот код.

Вы можете выбрать имя вашего файла DLL:
Проект - Свойства вашего проекта...

  • Имя сборки: введите имя. Просто создайте решение, и у вас есть файл DLL. Итак, откройте проект, в котором вы хотите использовать комбо только для чтения, щелкните правой кнопкой мыши на ссылке
  • Добавьте ссылку... и просмотрите файл DLL. Чтобы вставить свой пользовательский компонент в панель инструментов, откройте панель инструментов, щелкните правой кнопкой мыши вкладку Общие → Выбрать элементы...
  • Просмотрите свой файл DLL - Открыть. Теперь вы можете использовать ваш ReadOnlyComboBox в ваших проектах. PS: я использую VS2015.

Ответ 11

Почему бы вам просто не использовать текстовое поле? Текстовое поле имеет свойство "Только для чтения", и поскольку вы хотите, чтобы в вашем поле со списком отображались только данные, я не понимаю, зачем вам нужно поле со списком.

Альтернативой является то, что вы просто отмените ввод для события "on value changed". Таким образом, вы будете показывать свою информацию без матер, что делает пользователь...

Ответ 12

Собственно, его довольно просто:

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

Ответ 13

Задайте DropdownStyle Свойство Simple

Добавьте код ниже в KeyPress событие ComboBox

private void comboBoxName_KeyPress(object sender, KeyPressEventArgs e)
{
    e.Handled = true;
    return;
}

Добавьте код ниже в KeyDown событие ComboBox

private void comboBoxName_KeyDown(object sender, KeyEventArgs e)
{
    e.Handled = true;
    return;
}

Ответ 14

Если вы уже заполнили его и выбрали соответствующий элемент и сделали его DropDownList, вы можете использовать метод расширения, подобный этому, чтобы быстро уменьшить список выбора до только выбранного элемента:

public static void MakeReadOnly(this ComboBox pComboBox) {
   if (pComboBox.SelectedItem == null)
      return;

   pComboBox.DataSource = new List<object> {
      pComboBox.SelectedItem
   };
}

Ответ 15

Я знаю, что немного опоздал на вечеринку, но я изучал этот точный вопрос, и я знал, что должен быть какой-то способ сделать combobox readonly, как будто это текстовое поле, и отключил список, появляющийся, Это не идеально, но это определенно лучше, чем все ответы, которые я нашел по всему Интернету, которые не работают для меня. После нажатия кнопки и вызова OnDropDown создается новый поток, который устанавливает свойство DroppedDown в значение false, тем самым создавая эффект "ничего не происходит". Колесо мыши потребляется, а ключевые события также потребляются.

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

Ответ 16

Самый простой способ в коде:

вместо добавления методов для KeyPress или KeyDown, добавьте этот код в метод 'Form1_Load':

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

или

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

(sndr, eva) для (object sender, EventArgs e)

Ответ 17

Вот лучшее решение для ReadOnly Combo.

private void combo1_KeyPress(object sender, KeyPressEventArgs e) {
    e.KeyChar = (char)Keys.None; 
} 

Отбросит нажатие клавиши Combo. Он не имеет "e. KeyChar"!