2009-06-30 6 views
4

사용자 지정 클래스의 인스턴스를 포함하는 Winforms ComboBox이 있습니다. 항목이 ComboBox의 Items 컬렉션에 처음 추가되면 ToString 메서드는 각 메서드를 호출합니다.Winforms ComboBox에서 항목의 텍스트를 동적으로 변경합니다.

그러나 사용자가 응용 프로그램이 실행되는 언어를 변경하면 ToString 메서드의 결과가 변경됩니다.

따라서 ComboBox에서 모든 항목을 제거하지 않고 다시 모든 항목에 대해 ToString 메서드를 호출하여 다시 호출 할 수 있습니까?

답변

5

감사합니다, RefreshItems() 작업을 서브 클래스) 그러나 나는 당신이 내가

했다, 여기에 포함 된 Combro 상자를 서브 클래 싱 할 수 없기 때문에 조금 더 열심히했다, 난 그냥되는 ToolStripComboBox에 대해 동일한 작업을 수행해야했다

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

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

을해야했다

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

나는 코드가 내가 여기에 포함되지 않은 ToolStripComboBox의 경우와 동일로, OnSelectedValueChanged, OnSelectedItemChanged 및 OnSelectedIndexChanged를 재정 의하여 정상 CombroBox에 대한 원치 않는 이벤트를 중지 같은 여행을해야했다.

+0

를, 나는 같은 생각을했고, 저도 같은 솔루션은 다른 게시물에 발견했다 ('RefreshItems()')하지만, 실패했습니다. 그것이 당신을 위해 일한다고 썼을 때, 유일하게 남은 차이점을 발견했습니다 : 나는 참조 형 (C# class, C++ cli ref 클래스) 대신에 value 형 (C# struct, C++ cli value class)을 사용했습니다. 참조 유형으로 변경하면 나에게도 도움이됩니다. –

1

RefreshItems() 메서드를 호출하여이 작업을 수행 할 수 있어야합니다.

1

svick이 맞습니다. 그러나 Ian Ringrose에 언급 된 것처럼 하위 클래스가 필요합니다. RefreshItems는 System.Windows.Forms.ComboBox의 보호 된 메서드입니다.

A는 응용 프로그램이 아래의 문제의 예를 제공 양식 및 RefreshItems 방법은 콤보 업데이트 : 그렇게 만 호출 할 수 있습니다 (이 보호 그러나 같은 svick

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; 

     } 
관련 문제