2010-10-28 117 views
4
public partial class Form1 : Form 
{ 
    MyClass myClass = new MyClass("one", "two"); 

    public Form1() 
    { 
     InitializeComponent(); 
     textBox1.DataBindings.Add("Text", myClass, "Text1", false, DataSourceUpdateMode.Never); 
     textBox2.DataBindings.Add("Text", myClass, "Text2", false, DataSourceUpdateMode.Never); 
    } 

    private void saveButton_Click(object sender, EventArgs e) 
    { 
     myClass.Text1 = textBox1.Text; 
     myClass.Text2 = textBox2.Text; 
     //textBox1.DataBindings["Text"].WriteValue(); 
     //textBox2.DataBindings["Text"].WriteValue(); 
    } 
} 

public class MyClass : INotifyPropertyChanged 
{ 
    private string _Text1; 
    private string _Text2; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public string Text1 
    { 
     get { return _Text1; } 
     set { _Text1 = value; OnPropertyChanged(new PropertyChangedEventArgs("Text1")); } 
    } 

    public string Text2 
    { 
     get { return _Text2; } 
     set { _Text2 = value; OnPropertyChanged(new PropertyChangedEventArgs("Text2")); } 
    } 

    public MyClass(string text1, string text2) 
    { 
     Text1 = text1; 
     Text2 = text2; 
    } 

    protected void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     if (PropertyChanged != null) PropertyChanged(this, e); 
    } 
} 

我想我很清楚自己想要達到什麼目的。我希望我的表單將我在兩個TextBoxES中所做的更改保存到myClass。但是,無論何時在編輯兩個文本框後按下保存按鈕,並且調用saveButton_Click,第二個textBox2Text都會返回原始文本(「2」)。我嘗試使用BindingWriteValue函數,但同樣的事情發生。使用.net 4.0。DataBindings有問題,請解釋一下

編輯感謝您的回答,但我不需要解決方法。我可以自己找到它們。我只需要更好地理解綁定是如何工作的。我想了解爲什麼會發生這種情況?

回答

5

顯然,更新數據源上的任何值都會導致更新所有綁定。這解釋了行爲(設置myClass.Text1導致textBox2用當前值myClass.Text2更新)。不幸的是,我幾乎可以找到的幾篇文章只是說,「這就是它的工作原理」。

處理此問題的一種方法是創建一個BindingSource,BindingSource.DataSource = myClass,然後將您的TextBoxes綁定到BindingSource

BindingSource引發ListChanged事件,如果基礎數據源是一個列表和項目被添加,刪除等,如果DataSource性質發生變化。您可以通過將BindingSource.RaiseListChangedEvents設置爲false來禁止這些事件,這會允許您在沒有數據綁定更新綁定控件的情況下在myClass上設置多個屬性。

public partial class Form1 : Form 
{ 
    MyClass myClass = new MyClass("one", "two"); 
    BindingSource bindingSource = new BindingSource(); 

    public Form1() 
    { 
     InitializeComponent(); 

     bindingSource.DataSource = myClass; 

     textBox1.DataBindings.Add("Text", bindingSource, "Text1", true, DataSourceUpdateMode.Never); 
     textBox2.DataBindings.Add("Text", bindingSource, "Text2", true, DataSourceUpdateMode.Never);     
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     bindingSource.RaiseListChangedEvents = false; 
     myClass.Text1 = textBox1.Text; 
     myClass.Text2 = textBox2.Text; 
     bindingSource.RaiseListChangedEvents = true; 
    } 
} 

HTH

+0

工作。但我不明白爲什麼如果我的屬性不是列表的一部分。 – Juan 2010-10-29 02:08:00

+0

@jsoldi,我編輯了我的答案,以包含「DataCource」屬性更改時也引發'ListChanged'的事實。 – 2010-10-29 03:20:07

1

你需要改變你的數據綁定方式。嘗試這個。

MyClass myClass = new MyClass("one", "two"); 

public Form1() 
{ 
    InitializeComponent(); 
    textBox1.DataBindings.Add("Text", myClass, "Text1", false, DataSourceUpdateMode.OnPropertyChanged); 
    textBox2.DataBindings.Add("Text", myClass, "Text2", false, DataSourceUpdateMode.OnPropertyChanged); 
} 

private void saveButton_Click(object sender, EventArgs e) 
{ 
    // your object should already have new text values entered. 
    // Save your object! 

    //myClass.Text1 = textBox1.Text; 
    //myClass.Text2 = textBox2.Text; 
    //textBox1.DataBindings["Text"].WriteValue(); 
    //textBox2.DataBindings["Text"].WriteValue(); 
} 

的關鍵是DataSourceUpdateMode,這將使文本框的文本屬性級聯到您的自定義對象屬性發生變化時。我希望這有幫助。

[編輯]

我相信你需要做的,達到你問的這是什麼: TextBox1.DataBindings[0].ControlUpdateMode = ControlUpdateMode.Neverlink應該提供一些額外的信息。

+1

但我不想當'TextBox'的'Text'的變化,我想在按下保存按鈕,當它改變要保存的數據。我怎樣才能做到這一點?不是'DataSourceUpdateMode.Never'和'WriteValue()'一起實現這種功能嗎? – Juan 2010-10-28 18:27:33

+0

請勿使用數據綁定。只需在表單構造函數中手動分配文本值到文本框中,如下所示:'textBox1.Text = myClass.Text1;' – James 2010-10-28 18:28:55

+0

@jsoldi - 然後不對這些值使用數據綁定 - 設置saveButton_Click事件中的值。這就是數據綁定的目的 - 它將控件實例的屬性綁定到數據對象的屬性。 – JeremyDWill 2010-10-28 18:31:47