我有一个可编辑的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;
//..
}
答案 0 :(得分:1)
我建议您创建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>();
按如下所示更新Form的构造函数:
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
。
答案 1 :(得分:1)
I found the solution in a similar question,使用BeginInvoke()
使用Nikolay的解决方案,我的方法现在看起来像这样:
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需要加载或显示控件,如果程序刚刚启动,则不一定如此。从here得到了。
答案 2 :(得分:1)
这可能不是最优雅的解决方案,但对于初学者来说也是一个简单的解决方案 - 就像我一样 - 在他们理解它们之前不想使用那些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;
}
}
答案 3 :(得分:0)
redfalcon,
您不能以这种方式更改文字。您需要做的是获取selectedindex值,然后设置Text属性。这样的事情:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
var index = DropDownList1.SelectedIndex;
DropDownList1.Items[index].Text = "changed";
}
答案 4 :(得分:0)
` private void combobox_TextChanged(object sender,EventArgs e) { // ..
string destPath = combobox.SelectedItem.Text;
destPath = destPath.Replace("(All Users)", "");
destPath.Trim();
combobox.SelectedItem.Text = destPath;
//..
} `