4

我读了一些关于 DataBinding 的东西,主要是复杂的东西,比如 SQL 或任何 XAML 之类的东西。我想要我的程序做的就是,如果变量的“值”发生变化,只需将其写入文本框或标签。(使用 Windows 窗体)

到目前为止我所拥有的:

namespace DataBinding_Test
{
    public partial class Form1 : Form
    {

    BindingSource bs = new BindingSource();
    Class1 test = new Class1();

    public Form1()
    {
        InitializeComponent();

        test.name = "Hello";
        bs.DataSource = test;

        label1.DataBindings.Add(new Binding("Text", bs, "name", false, DataSourceUpdateMode.OnPropertyChanged));

    }

    private void button1_Click(object sender, EventArgs e)
    {
        test.name = textBox1.Text;
    }
  }
}

Class1 只是有一个公共属性名称。在启动 lable1 将显示我的“Hello”字符串。然后在按钮上单击名称属性将更改。在调试时我看到“bs”的实际数据源包含新的属性值,但标签不会显示任何东西......

有没有真正简单的方法来做到这一点?

背景是:定期通过 RS232 轮询传感器数据。如果一个传感器的值发生变化,我想在标签或文本框中显示它。现在后台线程计时器将需要调用和东西来访问 GUI 线程;认为使用数据绑定会更容易,但似乎不是:P

谢谢大家,伟大的网站,伟大的工作!:)

4

5 回答 5

3

另一种在不实施的情况下使事情顺利进行的方法INotifyPropertyChanged

class Class1
{
    private string name;

    public string Name
    {
        get { return name; }
        set
        {
            //Check if you are assigning the same value. Depends on your business logic
            //here is the simplest check
            if (Equals(name, value))
                return;
            name = value;
            OnNameChanged();
        }

        public event EventHandler NameChanged;

        protected virtual void OnNameChanged()
        {
            var handler = NameChanged;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
    }
}

诀窍是通过属性名称和后缀组合名称的事件,并Changed在您的属性值更改时引发它

于 2013-09-13T11:45:15.137 回答
2

为了您的代码能够正常工作,您应该在绑定的类中实现INotifyPropertyChanged接口。没有它,您的绑定根本不知道何时发生更改。在那里你应该实现逻辑,根据它你会通知你的订阅者你的类什么时候发生了变化(setter 部分)和什么发生了变化(PropertyChangedEventArgs)。请参阅您的班级示例:

class Class1: INotifyPropertyChanged
{
    private string name = "";

    public string Name
    {
        get { return name; }
        set { name = value; NotifyPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged()
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }
}

并将绑定中的属性名称从“名称”更改为“名称”:

label1.DataBindings.Add(new Binding("Text", bs, "Name", false, DataSourceUpdateMode.OnPropertyChanged));
于 2013-09-13T11:44:12.747 回答
0
// create winforms project on form1 drag a textbox (testbox1)  
// and a button (button1) with a button click event handler  
// this updates the textbox when the button is clicked

using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Linq;  
using System.Text;  
using System.Windows.Forms;   

namespace WindowsFormsApplication3  
{  
    public partial class Form1 : Form  
    {  
        MyClass Myobj = new MyClass();  
        public Form1()  
        {  
            InitializeComponent(); 

            /* propertyname, datasource, datamember */  
            textBox1.DataBindings.Add("Text", Myobj, "Unit");  
        }

        public class MyClass : INotifyPropertyChanged
        {
            private int unit = 3;
            /* property change event */
            public event PropertyChangedEventHandler PropertyChanged;  

            public int Unit
            {
                get
                {
                    return this.unit;
                }
                set
                {
                    if (value != this.unit)
                    {
                        this.unit = value;
                        NotifyPropertyChanged("Unit");
                    }
                }
            }

            private void NotifyPropertyChanged(String propertyName)     
            {
                PropertyChangedEventHandler handler = PropertyChanged;  

                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
           Myobj.Unit += 4;
        }
    }
}
于 2014-08-18T11:14:33.030 回答
0

我为此创建了一个扩展方法,我想分享

用法

private void Form1_Load(object sender, EventArgs e)
        {
            ResultLabel.Bind(NameTextBox);
            WarningLabel.Bind(NameTextBox,i => i.Length == 0 ? "field required!" : "");
            SendButton.Bind(NameTextBox, i => SendButton.Enabled = !(i.Length == 0));
        }

扩大

public static class Extention
    {
        public static void Bind(this Control owner, Control dataSource)
        {
            List<EventInfo> fields = dataSource.GetType().GetEvents().ToList();
            int index = fields.FindIndex(item => item.Name == "TextChanged");
            if (index >= 0)
            {
                Control sender = dataSource as Control;
                owner.Text = dataSource.Text;
                dataSource.TextChanged += delegate (Object o, EventArgs e) { owner.Text = sender.Text; };
            }
        }

        public static void Bind(this Control owner, Control dataSource, Func<string,string> onChange)
        {
            List<EventInfo> fields = dataSource.GetType().GetEvents().ToList();
            int index = fields.FindIndex(item => item.Name == "TextChanged");
            if (index >= 0)
            {
                Control sender = dataSource as Control;
                owner.Text = onChange(sender.Text);
                dataSource.TextChanged += delegate (Object o, EventArgs e) { owner.Text = onChange(sender.Text); };
            }
        }

        public static void Bind(this Control owner, Control dataSource, Action<string> onChange)
        {
            List<EventInfo> fields = dataSource.GetType().GetEvents().ToList();
            int index = fields.FindIndex(item => item.Name == "TextChanged");
            if (index >= 0)
            {
                Control sender = dataSource as Control;
                onChange(sender.Text);
                dataSource.TextChanged += delegate (Object o, EventArgs e) { onChange(sender.Text); };
            }
        }
    }
于 2016-10-04T12:45:42.677 回答
-1

我不确定这是否是您想要的,但您可以使用 control.Text 属性将变量包含的任何内容写入文本框或标签。

textBox1.Text ="Some other Text"

或者

string variable = "Hello 2";
textBox1.Text = variable;

为什么要使用数据绑定?这样更容易。

于 2013-09-13T11:36:05.893 回答