2009-08-07 9 views
0

데이터 바인딩을 사용하여 간단한 예제를 만들었습니다 (불행히도 우리 시스템에서는 비슷한 경우가 있습니다). 나는 펑키 콤보 박스 생성 : 클릭 할 때데이터 바인딩이 업데이트되지 않습니다.

public class FunkyComboBox : ComboBox 
{ 
    private object currentValue = null; 

    public FunkyComboBox() 
    { 
     if (LicenseManager.UsageMode == LicenseUsageMode.Runtime) 
      this.Items.Add("Other..."); 
    } 

    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
     if (!this.Text.StartsWith("Other") && currentValue != this.SelectedItem) 
     { 
      currentValue = this.SelectedItem; 
      BindingManagerBase bindingManager = DataManager; 
      base.OnSelectedIndexChanged(e); 
     } 
    } 

    protected override void OnSelectionChangeCommitted(EventArgs e) 
    { 
     string itemAsStr = this.SelectedItem != null ? SelectedItem.ToString() : ""; 
     if (itemAsStr.StartsWith("Other")) 
     { 
      string newItem = "item" + this.Items.Count; 
      if (!Items.Contains(newItem)) 
      { 
       Items.Add(newItem); 
      } 
      SelectedItem = newItem; 
     } 
     else 
     { 
      OnSelectedIndexChanged(e); //forces a selectedIndexChanged event to be thrown 
      base.OnSelectionChangeCommitted(e); 
     } 
    } 
} 

새로운 항목을 추가 다른 (당신이 데이터베이스 등을 조회 할 수있는 양식을 여는 우리의 시스템에서).

public class MyClass 
{ 
    private string value; 
    public string MyData 
    { 
     get{ return value;} 
     set{ this.value = value;} 
    } 
} 

그리고이 개체에 바인딩이 컨트롤 테스트 양식 (제거 일부 디자이너 코드) : : 그럼 난 간단한 데이터 개체가

public partial class Form1 : Form 
{ 
    MyClass myObj = new MyClass(); 
    public Form1() 
    { 
     InitializeComponent(); 
     myObj.MyData = "Nothing"; 
     myClassBindingSource.DataSource = myObj; 
    } 

    private void InitializeComponent() 
    { 
     this.components = new System.ComponentModel.Container(); 
     this.textBox1 = new System.Windows.Forms.TextBox(); 
     this.myClassBindingSource = new System.Windows.Forms.BindingSource(this.components); 
     this.funkyComboBox1 = new DataBindingTests.FunkyComboBox(); 
     ((System.ComponentModel.ISupportInitialize)(this.myClassBindingSource)).BeginInit(); 
     this.SuspendLayout(); 
     // 
     // textBox1 
     // 
     this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 

     // 
     // myClassBindingSource 
     // 
     this.myClassBindingSource.DataSource = typeof(DataBindingTests.MyClass); 
     // 
     // funkyComboBox1 
     // 
     this.funkyComboBox1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedItem", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 
     this.funkyComboBox1.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.myClassBindingSource, "MyData", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 
     // 
     // Form1 
     // 
     this.Controls.Add(this.textBox1); 
     this.Controls.Add(this.funkyComboBox1); 
     ((System.ComponentModel.ISupportInitialize)(this.myClassBindingSource)).EndInit(); 
     this.ResumeLayout(false); 
     this.PerformLayout(); 
    } 

    private FunkyComboBox funkyComboBox1; 
    private System.Windows.Forms.BindingSource myClassBindingSource; 
    private System.Windows.Forms.TextBox textBox1; 
} 

이 코드를 실행하고 노는 시작하는 경우 콤보 상자를 클릭하면 편집 상자가 변경된다는 것을 알 수 있습니다. 모든 변경 후 null 값이 내 개체로 설정되고 텍스트 상자가 지워집니다. 모든 변경 후에 올바른 값을 설정하려면 어떻게해야합니까?

답변

0

기본 ComboBox에도 버그가있는 것 같습니다. 이 바인딩 소스가 제대로 작동하지 않을 수 있습니다.

+0

데이터 소스로 설정 한 데이터 구조가 IBindingList (http://msdn.microsoft.com/en-us/library/system.componentmodel.ibindinglist%28v=)를 구현해야하는 것처럼 비슷한 것으로 나타났습니다. vs.110 % 29.aspx) 이러한 구조 중 하나는 BindingList (http://msdn.microsoft.com/en-us/library/ms132679%28v=vs.110%29.aspx)입니다. – aolszowka

2

왜 ComboBox 데이터 바인딩이 이런 식으로 동작하는지 잘 모르겠지만 해결 방법을 찾았습니다. ComboBox 값에 데이터 소스를 사용하지 않으면 데이터 바인딩이 올바르게 작동하지 않는 것처럼 보입니다.

FunkyComboBox에 약간의 변경을 가하고 예상대로 작동합니다.

public class FunkyComboBox : ComboBox 
{ 
    private object currentValue = null; 
    private List<string> innerItems = new List<string>(); 

    public FunkyComboBox() 
    { 
     if (LicenseManager.UsageMode == LicenseUsageMode.Runtime) 
      innerItems.Add("Other..."); 

     this.DataSource = innerItems; 
    } 

    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
     if (!this.Text.StartsWith("Other") && currentValue != this.SelectedItem) 
     { 
      currentValue = this.SelectedItem; 
      BindingManagerBase bindingManager = DataManager; 
      base.OnSelectedIndexChanged(e); 
     } 
    } 

    protected override void OnSelectionChangeCommitted(EventArgs e) 
    { 
     string itemAsStr = this.SelectedItem != null ? SelectedItem.ToString() : ""; 
     if (itemAsStr.StartsWith("Other")) 
     { 
      string newItem = "item" + this.Items.Count;     
      if(!innerItems.Contains(newItem)) 
      { 
       innerItems.Add(newItem); 
       this.RefreshItems(); 
      } SelectedItem = newItem; 
     } 
     else 
     { 
      OnSelectedIndexChanged(e); 
      //forces a selectedIndexChanged event to be thrown    
      base.OnSelectionChangeCommitted(e); 
     } 
    } 
} 
관련 문제