【问题标题】:Databound TextBox doesn't reflect source changes数据绑定文本框不反映源更改
【发布时间】:2010-12-10 01:47:40
【问题描述】:

我需要反映数据绑定字符串变化的 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。 我单击了按钮,它将 FirstName 重命名为“John”(第二个消息框确认)。 但是 textBox1 仍然充满了 Brad,而不是 John。为什么?什么会使这项工作发挥作用?

【问题讨论】:

    标签: c# data-binding listbox


    【解决方案1】:

    你需要在点击按钮时再次执行数据绑定,否则它只会在表单实例化时运行一次。

    补充一点:上述陈述不符合要求。它仍然可以工作(参见下面的代码),但违背了通过事件处理进行绑定的目的。

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

    【讨论】:

    • 我在我的示例中得到了 textBox,但也有数据绑定到只读控件 (listbox, label,...) 。真的是 "label1.DataBindings.Add("Text", this, "FirstName");"与“label1.Text = FirstName;”相同???我仍然认为必须存在双面绑定。
    • @Jing,我的回答不适合您的需要。为了让我的工作,需要在添加另一个之前删除数据绑定实例。其他答案给了你更好的设计。
    【解决方案2】:

    一种方法是添加一个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】:

      DataBinding 未反映您的更改的原因是因为您正在绑定一个简单的 System.String 对象,该对象并未设计为在修改时引发事件。

      所以你有两个选择。一种是在按钮的 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-30
        • 2011-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多