Blank data TextBox does not reflect source changes
I need a TextBox that will reflect the changes in the anchor string. I've tried the following code:
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);
}
}
After starting the application, textBox1 is correctly populated with Brad. I pressed the Button, it renamed FirstName to John (the second message confirms this). But textBox1 is still filled with Brad, not John. What for? What will it do?
source to share
The reason the DataBinding doesn't reflect your changes is because you are binding a simple System.String object that was not designed to change events on change.
So you have 2 options. One is to reset the value when in your button's Click event (please avoid!). Another is to create a custom class that will implement INotifyPropertyChanged like this:
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 documentation: MSDN
source to share
One way is to add an event FirstNameChanged
to which the data binding is bound. Then raise the event when you changed the property and it will be re-committed. For example:
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());
}
}
There may be other ways to do this (using for example INotifyPropertyChanged
) - I'm not a data binding expert by any means.
source to share
You need to do the data binding again when the button is clicked, otherwise it only fires once after the form is instantiated.
To add: the above expression was not correct for this requirement. It still works (see code below) but defeats the purpose of binding through event handling.
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);
}
source to share