[英]Replace text in ComboBox upon selecting an item
我有一个应包含路径的可编辑ComboBox。 用户可以从下拉列表中选择几个默认路径(或输入自己的默认路径),例如%ProgramData%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\ (All Users)
。 下拉列表中的项目包含简短说明,例如前面示例中的(All Users)
部分。 选择此类项目后,我想删除此说明,以便在ComboBox中显示有效路径。
我目前将解释从字符串中删除,并尝试通过设置ComboBox的Text
属性来更改文本。 但这不起作用,字符串已正确解析,但显示的文本不会更新(与解释中的下拉列表相同)。
private void combobox_TextChanged(object sender, EventArgs e) {
//..
string destPath = combobox.GetItemText(combobox.SelectedItem);
destPath = destPath.Replace("(All Users)", "");
destPath.Trim();
combobox.Text = destPath;
//..
}
我建议您创建PathEntry
类以存储Path
及其Description
。
public sealed class PathEntry
{
public string Path { get; private set; }
public string Description { get; private set; }
public PathEntry(string path)
: this(path, path)
{
}
public PathEntry(string path, string description)
{
this.Path = path;
this.Description = description;
}
}
然后创建BindingList<PathEntry>
的实例,以存储所有已知的路径和描述。 稍后,您可以向其添加用户定义的路径。
private readonly BindingList<PathEntry> m_knownPaths =
new BindingList<PathEntry>();
并如下更新窗体的构造函数:
public YourForm()
{
InitializeComponent();
m_knownPaths.Add(new PathEntry("%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs",
"(All Users)"));
// TODO: add other known paths here
combobox.ValueMember = "Path";
combobox.DisplayMember = "Description";
combobox.DataSource = m_knownPaths;
}
private void combobox_DropDown(object sender, EventArgs e)
{
combobox.DisplayMember = "Description";
}
private void combobox_DropDownClosed(object sender, EventArgs e)
{
combobox.DisplayMember = "Path";
}
您可能想从MSDN了解更多关于DataSource
, DisplayMember
和ValueMember
信息。
我通过使用BeginInvoke() 在类似的问题中找到了解决方案
使用尼古拉的解决方案,我的方法现在看起来像这样:
private void combobox_SelectedIndexChanged(object sender, EventArgs e) {
if (combobox.SelectedIndex != -1) {
//Workaround (see below)
var x = this.Handle;
this.BeginInvoke((MethodInvoker)delegate { combobox.Text = combobox.SelectedValue.ToString(); });
}
}
这是必需的解决方法,因为BeginInvoke要求加载或显示控件,如果程序刚刚启动,则不一定是这种情况。 从这里得到的。
这可能不是最优雅的解决方案,但对于像我这样的初学者来说,这是一个简单的解决方案,他们不想在更了解它们之前先使用那些InvokeMethods。
布尔值是必需的,因为在为Items数组中的位置分配新的字符串(对象)时,将再次递归触发处理程序。
因为我正在研究完全相同的问题,所以我现在才知道。
只是分享:)
bool preventDoubleChange = false;
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (preventDoubleChange){
preventDoubleChange = false;
return;
}
preventDoubleChange = true;
switch (comboBox1.SelectedIndex)
{
case 0:
comboBox1.Items[0] = "ChangeToThisText";
break;
case 1:
comboBox1.Items[1] = "ChangeToThisText";
break;
default:
preventDoubleChange = false;
break;
}
}
...或者,如果您愿意使用“标记”字段,则可以避免布尔值造成的麻烦。 我认为第二种变化也更干净。
public Form1()
{
InitializeComponent();
comboBox1.Items.Add("Item One"); //Index 0
comboBox1.Items.Add("Item Two"); //Index 1
comboBox1.Items.Add("Item Three"); //Index 2
comboBox1.Items.Add("Item Four"); //Index 3
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.Tag != null && (int)comboBox1.Tag == comboBox1.SelectedIndex)
return;
switch (comboBox1.SelectedIndex)
{
case 0:
break;
case 1:
comboBox1.Tag = comboBox1.SelectedIndex;
comboBox1.Items[comboBox1.SelectedIndex] = "changed item 2";
break;
case 2:
comboBox1.Tag = comboBox1.SelectedIndex;
comboBox1.Items[comboBox1.SelectedIndex] = "changed item 3";
break;
case 3:
break;
default:
break;
}
}
雷德法肯
您不能以这种方式更改文本。 您需要做的是获取selectedindex值,然后设置Text属性。 像这样:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
var index = DropDownList1.SelectedIndex;
DropDownList1.Items[index].Text = "changed";
}
`private void combobox_TextChanged(object sender,EventArgs e){// ..
string destPath = combobox.SelectedItem.Text;
destPath = destPath.Replace("(All Users)", "");
destPath.Trim();
combobox.SelectedItem.Text = destPath;
//..
}`
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.