2010-10-28 121 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