如何在winforms中制作Combobox readonly

时间:2008-12-24 19:29:09

标签: c# .net winforms

我不希望用户能够更改组合框中显示的值。我一直在使用Enabled = false,但它会使文本变灰,因此它的可读性不高。我希望它的行为类似于ReadOnly = true的文本框,文本正常显示,但用户无法编辑。

有没有办法实现这个目标?

18 个答案:

答案 0 :(得分:145)

DropDownStyle属性设为DropDownList而不是DropDown 然后处理TextChanged事件以防止用户更改文本。

答案 1 :(得分:18)

文章ComboBox-with-read-only-behavior提出了一个有趣的解决方案:

在同一个位置创建只读文本框和组合框。当您想要只读模式时,显示文本框,当您想要它可编辑时,显示组合框。

答案 2 :(得分:11)

不确定这是否是你要找的......但

设置DropDownStyle = DropDownList

然后在SelectedIndexChanged事件

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

这个丑陋的部分是他们会“感觉”他们可以改变它。他们可能认为这是一个错误,除非你给他们一个警告,告诉他们为什么他们不能改变价值。

答案 3 :(得分:9)

我可以建议的最好的方法是用只读文本框(或者只是标签)替换组合框 - 这样用户仍然可以选择/复制值等。

当然,另一种厚颜无耻的策略是将DropDownStyle设置为DropDownList,然后删除所有其他选项 - 然后用户没有别的选择;-p

答案 4 :(得分:8)

enter link description here

  

只需将DropDownStyle更改为DropDownList即可。或者,如果你想要它完全只读,你可以设置Enabled = false,或者如果你不喜欢它的外观我有时有两个控件,一个只读文本框和一个组合框然后隐藏组合并显示文本框它应该是完全只读的,反之亦然。

答案 5 :(得分:4)

我通过继承ComboBox来添加一个ReadOnly属性来处理它,该属性在设置时隐藏自身并在顶部显示包含相同文本的ReadOnly TextBox:

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

答案 6 :(得分:2)

迈克尔R的代码有效,但是......
当ReadOnly属性设置为false时,DropDownHeight = 1;必须返回默认值。因此,请在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);
        }
    }
}

要完成此答案:

  

档案 - &gt;新 - &gt;项目...... Visual C# - &gt; Windows - &gt;经典桌面 - &gt;   Windows窗体控件库

输入控件的名称 - 确定并粘贴此代码。

您可以选择dll文件的名称:
项目 - 您的项目属性...

  • 程序集名称:键入名称。只需构建解决方案,您就拥有了dll文件。因此,打开要使用“只读”组合的项目,右键单击“参考”
  • 添加引用...并浏览您的dll文件。要将自定义组件插入工具箱,请打开工具箱,右键单击常规选项卡 - &gt;选择项目......
  • 浏览您的dll文件 - 打开。现在,您可以在项目中使用ReadOnlyComboBox。 PS:我正在使用VS2015。

答案 7 :(得分:2)

这是ReadOnly Combo的最佳解决方案。

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

它将丢弃组合键的按键。

答案 8 :(得分:1)

这就是为什么你要解决ComboBox Enabled = False难以理解的事实:

A combobox that looks decent when it is disabled

答案 9 :(得分:1)

您可以将前景色和背景色更改为启用的组合框的系统颜色,虽然这可能会让用户感到困惑(如果无法更改它们,为什么会这样),它看起来会更好。

答案 10 :(得分:0)

实际上,它很简单:

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

答案 11 :(得分:0)

DropdownStyle属性设置为Simple

将以下代码添加到ComboBox的KeyPress事件

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

将以下代码添加到ComboBox的KeyDown事件

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

答案 12 :(得分:0)

如果您已经填充了它,并选择了相应的项目,并将其设为DropDownList,那么您可以使用这样的扩展方法快速将选择列表缩小到所选项目:< / p>

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

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

答案 13 :(得分:0)

我知道我参加派对的时间有点晚了,但是我正在研究这个问题,我知道必须有一些方法可以使组合框只读文件框并禁用列表弹出。它并不完美,但它肯定比我在互联网上找到的所有不适合我的所有答案都要好。按下按钮并调用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);
        }
    }
}

答案 14 :(得分:0)

为什么不使用文本框?文本框有一个“只读”属性,因为你只想让你的组合框显示数据,我不明白为什么你需要一个组合框。

另一种方法是,您只需取消“on on changed changed”事件的输入。这样,您将显示您的信息,无论用户做什么......

答案 15 :(得分:0)

代码中最简单的方式

而不是为__bridge_transferKeyPress添加方法, 在“KeyDown”方法中添加此代码:

  

Form1_Load

  

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

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

答案 16 :(得分:0)

我不知道这是您要查找的内容,但这使用户无法从下拉列表中选择任何项目,并且仍然能够在组合框中键入文本。如果您不希望用户在组合框中键入文本,则可以从属性菜单中将其设置为下拉列表。

因此您会获得只读组合框

  1. 更改选定索引时
  2. 使所选索引为-1“ comboBox.SelectedIndex = -1 ”;

        private void MyComboBox_comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            MyComboBox_comboBox.SelectedIndex = -1; 
    
        }
    

答案 17 :(得分:-1)

这是ReadOnly Combo的最佳解决方案。

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

它会丢弃Combo的按键。它没有“e。 KeyChar ”!