Problem with DataBindings, explain please
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 = textBox开发者_如何学C2.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);
}
}
I think is pretty clear what I'm trying to achieve. I want my form to save the changes made in my two TextBox
es to myClass
. But whenever I press the save button after editing both text boxes, and saveButton_Click
is invoked, the second textBox2
's Text
goes back to the original text ("two"). I tried using Binding
's WriteValue
function but the same thing happens. Using .net 4.0.
Edit Thanks for your answers, but I don't need workarounds. I can find them myself. I just need to understand a little bit better how binding works. I would like to understand why is this happening?
Apparently, updating any value on the data source will cause all bindings to be updated. This explains the behavior (setting myClass.Text1
causes textBox2
to be updated with the current value of myClass.Text2
). Unfortunately, the few posts I was able to find pretty much just said, "that's how it works".
One way to handle this is to create a BindingSource, set BindingSource.DataSource = myClass
, and then bind your TextBoxes to the BindingSource
.
BindingSource
raises ListChanged events if the underlying data source is a list and items are added, removed, etc., or if the DataSource
properties change. You can suppress these events by setting BindingSource.RaiseListChangedEvents to false
, which would let you set multiple properties on myClass
without data-binding updating the bound controls.
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
You need to change the way you are doing your data binding. Try this.
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();
}
The key is the DataSourceUpdateMode, this will allow the text property of the textbox to cascade into your custom object whenever the property changes. I hope this helps.
[Edit]
I believe what you need to do to achieve what you're asking for is this:
TextBox1.DataBindings[0].ControlUpdateMode = ControlUpdateMode.Never
This link should provide some additional information.
精彩评论