Как сделать Combobox в winforms только для чтения - PullRequest
53 голосов
/ 24 декабря 2008

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

Есть ли способ сделать это?

Ответы [ 17 ]

145 голосов
/ 21 февраля 2009

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

18 голосов
/ 31 января 2009

Статья ComboBox с поведением только для чтения предлагает интересное решение:

Создайте текстовое поле только для чтения и комбинированный список в одном месте. Если вы хотите использовать режим только для чтения, отобразите текстовое поле, если вы хотите, чтобы он был редактируемым, отобразите комбинированный список.

11 голосов
/ 24 декабря 2008

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

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

Затем по событию SelectedIndexChanged

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

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

9 голосов
/ 24 декабря 2008

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

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

8 голосов
/ 11 мая 2015

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

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

4 голосов
/ 21 ноября 2012

Я обработал его, создав подкласс 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;
            }
        }
    }
}
2 голосов
/ 10 сентября 2010

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

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

Отменит нажатие клавиши для Комбо.

2 голосов
/ 19 ноября 2016

Код Майкла Р работает, но ...
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 C # -> Windows -> Классический рабочий стол -> Библиотека управления Windows Forms

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

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

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

Вот как вы бы обратили внимание на тот факт, что ComboBox с Enabled = False трудно читать:

Комбо-бокс, который выглядит прилично, когда он отключен

1 голос
/ 25 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...