I need TextBox which will reflect changes in databound string. I tried 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 launching an application, textBox1 is correctly filled with Brad.
I clicked the Button, it renamed FirstName to "John" (second messagebox confirms it).
But the textBox1 is still filled with Brad, not with John. Why? What will make this work?
The reason why the DataBinding is not reflecting your changes is because you are binding a simple System.String object which have not been designed to throw events when modified.
So you have 2 choices. One is to rebind the value when in the Click event of your button (please avoid!). The other is to make 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
One way is to add a FirstNameChanged
event which data binding will then hook into. Then raise the event when you've changed the property, and it will rebind. 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 well be other ways of doing it (e.g. using INotifyPropertyChanged
) - I'm not a databinding expert by any means.
You need to perform databinding again upon button click, else it only run once upon form instantiation.
To add: above statement wasn't the right one for the requirement. It still work (see code below), but defeats the purpose of binding via 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);
}