2012-10-10 49 views
0

我有一个应该包含路径的可编辑组合框。用户可以从下拉列表中选择多个默认路径(或输入他自己的路径),例如%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; 

      //.. 
} 
+1

什么或如何显示文本看就是不能正常工作..? – MethodMan

+0

和你有没有尝试捕获SelectedItemIndex,以便你确切知道哪些combox.Text设置..? – MethodMan

+0

如果它没有正常工作,那么文本就和我没有删除文本一样。我不太了解你的第二个评论,因为设置Text属性在任何情况下都不起作用。 – Lennart

回答

1

I found the solution in a similar question,通过使用的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的需要待装载或所示的控制,这如果该计划刚刚开始,情况并非一定如此。从here得到。

0

redfalcon,

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

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

     DropDownList1.Items[index].Text = "changed"; 
    } 
+0

我从哪里得到DropDownList对象?我使用ComboBox中的“集成”。 – Lennart

+0

DropDownList和你的combobox对象是一样的吗? – Daniel

+0

@Daniel redfalcon说他的ComboBox是可编辑的。所以我怀疑他将combobox.DropDownStyle设置为ComboBoxStyle.DropDown,他可以更改文本。这就是为什么我低估了你的答案。 –

0

` 私人无效combobox_TextChanged(对象发件人,EventArgs的){ // ..

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

     //.. 

} `

+0

combobox.SelectedItem没有Text属性。请参阅[MSDN](http://msdn.microsoft.com/zh-cn/library/system.windows.forms.combobox.selecteditem.aspx)条目。 – Lennart

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

您可能想详细了解如何DataSource,从MSDN DisplayMemberValueMember

+0

这是一个不错的主意,但它仍然不能解决我的实际问题。如果我现在从下拉列表中选择一个项目,例如'(所有用户)'在选择项目后,ComboBox的可编辑部分中的文本仍然是'(所有用户)',而不是'%ProgramData%\\ Microsoft \\ Windows \\开始菜单\\程序」。 – Lennart

+0

@Lennart我已经更新了我的答案。 –

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; 
     } 
    } 
相关问题