选择项目时替换ComboBox中的文本

时间:2012-10-10 16:34:38

标签: c# combobox

我有一个可编辑的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; 

            //..
}

5 个答案:

答案 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了解更多资源DataSourceDisplayMemberValueMember

答案 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; 

        //..

} `