Мне нужен TextBox, который будет отражать изменения в строке привязки. Я пробовал следующий код:
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);
}
}
После запуска приложения textBox1 правильно заполняется Brad. Я нажал кнопку "Button", она переименовала FirstName в "John" (второе сообщение подтверждает это). Но textBox1 все еще заполнен Брэдом, а не Джоном. Зачем? Что это сделает?
Причина, по которой DataBinding не отражает ваши изменения, заключается в том, что вы связываете простой объект System.String, который не был предназначен для изменения событий при изменении.
Итак, у вас есть 2 варианта. Один из них заключается в том, чтобы переустановить значение, когда в событии Click вашей кнопки (пожалуйста, избегайте!). Другой - создать пользовательский класс, который будет реализовывать INotifyPropertyChanged следующим образом:
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: MSDN
Один из способов - добавить событие FirstNameChanged
, в которое привязывается привязка данных. Затем поднимите событие, когда вы изменили свойство, и оно будет переподтверждено. Например:
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());
}
}
Там могут быть другие способы сделать это (например, используя INotifyPropertyChanged
) - Я не специалист по привязке данных любыми способами.
Вам нужно выполнить привязку данных снова при нажатии кнопки, иначе он запускается только один раз после создания экземпляра формы.
Чтобы добавить: выше выражение не было правильным для этого требования. Он по-прежнему работает (см. Код ниже), но побеждает цель привязки через обработку событий.
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);
}