0

我有一个应包含路径的可编辑组合框。用户可以从下拉列表中选择多个默认路径(或输入自己的路径),例如%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\ (All Users). 下拉列表中的项目包含一个简短的解释,如(All Users)前一个示例中的部分。选择此类项目后,我想删除此说明,以便在 ComboBox 中显示有效路径。

我目前从字符串中去除解释,并尝试通过设置TextComboBox 的属性来更改文本。但这不起作用,字符串被正确解析,但显示的文本不会更新(它与下拉列表中的内容相同,并带有解释)。

private void combobox_TextChanged(object sender, EventArgs e) {
            //..             

               string destPath = combobox.GetItemText(combobox.SelectedItem);                  
               destPath = destPath.Replace("(All Users)", "");                   
               destPath.Trim();                   
               combobox.Text = destPath; 

            //..
}
4

5 回答 5

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

并更新您的表单的构造函数,如下所示:

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

您可能想了解更多 about和DataSourceMSDN 。DisplayMemberValueMember

于 2012-10-10T17:34:17.413 回答
1

我通过使用 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 需要加载或显示控件,如果程序刚刚启动,则不一定是这种情况。从这里得到。

于 2012-10-11T10:25:33.703 回答
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;
        }
    }
于 2013-06-20T11:59:34.157 回答
0

红隼,

您不能以这种方式更改文本。您需要做的是获取 selectedindex 值,然后设置 Text 属性。像这样的东西:

 protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        var index = DropDownList1.SelectedIndex;

        DropDownList1.Items[index].Text = "changed";
    }
于 2012-10-10T17:06:42.230 回答
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; 

        //..

} `

于 2012-10-10T17:16:38.763 回答