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

Posted

技术标签:

【中文标题】选择项目时替换 ComboBox 中的文本【英文标题】:Replace text in ComboBox upon selecting an item 【发布时间】:2012-10-10 16:34:37 【问题描述】:

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

            //..

【问题讨论】:

显示文本看起来不正常是什么或如何......? 您是否尝试过捕获 SelectedItemIndex 以便您确切知道要设置哪个 combox.Text..? 如果它不能正常工作,则文本与我没有剥离文本完全相同。我不太明白你的第二条评论,因为设置 Text 属性在任何情况下都不起作用。 您是否使用 %ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\(所有用户)减去(所有用户)存储路径,请澄清 不,下拉列表中的路径包括(All Users),我想删除它并在组合框的文本字段中仅显示路径(无(All Users))。 【参考方案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】:

我建议您创建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 了解更多关于 DataSourceDisplayMemberValueMember 的信息。

【讨论】:

这是个好主意,但它仍然不能解决我的实际问题。如果我现在从下拉列表中选择一个项目,例如(All Users) 选择项目后 ComboBox 可编辑部分中的文本仍将是 (All Users),而不是 %ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs【参考方案3】:

这可能不是最优雅的解决方案,但对于像我这样的初学者来说是一个简单的解决方案,他们不想在更好地理解它们之前使用这些 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;
        
    

【讨论】:

【参考方案4】:

红隼,

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

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

        DropDownList1.Items[index].Text = "changed";
    

【讨论】:

从哪里获得 DropDownList 对象?我使用 ComboBox 中的“集成”。 DropDownList 和你的组合框对象是一样的,对吧? @Daniel redfalcon 说他的 ComboBox 是可编辑的。所以我怀疑他将 combobox.DropDownStyle 设置为 ComboBoxStyle.DropDown 并且他能够更改文本。这就是为什么我不赞成你的回答。【参考方案5】:

` 私人无效组合框_TextChanged(对象发送者,EventArgs e) //..

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

        //..

`

【讨论】:

combobox.SelectedItem 没有 Text 属性。请参阅MSDN 条目。

以上是关于选择项目时替换 ComboBox 中的文本的主要内容,如果未能解决你的问题,请参考以下文章

关于EasyUI ComboBox(下拉列表框)能否直接输入文本的问题,详情如图所示。

选择后 ComboBox QML 不显示项目文本

如何使用 Powershell 将 ComboBox 选定文件附加到 TextBox?

从 C# 中的 Combobox 中选择特定项目时,将 Label 值增加 1

ComboBox:如果操作员键入文本,然后按回车,则发生哪个事件

更改 ComboBox 文本但未选择项