Winforms Textbox with two way DataBinding not working as it should be
Winforms has two Textboxes. textBox2
is binded to a property Unit.
I wish that any changes made to Unit or textBox2
will automatically update textBox2
or Unit respectively. But it does not.
Here are three versions of the code for a Winform.
Version one set data binding, hope it will have two ways auto update but does not work
public partial class Receiver : Form, INotifyPropertyChanged
{
private int unit=0;
public int Unit
{
get { return unit; }
set
{
if (value != unit)
{
unit = value;
}
}
}
public Receiver()
{
InitializeComponent();
textBox2.DataBindings.Add("Text", Unit, "Unit");
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
//textBox1 change makes Unit change,
//I wish the change will be displayed in textBox2 automatically
Unit = Convert.ToInt32(textBox1.Text);
}
}
Versio开发者_如何转开发n two with event handler , hard code to update textBox2
with the event handler
but change textBox2
still will not update Unit automatically
public partial class Receiver : Form, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int unit=0;
public int Unit
{
get { return unit; }
set
{
if (value != unit)
{
unit = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
}
public Receiver()
{
InitializeComponent();
textBox2.DataBindings.Add("Text", this.Unit, "Unit", false,
DataSourceUpdateMode.OnPropertyChanged);
PropertyChanged += new PropertyChangedEventHandler(OnPropertyChanged);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
Unit = Convert.ToInt32(textBox1.Text);
}
private void OnPropertyChanged(object sender, EventArgs e)
{
//this actually is hard coded to update textBox2, binding does no help
textBox2.Text = Unit.ToString();
}
}
Version three why use event handler, we can simply do this way.
public partial class Receiver : Form, INotifyPropertyChanged
{
private int unit=0;
public int Unit
{
get { return unit; }
set
{
if (value != unit)
{
unit = value;
textBox2.text = unit.toString();
}
}
}
public Receiver()
{
InitializeComponent();
textBox2.DataBindings.Add("Text", Unit, "Unit");
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
Unit = Convert.ToInt32(textBox1.Text);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
Unit = Convert.ToInt32(textBox2.Text);
}
}
}
Version two and Version three have a problem, any changes to textbox1
will cause update in textbox2
. That will cause a lot of CPU cycle. The best way is when the mouse focus leaves textBox1
then do the update. So how to do it?
The problem in your code is at line:
textBox2.DataBindings.Add("Text", Unit, "Unit");
You should replace the data source by the instance that holds that property not the property itself, and here you should also specify the data source update mode set it to DataSourceUpdateMode.OnPropertyChanged
. So:
textBox2.DataBindings.Add("Text", this, "Unit", false, DataSourceUpdateMode.OnPropertyChanged);
//test using the second or the third approach:
Unit = 15;//now the textBox2.Text equals to 15 too.
textBox2.Text = 12;//now Unit equals 12 too
精彩评论