[英]How to make Combobox in winforms readonly
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 readable.我一直在使用
Enabled = false
但它使文本变灰,所以它不是很可读。 I want it to behave like a textbox with ReadOnly = true
, where the text is displayed normally, but the user can't edit it.我希望它表现得像一个带有
ReadOnly = true
的文本框,文本正常显示,但用户无法编辑它。
Is there is a way of accomplishing this?有没有办法做到这一点?
将DropDownStyle
属性设置为DropDownList
而不是DropDown
然后处理TextChanged
事件以防止用户更改文本。
The article ComboBox-with-read-only-behavior suggests an interesting solution:文章ComboBox-with-read-only-behavior提出了一个有趣的解决方案:
Create both a readonly textbox and a combobox in the same place.在同一位置创建只读文本框和组合框。 When you want readonly mode, display the textbox, when you want it to be editable, display the combobox.
当你想要只读模式时,显示文本框,当你想要它可编辑时,显示组合框。
Not sure if this is what you're looking for but...不确定这是否是您要找的东西,但是...
Set the DropDownStyle = DropDownList设置 DropDownStyle = DropDownList
Then on the SelectedIndexChanged event然后在 SelectedIndexChanged 事件上
if (ComboBox1.SelectedIndex != 0)
{
ComboBox1.SelectedIndex = 0;
}
This ugly part is that they will "feel" like they can change it.这个丑陋的部分是他们会“感觉”他们可以改变它。 They might think this is an error unless you give them an alert telling them why they can't change the value.
他们可能会认为这是一个错误,除非您向他们发出警报,告诉他们为什么无法更改该值。
enter link description here在此处输入链接描述
Just change the
DropDownStyle
toDropDownList
.只需将
DropDownStyle
更改为DropDownList
。 Or if you want it completely read only you can setEnabled = false
, or if you don't like the look of that I sometimes have two controls, one readonly textbox and one combobox and then hide the combo and show the textbox if it should be completely readonly and vice versa.或者,如果您希望它完全只读,您可以设置
Enabled = false
,或者如果您不喜欢它的外观,我有时会使用两个控件,一个只读文本框和一个组合框,然后隐藏组合并显示文本框(如果应该)完全只读,反之亦然。
The best thing I can suggest is to replace the combo-box with a read-only textbox (or just perhaps a label) - that way the user can still select/copy the value, etc.我能建议的最好的事情是用只读文本框(或者只是一个标签)替换组合框 - 这样用户仍然可以选择/复制值等。
Of course, another cheeky tactic would be to set the DropDownStyle
to DropDownList
, and just remove all other options - then the user has nothing else to pick ;-p当然,另一种厚颜无耻的策略是将
DropDownStyle
设置为DropDownList
,然后删除所有其他选项 - 然后用户没有其他选择;-p
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:我已经通过继承 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;
}
}
}
}
Here is the Best solution for the ReadOnly Combo.这是 ReadOnly Combo 的最佳解决方案。
private void combo1_KeyPress(object sender, KeyPressEventArgs e)
{
e.KeyChar = (char)Keys.None;
}
It will discard the keypress for the Combo.它将丢弃 Combo 的按键。
Michael R's code works, but... Michael R 的代码有效,但是...
The DropDownHeight = 1;
DropDownHeight = 1;
must be back to the default value when ReadOnly property is set to false.当 ReadOnly 属性设置为 false 时,必须恢复为默认值。 So, insert before
base.OnDropDown(e)
: DropDownHeight = 106;
所以,在
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);
}
}
}
To complete this answer:要完成此答案:
File -> New -> Project... Visual C# -> Windows -> Classic Desktop -> Windows Forms Control Library
文件 -> 新建 -> 项目... Visual C# -> Windows -> 经典桌面 -> Windows 窗体控件库
type the Name of your control - OK and paste this code.输入控件的名称 - 确定并粘贴此代码。
You can choose the name of your dll file:您可以选择 dll 文件的名称:
Project - yourproject Properties...项目 - 您的项目属性...
This is how you would address the fact that a ComboBox
with Enabled = False
is hard to read:这是您将如何解决具有
Enabled = False
的ComboBox
难以阅读的事实:
A combobox that looks decent when it is disabled 禁用时看起来不错的组合框
您可以将前景色和背景色更改为已启用组合框的系统颜色,尽管这可能会使用户感到困惑(如果他们不能更改它,为什么要使用它),但它看起来会更好。
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
Set DropdownStyle
Property to Simple
将
DropdownStyle
属性设置为Simple
Add below code to to KeyPress
event of ComboBox将以下代码添加到 ComboBox 的
KeyPress
事件
private void comboBoxName_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
return;
}
Add below code to to KeyDown
event of ComboBox将以下代码添加到 ComboBox 的
KeyDown
事件
private void comboBoxName_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
return;
}
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:如果您已经填充了它,并选择了适当的项目,并将其设为
DropDownList
,那么您可以使用这样的扩展方法来快速将选择列表缩小到选定的项目:
public static void MakeReadOnly(this ComboBox pComboBox) {
if (pComboBox.SelectedItem == null)
return;
pComboBox.DataSource = new List<object> {
pComboBox.SelectedItem
};
}
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."
按下按钮并调用 OnDropDown 后,将创建一个新线程,将 DroppedDown 属性设置为 false,从而产生“什么也没有发生”的效果。 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);
}
}
}
Simplest way in code :代码中最简单的方法:
instead of adding methods for KeyPress
or KeyDown
, add this code on ' Form1_Load
' method:不要为
KeyPress
或KeyDown
添加方法,而是在“ Form1_Load
”方法上添加此代码:
comboBox1.KeyPress += (sndr, eva) => eva.Handled = true;
or或
comboBox1.KeyDown += (sndr, eva) => eva.SuppressKeyPress = true;
(sndr, eva)
is for (object sender, EventArgs e)
(sndr, eva)
用于(object sender, EventArgs e)
Why don't you just use a text box?为什么不直接使用文本框? Text box has a "Read only" property, and since you want your combo box only to display data, I don't see why you would need a combo box.
文本框具有“只读”属性,并且由于您希望组合框仅显示数据,因此我不明白您为什么需要组合框。
An alternative is that you just cancel out the input for the "on value changed" event.另一种方法是您只需取消“on value changed”事件的输入。 That way you will be displaying your information no mater what user does ...
这样,无论用户做什么,您都将显示您的信息......
I dont know if that is what you are looking but this prevents the user from chosing any item from the drop down and still be able to type text in the combobox.我不知道这是否是您要查找的内容,但这会阻止用户从下拉列表中选择任何项目并且仍然能够在组合框中键入文本。 If you dont want the user to type text in the combobox you can make it Dropdown list from the properties menu.
如果您不希望用户在组合框中键入文本,您可以从属性菜单中将其设为下拉列表。
So you get Read Only combobox .所以你得到Read Only 组合框。
Make the selected Index -1 " comboBox.SelectedIndex = -1 ";使选定的索引 -1 " comboBox.SelectedIndex = -1 ";
private void MyComboBox_comboBox_SelectedIndexChanged(object sender, EventArgs e) { MyComboBox_comboBox.SelectedIndex = -1; }
Here is the Best solution for the ReadOnly Combo.这是 ReadOnly Combo 的最佳解决方案。
private void combo1_KeyPress(object sender, KeyPressEventArgs e) {
e.KeyChar = (char)Keys.None;
}
It will discard the keypress for the Combo.它将丢弃 Combo 的按键。 It doesn't have "e. KeyChar " !
它没有“e. KeyChar ”!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.