Связанный с данными TextBox не отражает изменения источника

2

Мне нужен 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 все еще заполнен Брэдом, а не Джоном. Зачем? Что это сделает?

Теги:
data-binding
listbox

3 ответа

3
Лучший ответ

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

3

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

0

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

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

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);
}
  • 0
    В моем примере я получил textBox, но есть также привязка данных к элементам управления только для чтения (listbox, label, ...). Действительно "label1.DataBindings.Add (" Text ", this," FirstName ");" такой же как "label1.Text = FirstName;" ??? Я все еще верю, что должно существовать двустороннее связывание.
  • 0
    @ Цзин, мой ответ не подходил для твоих нужд. Чтобы мой работал, нужно удалить экземпляр привязки данных перед добавлением еще одного. Другие ответы дали вам лучший дизайн.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню