2009-06-30 144 views
4

我有一个Winforms ComboBox,其中包含一个自定义类的实例。当这些项目首次添加到ComboBox的Items集合中时,将调用其中的每个方法的ToString方法。动态更改WinForms组合框中项目的文本

但是,当用户更改运行应用程序的语言时,ToString方法的结果会更改。

因此,我怎样才能让ComboBox再次调用所有项目上的ToString方法,而无需从ComboBox中删除所有项目并重新添加它们?

回答

5

由于svick,RefreshItems()工作,但是,因为它是受保护的(因此可以仅通过被称为一个子类),我不得不这样做

public class RefreshingComboBox : ComboBox 
{ 
    public new void RefreshItem(int index) 
    { 
     base.RefreshItem(index); 
    } 

    public new void RefreshItems() 
    { 
     base.RefreshItems(); 
    } 
} 

我刚刚为一个ToolStripComboBox控件做同样的,但它是一个有点困难,因为你不能子类Combro盒包含,我做了

public class RefreshingToolStripComboBox : ToolStripComboBox 
{ 
    // We do not want "fake" selectedIndex change events etc, subclass that overide the OnIndexChanged etc 
    // will have to check InOnCultureChanged them selfs 
    private bool inRefresh = false; 
    public bool InRefresh { get { return inRefresh; } } 

    public void Refresh() 
    { 
     try 
     { 
      inRefresh = true; 

      // This is harder then it shold be, as I can't get to the Refesh method that 
      // is on the embebed combro box. 
      // 
      // I am trying to get ToString recalled on all the items 
      int selectedIndex = SelectedIndex; 
      object[] items = new object[Items.Count]; 
      Items.CopyTo(items, 0); 

      Items.Clear(); 

      Items.AddRange(items); 
      SelectedIndex = selectedIndex; 
     } 
     finally 
     { 
      inRefresh = false; 
     } 
    } 

    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
     if (!inRefresh) 
     { 
      base.OnSelectedIndexChanged(e); 
     } 
    } 
} 

我必须做同样的行程停止不必要的事件正常CombroBox,通过重写OnSelectedValueChanged,OnSelectedItemChanged和OnSelectedIndexChanged,因为代码是一样的,因为我在这里没有包括它的ToolStripComboBox控件。

+0

我有完全一样的情况,我有同样的想法,和我有同样的解决方案在另一篇文章中(`RefreshItems()`),但它失败了。当你写它对你有用时,我发现了唯一的区别:我使用了一个值类型(c#struct,C++ cli value class)而不是引用类型(c#class,C++ cli ref class)。更改为引用类型后,它也适用于我。 – 2017-03-11 09:54:48

1

你应该可以通过调用RefreshItems()方法来做到这一点。

1

svick是对的。但是,如Ian Ringrose所述,子类是必需的。 RefreshItems是System.Windows.Forms.ComboBox的受保护方法。

A表格以下申请提供了行为的一个例子,并且RefreshItems方法更新所述组合框:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsApplication1 
{ 
    public class Form1 : Form 
    { 
     private List<HelloWorld> helloWorlds; 

     #region Form1.Designer.cs 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.comboBox1 = new RefreshingComboBox(); 
      this.comboBox2 = new RefreshingComboBox(); 
      this.label1 = new System.Windows.Forms.Label(); 
      this.label2 = new System.Windows.Forms.Label(); 
      this.button1 = new System.Windows.Forms.Button(); 
      this.button2 = new System.Windows.Forms.Button(); 
      this.button3 = new System.Windows.Forms.Button(); 
      this.SuspendLayout(); 
      // 
      // comboBox1 
      // 
      this.comboBox1.FormattingEnabled = true; 
      this.comboBox1.Location = new System.Drawing.Point(76, 12); 
      this.comboBox1.Name = "comboBox1"; 
      this.comboBox1.Size = new System.Drawing.Size(115, 21); 
      this.comboBox1.TabIndex = 0; 
      // 
      // comboBox2 
      // 
      this.comboBox2.FormattingEnabled = true; 
      this.comboBox2.Location = new System.Drawing.Point(250, 12); 
      this.comboBox2.Name = "comboBox2"; 
      this.comboBox2.Size = new System.Drawing.Size(218, 21); 
      this.comboBox2.TabIndex = 1; 
      // 
      // label1 
      // 
      this.label1.AutoSize = true; 
      this.label1.Location = new System.Drawing.Point(12, 15); 
      this.label1.Name = "label1"; 
      this.label1.Size = new System.Drawing.Size(58, 13); 
      this.label1.TabIndex = 2; 
      this.label1.Text = "Language:"; 
      // 
      // label2 
      // 
      this.label2.AutoSize = true; 
      this.label2.Location = new System.Drawing.Point(213, 15); 
      this.label2.Name = "label2"; 
      this.label2.Size = new System.Drawing.Size(31, 13); 
      this.label2.TabIndex = 3; 
      this.label2.Text = "Text:"; 
      // 
      // button1 
      // 
      this.button1.Location = new System.Drawing.Point(34, 42); 
      this.button1.Name = "button1"; 
      this.button1.Size = new System.Drawing.Size(75, 23); 
      this.button1.TabIndex = 4; 
      this.button1.Text = "Set All"; 
      this.button1.UseVisualStyleBackColor = true; 
      this.button1.Click += new System.EventHandler(this.button1_Click); 
      // 
      // button2 
      // 
      this.button2.Location = new System.Drawing.Point(116, 42); 
      this.button2.Name = "button2"; 
      this.button2.Size = new System.Drawing.Size(75, 23); 
      this.button2.TabIndex = 5; 
      this.button2.Text = "Set Random"; 
      this.button2.UseVisualStyleBackColor = true; 
      this.button2.Click += new System.EventHandler(this.button2_Click); 
      // 
      // button3 
      // 
      this.button3.Location = new System.Drawing.Point(393, 42); 
      this.button3.Name = "button3"; 
      this.button3.Size = new System.Drawing.Size(75, 23); 
      this.button3.TabIndex = 6; 
      this.button3.Text = "Refresh!"; 
      this.button3.UseVisualStyleBackColor = true; 
      this.button3.Click += new System.EventHandler(this.button3_Click); 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(556, 77); 
      this.Controls.Add(this.button3); 
      this.Controls.Add(this.button2); 
      this.Controls.Add(this.button1); 
      this.Controls.Add(this.label2); 
      this.Controls.Add(this.label1); 
      this.Controls.Add(this.comboBox2); 
      this.Controls.Add(this.comboBox1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 
      this.PerformLayout(); 

     } 

     #endregion 

     private System.Windows.Forms.ComboBox comboBox1; 
     private System.Windows.Forms.ComboBox comboBox2; 
     private System.Windows.Forms.Label label1; 
     private System.Windows.Forms.Label label2; 
     private System.Windows.Forms.Button button1; 
     private System.Windows.Forms.Button button2; 
     private System.Windows.Forms.Button button3; 

     #endregion 

     public Form1() 
     { 
      InitializeComponent(); 

      comboBox1.DataSource = new HelloWorld().GetLanguages(); 

      helloWorlds = new List<HelloWorld>(); 
      while (helloWorlds.Count < 10) 
      { 
       helloWorlds.Add(new HelloWorld()); 
      } 

      comboBox2.DataSource = helloWorlds; 
     } 

     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 

     private void changeAllLanguages() 
     { 
      HelloWorld.LanguageValue newLang = (HelloWorld.LanguageValue) comboBox1.SelectedValue; 

      helloWorlds.ForEach(
       delegate(HelloWorld hw) 
       { 
        hw.Language = newLang; 
       }); 

     } 

     private void changeRandomLanguage() 
     { 
      int index = new Random().Next(helloWorlds.Count); 
      HelloWorld.LanguageValue newLang = (HelloWorld.LanguageValue) comboBox1.SelectedValue; 

      helloWorlds[index].Language = newLang; 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      changeAllLanguages(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      changeRandomLanguage(); 
     } 

     private void button3_Click(object sender, EventArgs e) 
     { 
      (comboBox2 as RefreshingComboBox).RefreshItems(); 
     } 
    } 

    public class RefreshingComboBox : System.Windows.Forms.ComboBox 
    { 
     public new void RefreshItem(int index) 
     { 
      base.RefreshItem(index); 
     } 

     public new void RefreshItems() 
     { 
      base.RefreshItems(); 
     } 
    } 

    public class HelloWorld 
    { 
     public enum LanguageValue 
     { 
      English, 
      日本語, 
      Deutsch, 
      Français, 
      Český 
     } 

     private LanguageValue language; 

     public LanguageValue Language 
     { 
      get 
      { 
       return language; 
      } 
      set 
      { 
       language = value; 
      } 
     } 

     public Array GetLanguages() 
     { 
      return Enum.GetValues(typeof(LanguageValue)); 
     } 

     Dictionary<LanguageValue, string> helloWorlds; 

     public HelloWorld() 
     { 
      helloWorlds = new Dictionary<LanguageValue, string>(); 
      helloWorlds[LanguageValue.English] = "Hello, world!"; 
      helloWorlds[LanguageValue.日本語] = "こんにちは、世界!"; 
      helloWorlds[LanguageValue.Deutsch] = "Hallo, Welt!"; 
      helloWorlds[LanguageValue.Français] = "Sallut, monde!"; 
      helloWorlds[LanguageValue.Český] = "Ahoj svět!"; 
     } 

     public override string ToString() 
     { 
      return helloWorlds[language]; 
     } 
    } 
} 
1

我使用这个扩展:

 /// <summary> 
     /// Recreates the items 
     /// </summary> 
     public static void RefreshItems(this ComboBox cb) 
     { 
      var selectedIndex = cb.SelectedIndex; 
      cb.SelectedIndex = -1;    
      MethodInfo dynMethod = cb.GetType().GetMethod("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance); 
      dynMethod.Invoke(cb, null); 
      cb.SelectedIndex = selectedIndex; 

     } 
相关问题