Связанный с данными TextBox не отражает изменения источника - PullRequest
2 голосов
/ 26 октября 2009

Мне нужен 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 правильно заполнен Брэдом. Я нажал на кнопку, она переименовала FirstName в «John» (второе сообщение подтверждает это). Но textBox1 все еще заполнен Брэдом, а не Джоном. Зачем? Что заставит это работать?

Ответы [ 3 ]

3 голосов
/ 26 октября 2009

Один из способов - добавить событие 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) - я ни в коем случае не эксперт по привязке данных.

3 голосов
/ 26 октября 2009

Причина, по которой 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

0 голосов
/ 26 октября 2009

Вам нужно снова выполнить привязку данных при нажатии кнопки, иначе она запускается только один раз при создании экземпляра формы.

Чтобы добавить: приведенное выше утверждение не было правильным для требования. Он по-прежнему работает (см. Код ниже), но не имеет смысла связывать с помощью обработки событий.

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);
}
...