C#& .Net 2.0问题(WinForms)
我在ComboBox
中设置了一组项目,但未选中其中的项目。我想在那种情况下在组合词“请选择项目”上显示一个字符串。
当前实现只是在索引 0 上添加了带有此类文本的空项,并在用户选择以下项之一时将其删除。不幸的是,空项目也显示在下拉列表中。如何避免这种情况或以其他方式 - 当没有选择项目时,有没有办法在ComboBox
上显示自定义文字?
ComboBoxStyle
设置为DropDown
时ComboBox
可编辑,
以下答案有效。当ComboBoxStyle
设置为DropDownList
时,是否有可能执行此操作?
答案 0 :(得分:14)
使用组合框的插入方法将“请选择项目”插入0索引
comboBox1.Items.Insert(0, "Please select any value");
并在第一个索引后将所有项添加到组合框中。在表单加载集
中comboBox1.SelectedIndex = 0;
编辑:
在表单加载中,通过硬编码将文本写入comboBox1.Text
comboBox1.Text = "Please, select any value";
并在comboBox1的TextChanged事件中编写以下代码
private void comboBox1_TextChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex < 0)
{
comboBox1.Text = "Please, select any value";
}
else
{
comboBox1.Text = comboBox1.SelectedText;
}
}
答案 1 :(得分:5)
我是这样做的。它可能不是最好的方法,并提供最少的控制;然而,它简单快捷,我认为分享它可能是一个好主意,以便为其他人提供更多选择。
<ComboBox SelectedIndex="0">
<ComboBoxItem Visibility="Collapsed">Please select one...</ComboBoxItem>
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
<ComboBoxItem>4</ComboBoxItem>
</ComboBox>
这背后的想法是初始选择是索引0,它是折叠的,所以一旦他们选择其他东西,它就不能在用户的选择下使用。缺点是您必须记住,如果您正在检查所选索引,请记住索引0表示没有选择。
答案 2 :(得分:4)
private void comboBox1_TextChanged(object sender, EventArgs e)
{
if (comboBox1.Text == "")
comboBox1.Text = "Select one of the answers";
}
应该做的伎俩 在启动时,此行存在,当在组合框中选择项目时,将显示此项目文本。删除文本时,此文本将再次出现
答案 3 :(得分:2)
为了回应IronRazerz,必须向TextBox watermark (CueBanner) which goes away when user types in single line TextBox (not for RichTextBox)提供信用。
您将需要在您的课程中声明以下内容:
private const int CB_SETCUEBANNER = 0x1703;
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]string lParam);
然后,您可以将其与类似以下内容一起使用:
SendMessage(this.comboBox1.Handle, CB_SETCUEBANNER, 0, "Please select an item...");
这是假设组合框的DropDownStyle
设置为DropDownList
,就像原始海报的问题一样。
这应该导致如下所示:
答案 4 :(得分:2)
我使用了快速解决方法,因此我可以保留DropDownList样式。
class DummyComboBoxItem
{
public string DisplayName
{
get
{
return "Make a selection ...";
}
}
}
public partial class mainForm : Form
{
private DummyComboBoxItem placeholder = new DummyComboBoxItem();
public mainForm()
{
InitializeComponent();
myComboBox.DisplayMember = "DisplayName";
myComboBox.Items.Add(placeholder);
foreach(object o in Objects)
{
myComboBox.Items.Add(o);
}
myComboBox.SelectedItem = placeholder;
}
private void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (myComboBox.SelectedItem == null) return;
if (myComboBox.SelectedItem == placeholder) return;
/*
do your stuff
*/
myComboBox.Items.Add(placeholder);
myComboBox.SelectedItem = placeholder;
}
private void myComboBox_DropDown(object sender, EventArgs e)
{
myComboBox.Items.Remove(placeholder);
}
private void myComboBox_Leave(object sender, EventArgs e)
{
//this covers user aborting the selection (by clicking away or choosing the system null drop down option)
//The control may not immedietly change, but if the user clicks anywhere else it will reset
if(myComboBox.SelectedItem != placeholder)
{
if(!myComboBox.Items.Contains(placeholder)) myComboBox.Items.Add(placeholder);
myComboBox.SelectedItem = placeholder;
}
}
}
如果您使用数据绑定,则必须创建您所绑定类型的虚拟版本 - 只需确保在任何持久性逻辑之前删除它。
答案 5 :(得分:1)
我看不到任何原生的.NET方法,但是如果你想弄清楚底层的Win32控件......
您应该能够发送CB_GETCOMBOBOXINFO
消息,其中COMBOBOXINFO
结构将包含内部编辑控件的句柄。
然后,您可以使用指向字符串的指针向编辑控件发送EM_SETCUEBANNER
消息。
(请注意,这至少需要启用XP和视觉样式。
答案 6 :(得分:1)
将组合框的Dropdownstyle属性设为Dropdown,并将组合框文本设置为“Select”,如下所示
combobox.DataSource = dsIn.Tables[0];
combobox.DisplayMember = "Name";
combobox.ValueMember = "Value";
combobox.Text = "--Select--";
答案 7 :(得分:1)
表单InitializeComponent();
cbo_MyDropBox.Text = "Select a server...";
你只需要一次吗?如果选择是必需的,您需要做的就是检查框索引!= -1
。任何人都可以详细说明为什么其他答案会通过箍来实现这一目标吗?
我唯一缺少的就是让这个初始文字变灰了。如果你真的想要只使用前面的标签,并在索引改变后将其关闭。
答案 8 :(得分:0)
在这里你可以找到pavlo_ua创建的解决方案: If you have .Net > 2.0和 If you have .Net == 2.0 (search for pavlo_ua answer)
干杯,jbk
编辑: 所以要明确回答不仅仅是链接
当样式设置为DropDown时,可以设置组合框文本(并且可以编辑)。 当你有.Net版本&lt; 3.0没有IsReadonly属性所以我们需要使用win api将combobox的文本框设置为readonly:
private bool m_readOnly = false;
private const int EM_SETREADONLY = 0x00CF;
internal delegate bool EnumChildWindowsCallBack( IntPtr hwnd, IntPtr lParam );
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[ DllImport( "user32.dll" ) ]
internal static extern int EnumChildWindows( IntPtr hWndParent, EnumChildWindowsCallBack lpEnumFunc, IntPtr lParam );
private bool EnumChildWindowsCallBackFunction(IntPtr hWnd, IntPtr lparam)
{
if( hWnd != IntPtr.Zero )
{
IntPtr readonlyValue = ( m_readOnly ) ? new IntPtr( 1 ) : IntPtr.Zero;
SendMessage( hWnd, EM_SETREADONLY, readonlyValue, IntPtr.Zero );
comboBox1.Invalidate();
return true;
}
return false;
}
private void MakeComboBoxReadOnly( bool readOnly )
{
m_readOnly = readOnly;
EnumChildWindowsCallBack callBack = new EnumChildWindowsCallBack(this.EnumChildWindowsCallBackFunction );
EnumChildWindows( comboBox1.Handle, callBack, IntPtr.Zero );
}
答案 9 :(得分:0)
如果ComboBoxStyle
设置为DropDownList
,那么确保用户选择项目的最简单方法是设置SelectedIndex = -1
,这将是空的
答案 10 :(得分:0)
我意识到这是一个旧线程,但只是想让其他可能搜索此问题答案的人知道,在当前版本的Visual Studio(2015)中,有一个名为“Placeholder Text”的属性可以什么是约特贝克最初问的问题。使用“常用”属性下的“属性”框。
答案 11 :(得分:0)
不幸的是,以上都没有为我工作,所以我在comboxbox的顶部添加了一个标签,上面写着“请选择”。我使用以下代码来显示和隐藏它:
当我初始化我的组合框时,如果没有选定的值,我将它带到前面并设置文本:
PleaseSelectValueLabel.BringToFront();
PleaseSelectValueLabel.Text = Constants.AssessmentValuePrompt;
如果选择了值,我会将其发送到后面:
PleaseSelectValueLabel.SendToBack();
然后我使用以下事件将标签移到前面或后面,具体取决于用户是否选择了一个值:
private void PleaseSelectValueLabel_Click(object sender, EventArgs e)
{
PleaseSelectValueLabel.SendToBack();
AssessmentValue.Focus();
}
private void AssessmentValue_Click(object sender, EventArgs e)
{
PleaseSelectValueLabel.SendToBack();
}
//if the user hasnt selected an item, make the please select label visible again
private void AssessmentValue_Leave(object sender, EventArgs e)
{
if (AssessmentValue.SelectedIndex < 0)
{
PleaseSelectValueLabel.BringToFront();
}
}
答案 12 :(得分:0)
我也希望找到解决方案。我发现这是一篇较旧的帖子,但希望我的方法可以为其他人简化这个问题。
我使用的是具有下拉式DropDownList的组合框,但这应该适用于其他样式。在我的情况下,我希望文本读取“选择源”,我希望其他选项是“文件”和“文件夹”
/usr/local/anaconda3/envs/ds/lib/python3.6/site-packages/ipykernel_launcher.py:1: RuntimeWarning: invalid value encountered in log
"""Entry point for launching an IPython kernel.
如果您愿意,可以选择0索引。 然后,我在更改索引时删除了“选择源”项,因为如果该文本可见则不再重要。
NaN
由于
答案 13 :(得分:0)
这适用于DropDownList样式-创建从ComboBox派生的类
(将在重建后显示在工具箱中),使用System.Drawing绘制提示,
将此控件从“工具箱”放置到窗体中,并在其属性中设置提示“请选择项目”。
public class HintComboBox : ComboBox
{
string hint;
public string Hint
{
get { return hint; }
set { hint = value; Invalidate(); }
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0xf && !Focused && string.IsNullOrEmpty(Text) && !string.IsNullOrEmpty(Hint))
using (var g = CreateGraphics())
{
TextRenderer.DrawText(g, Hint, Font, ClientRectangle, SystemColors.GrayText, BackColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter);
}
}
}
答案 14 :(得分:0)
我无法使用@Andrei Karcheuski的工作方法,但是他启发了我这种方法: (我添加了Localizable属性,以便可以针对使用它的每个对话框通过.resx文件转换提示。)
public partial class HintComboBox : ComboBox
{
string hint;
Font greyFont;
[Localizable(true)]
public string Hint
{
get { return hint; }
set { hint = value; Invalidate(); }
}
public HintComboBox()
{
InitializeComponent();
}
protected override void OnCreateControl()
{
base.OnCreateControl();
if (string.IsNullOrEmpty(Text))
{
this.ForeColor = SystemColors.GrayText;
Text = Hint;
}
else
{
this.ForeColor = Color.Black;
}
}
private void HintComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if( string.IsNullOrEmpty(Text) )
{
this.ForeColor = SystemColors.GrayText;
Text = Hint;
}
else
{
this.ForeColor = Color.Black;
}
}
答案 15 :(得分:0)
如果之前的解决方案都不适合您,为什么不在组合框上添加一些验证,例如,
var orginalindex = 0;
private void comboBox1_SelectedItemChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 0)
{
comboBox1.Text = "Select one of the answers";
comboBox1.SelectedIndex = comboBox1.SelectedIndex;
}
else
{
orginalindex = comboBox1.SelectedIndex;
}
}
答案 16 :(得分:-3)
为什么不做XAML?
<ComboBox x:Name="myComboBoxMenu" PlaceholderText="Hello"/>