Databound TextBox doesn't reflect source changes
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 J开发者_JAVA技巧ohn. 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);
}
精彩评论