当选定任何项目,如何显示组合框的文本?

问题描述 投票:21回答:16

C#和.NET 2.0问题(的WinForms)

我已选择了ComboBox项目,其中非。我想显示对组合的字符串在这种情况下“请选择商品”。

当前的实现只是在指数0加入空项目有这样的文字并删除它,当用户选择以下项目之一。不幸的是空的项目在下拉列表中显示的为好。如何避免这种情况或以其它方式 - 有没有什么办法,以显示对ComboBox自定义文本没有选择项目时?

下面工作时,答案是ComboBoxStyle设置为DropDownComboBox是可编辑的)。有没有可能当ComboBoxStyle设置为DropDownList做到这一点?

c# winforms .net-2.0
16个回答
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;
            }
        }

0
投票

如果ComboBoxStyle设置为DropDownList那么最简单的方式,以确保用户选择的产品设定SelectedIndex = -1,这将是空的


0
投票

我意识到这是一个古老的线程,但只是想让其他人谁可能会寻找一个答案,这个问题的认识,在Visual Studio(2015年)的当前版本中,有一个名为“占位符文本”,做了最初jotbek财产问。使用属性对话框,在“公共”性质。


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

0
投票

我希望能找到一个解决这一点。我看到这是一个老帖子,但希望我的做法可能会简化这个问题别人。

我是用一个下拉的DropDownList的风格的组合框,但这应该与其他款式工夫。在我的情况,我想文本阅读“选择源”,我想其他的选项是“文件”和“文件夹”

comboBox1.Items.AddRange(new string[] {"Select Source", "File", "Folder" });
comboBox1.Text = "Select Source";

您可以选择0指数,而不是如果你喜欢。当如果该文本是可见的索引改变它不再是问题我再去掉了“选择源”项目。

comboBox1.SelectedIndexChanged += new EventHandler(comboBox1_IndexChanged);

private void comboBox1_IndexChanged(object sender, EventArgs e)
    {
        comboBox1.Items.Remove("Select Source");
        if (comboBox1.SelectedIndex != -1)
        {
            if (comboBox1.SelectedIndex == 0) // File
            {
                // Do things
            }
            else if (comboBox1.SelectedIndex == 1) // Folder
            {
                // Do things
            }
        }
    }

谢谢


0
投票

这适用于DropDownList的风格 - 创建一个从组合框派生的类 (重建后,将出现在工具箱),其中提请使用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);
           }
    }
}

0
投票

我不能让@Andrei Karcheuski的方式来工作,但他启发了我这个方法:(我加的本地化属性,因此提示可以通过.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;
        }
    }

-3
投票

为什么不去做呢XAML?

<ComboBox x:Name="myComboBoxMenu" PlaceholderText="Hello"/>

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表示没有做出选择。


4
投票
    private void comboBox1_TextChanged(object sender, EventArgs e)
    {
        if (comboBox1.Text == "")
            comboBox1.Text = "Select one of the answers"; 
    }

应该做在启动时的伎俩这条线是目前在组合框中选择项目时,该项目中的文字会出现。 deleling文本时,本文将再次出现


4
投票

我看不到任何本地.NET的方式来做到这一点,但如果你想获得你的手脏与底层的Win32控制...

你应该能够与CB_GETCOMBOBOXINFO结构将包含内部编辑控件的句柄发送的COMBOBOXINFO消息。然后,您可以用字符串指针发送的编辑控件EM_SETCUEBANNER消息。 (请注意,这至少需要启用XP和视觉样式。


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

如果您使用数据绑定,你必须创建你一定类型的虚拟版本 - 只要确保你的任何持久性逻辑之前将其删除。


1
投票

让组合框的DropDownStyle属性到下拉列表并设置组合框的文本为“选择”,如下

            combobox.DataSource = dsIn.Tables[0];
            combobox.DisplayMember = "Name";
            combobox.ValueMember = "Value";
            combobox.Text = "--Select--";

1
投票

形式InitializeComponent();后,一号线

cbo_MyDropBox.Text = "Select a server...";

你只需要一次吗?所有你需要做的,如果一个选择是强制性的检查框指数!= -1。谁能阐述为什么其他的答案跳火圈得到这是怎么回事?

我在这里失踪的唯一的事情是有变灰只是这个初始文本。如果你真的想要,只是使用标签在前面,一旦指数改变将其关闭。


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

0
投票

在这里,你可以找到pavlo_ua创建解决方案:If you have .Net > 2.0If you have .Net == 2.0 (search for pavlo_ua answer)

干杯,JBK

编辑:那么,有明确的答案不只是链接

当其样式设置为下拉您可以设置组合框的文本(它是可编辑的)。当你有.NET版本<3.0没有IsReadOnly属性,所以我们需要用胜利API以只读方式设置组合框的文本框:

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 );
}
© www.soinside.com 2019 - 2024. All rights reserved.