2009-10-26 25 views
2

我需要的文本框,這將反映數據綁定字符串的變化。我嘗試了以下代碼:數據綁定文本框並不反映源變化

public partial class Form1 : Form 
{ 
    string m_sFirstName = "Brad"; 
    public string FirstName 
    { 
     get { return m_sFirstName; } 
     set { m_sFirstName = value; } 
    } 

    public Form1() 
    { 
     InitializeComponent(); 

     textBox1.DataBindings.Add("Text", this, "FirstName"); 
    } 

    private void buttonRename_Click(object sender, EventArgs e) 
    { 
     MessageBox.Show("before: " + FirstName); 
     FirstName = "John"; 
     MessageBox.Show("after: " + FirstName); 
    } 
} 

啓動應用程序後,textBox1正確填充了Brad。 我點擊按鈕,改名姓爲「約翰」(第二消息框證實了這一點)。 但textBox1仍然充滿了布拉德,而不是約翰。爲什麼?什麼會使這項工作?

回答

3

爲什麼數據綁定不反映你的變化的原因是因爲你要綁定哪些沒有被設計修改時,拋出事件簡單的System.String對象。

所以,你有兩個選擇。一種是在按鈕的Click事件中重新綁定值(請避免!)。另一種是創建一個自定義類,將執行INotifyPropertyChanged是這樣的:

public partial class Form1 : Form 
{ 
    public Person TheBoss { get; set; } 

    public Form1() 
    { 
     InitializeComponent(); 

     TheBoss = new Person { FirstName = "John" }; 

     textBox1.DataBindings.Add("Text", this, "TheBoss.FirstName"); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     TheBoss.FirstName = "Mike"; 
    } 


    public class Person : INotifyPropertyChanged 
    { 
     private string firstName; 

     public string FirstName 
     { 
      get 
      { 
       return firstName; 
      } 
      set 
      { 
       firstName = value; 
       NotifyPropertyChanged("FirstName"); 
      } 
     } 

     private void NotifyPropertyChanged(String info) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 

     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged; 

     #endregion 
    } 
} 

INotifyPropertyChanged的文檔:MSDN

0

您需要在點擊按鈕再次進行綁定,否則只有在形式實例運行一次。

補充:上面的語句是不是要求是正確的。它仍然有效(見下面的代碼),但是通過事件處理失敗了綁定的目的。

Binding binding1; //binding instance 
public Form1() 
{ 
    InitializeComponent(); 
    binding1 = textBox1.DataBindings.Add("Text", this, "FirstName"); //assign binding instance 
} 

private void buttonRename_Click(object sender, EventArgs e) 
{ 
    MessageBox.Show("before: " + FirstName); 
    FirstName = "John"; 
    textBox1.DataBindings.Remove(binding1); //remove binding instance 
    binding1 = textBox1.DataBindings.Add("Text", this, "FirstName"); //add new binding 
    MessageBox.Show("after: " + FirstName); 
} 
+0

我在我的例子了文本框,但也有數據綁定控件只讀(列表框,標籤,。 ..)。真的是「label1.DataBindings.Add(」Text「,this,」FirstName「);」與「label1.Text = FirstName;」相同???我仍然相信必須存在雙面約束。 – jing 2009-10-26 09:21:13

+0

@Jing,我的回答不適合您的需要。爲了工作,需要在添加另一個實例之前刪除數據綁定實例。其他答案給了你更好的設計。 – 2009-10-26 10:07:17

3

一種方法是添加一個FirstNameChanged事件,該事件將綁定數據綁定。然後在您更改財產時提出事件,並重新綁定。例如:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

public class DataBindingTest : Form 
{ 
    public event EventHandler FirstNameChanged; 

    string m_sFirstName = "Brad"; 
    public string FirstName 
    { 
     get { return m_sFirstName; } 
     set 
     { 
      m_sFirstName = value; 
      EventHandler handler = FirstNameChanged; 
      if (handler != null) 
      { 
       handler(this, EventArgs.Empty); 
      } 
     } 
    } 

    public DataBindingTest() 
    { 
     Size = new Size(100, 100); 
     TextBox textBox = new TextBox(); 
     textBox.DataBindings.Add("Text", this, "FirstName"); 

     Button button = new Button 
     { 
      Text = "Rename", 
      Location = new Point(10, 30) 
     }; 
     button.Click += delegate { FirstName = "John"; }; 
     Controls.Add(textBox); 
     Controls.Add(button); 
    } 

    static void Main() 
    { 
     Application.Run(new DataBindingTest()); 
    } 
} 

有可能是(例如使用INotifyPropertyChanged)做它的其他方式 - 我不以任何方式數據綁定專家。