简体   繁体   English

数据绑定文本框不反映源更改

[英]Databound TextBox doesn't reflect source changes

I need TextBox which will reflect changes in databound string. 我需要TextBox来反映数据绑定字符串中的更改。 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. 启动应用程序后,brad会正确填充textBox1。 I clicked the Button, it renamed FirstName to "John" (second messagebox confirms it). 我单击了按钮,将“ FirstName”重命名为“ John”(第二个消息框确认了这一点)。 But the textBox1 is still filled with Brad, not with John. 但是textBox1仍然充满Brad,而不是John。 Why? 为什么? What will make this work? 什么会使这项工作?

One way is to add a FirstNameChanged event which data binding will then hook into. 一种方法是添加FirstNameChanged事件,然后将其绑定到数据绑定中。 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 (eg using INotifyPropertyChanged ) - I'm not a databinding expert by any means. 可能还有其他方法(例如,使用INotifyPropertyChanged )-无论如何,我不是数据绑定专家。

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. DataBinding之所以不能反映您的更改,是因为您要绑定一个简单的System.String对象,该对象尚未设计成在修改时会引发事件。

So you have 2 choices. 因此,您有2个选择。 One is to rebind the value when in the Click event of your button (please avoid!). 一种是在按钮的Click事件中重新绑定值(请避免!)。 The other is to make a custom class that will implement INotifyPropertyChanged like this: 另一种方法是创建一个自定义类,该类将实现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 documentation : MSDN INotifyPropertyChanged文档: MSDN

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM