如果没有选择项目,如何在组合框中显示文本?

时间:2011-11-09 11:09:45

标签: c# winforms .net-2.0

C#& .Net 2.0问题(WinForms)

我在ComboBox中设置了一组项目,但未选中其中的项目。我想在那种情况下在组合词“请选择项目”上显示一个字符串。

当前实现只是在索引 0 上添加了带有此类文本的空项,并在用户选择以下项之一时将其删除。不幸的是,空项目也显示在下拉列表中。如何避免这种情况或以其他方式 - 当没有选择项目时,有没有办法在ComboBox上显示自定义文字?

ComboBoxStyle设置为DropDownComboBox可编辑,

以下答案有效。当ComboBoxStyle设置为DropDownList时,是否有可能执行此操作?

17 个答案:

答案 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,就像原始海报的问题一样。

这应该导致如下所示:

Placeholder text for combo box drop down list

答案 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.0If 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的顶部添加了一个标签,上面写着“请选择”。我使用以下代码来显示和隐藏它:

  1. 当我初始化我的组合框时,如果没有选定的值,我将它带到前面并设置文本:

    PleaseSelectValueLabel.BringToFront();
    PleaseSelectValueLabel.Text = Constants.AssessmentValuePrompt;
    
  2. 如果选择了值,我会将其发送到后面:

    PleaseSelectValueLabel.SendToBack();
    
  3. 然后我使用以下事件将标签移到前面或后面,具体取决于用户是否选择了一个值:

    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"/>