[英]How to Show text in combobox when no item selected like “..Select room…”
[英]How to show text in combobox when no item selected?
C# &.Net 2.0 問題 (WinForms)
我在ComboBox
中有一組項目,但沒有選擇。 在那種情況下,我想在組合“ Please select item ”上顯示一個字符串。
當前的實現只是在索引0上添加帶有此類文本的空項目,並在用戶 select 以下項目之一時將其刪除。 不幸的是,空項目也顯示在下拉列表中。 如何避免這種情況或以其他方式 - 當沒有選擇任何項目時,有沒有辦法在ComboBox
上顯示自定義文本?
當ComboBoxStyle
設置為DropDown
( ComboBox
是可編輯的)時,下面的答案有效。 當ComboBoxStyle
設置為DropDownList
時是否有可能這樣做?
使用組合框的插入方法將“請選擇項目”插入到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;
}
}
必須將功勞歸功於 IronRazerz ,以響應TextBox 水印 (CueBanner),當用戶在單行 TextBox(不適用於 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
,就像原始海報的問題一樣。
這應該會導致如下結果:
我看不到任何原生的 .NET 方式來做到這一點,但如果你想用底層的 Win32 控件弄臟你的手......
你應該能夠給它發送CB_GETCOMBOBOXINFO
與消息COMBOBOXINFO
結構,其中將包含內部編輯控件的句柄。 然后,您可以向編輯控件發送帶有指向字符串的指針的EM_SETCUEBANNER
消息。 (請注意,這至少需要啟用 XP 和視覺樣式。
private void comboBox1_TextChanged(object sender, EventArgs e)
{
if (comboBox1.Text == "")
comboBox1.Text = "Select one of the answers";
}
應該在啟動時完成此行,當在組合框中選擇一個項目時,將出現此項目文本。 刪除文本時,此文本將再次出現
這是我如何做到的。 它可能不是最好的方法,並且提供的控制最少; 但是,它簡單快捷,我認為分享它可能是個好主意,以便其他人可以使用更多選擇。
<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 表示沒有進行選擇。
我使用了一個快速解決方法,這樣我就可以保持 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;
}
}
}
如果您使用數據綁定,您將必須創建一個您綁定的類型的虛擬版本 - 只需確保在任何持久性邏輯之前將其刪除。
將組合框的 Dropdownstyle 屬性設置為 Dropdown 並將組合框文本設置為“選擇”,如下所示
combobox.DataSource = dsIn.Tables[0];
combobox.DisplayMember = "Name";
combobox.ValueMember = "Value";
combobox.Text = "--Select--";
表格InitializeComponent();
后一行InitializeComponent();
cbo_MyDropBox.Text = "Select a server...";
你只需要一次吧? 如果選擇是強制性的,您需要做的就是檢查框索引是否為!= -1
。 任何人都可以詳細說明為什么其他答案跳過箍來實現這一目標?
我在這里唯一缺少的就是這個初始文本變灰了。 如果您真的想要,只需在前面使用一個標簽,並在索引更改后將其關閉。
如果以前的解決方案都不適合您,為什么不在組合框上添加一些驗證,例如,
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;
}
}
在這里您可以找到由 pavlo_ua 創建的解決方案: 如果您有 .Net > 2.0並且如果您有 .Net == 2.0(搜索 pavlo_ua 答案)
干杯,jbk
編輯:所以要有明確的答案,而不僅僅是鏈接
當組合框的樣式設置為 DropDown(並且它是可編輯的)時,您可以設置組合框的文本。 當您的 .Net 版本 < 3.0 時,沒有 IsReadonly 屬性,因此我們需要使用 win 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 );
}
如果ComboBoxStyle
設置為DropDownList
則確保用戶選擇項目的最簡單方法是設置SelectedIndex = -1
,它將為空
我意識到這是一個舊線程,但只是想讓其他可能搜索這個問題的答案的人知道,在當前版本的 Visual Studio(2015)中,有一個名為“Placeholder Text”的屬性,它最初執行 jotbek問了。 使用“通用”屬性下的“屬性”框。
不幸的是,以上都不適合我,所以我在組合框頂部添加了一個標簽,上面寫着“請選擇”。 我使用以下代碼來顯示和隱藏它:
當我初始化我的組合框時,如果沒有選定的值,我將它放在前面並設置文本:
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(); } }
我也希望找到解決方案。 我看到這是一篇較舊的帖子,但希望我的方法可以為其他人簡化這個問題。
我使用的是下拉樣式為 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
}
}
}
謝謝
這適用於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);
}
}
}
我無法獲得 @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;
}
}
將此 class 添加到您的解決方案中。 重建解決方案后,您將在工具箱中看到 ComboBoxPlus。 它適用於 DropDownList for DropDownStyle of comboBox。享受它。
class ComboBoxPlus : System.Windows.Forms.ComboBox
{
private const int CB_SETCUEBANNER = 0x1703;
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern int SendMessage(System.IntPtr hWnd, int msg, int wParam, [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]string lParam);
private string placeholder = string.Empty;
public string Placeholder
{
get { return placeholder; }
set
{
placeholder = value;
SendMessage(Handle, CB_SETCUEBANNER, 0, Placeholder);
}
}
}
為什么不做 XAML?
<ComboBox x:Name="myComboBoxMenu" PlaceholderText="Hello"/>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.