C#DataBinding - 自动将更改的属性写入标签或文本框

时间:2013-09-13 11:28:38

标签: c# data-binding windows-forms-designer

我读了一些关于DataBinding的内容,主要是复杂的东西,如SQL或其他任何XAML和东西。 我想让我的程序做的就是,如果变量的“值”改变只是将它写在文本框或标签中。 (使用WindowsForms)

到目前为止我所拥有的:

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”数据源包含新的属性值,但标签不会显示任何内容......

有没有这么简单的方法呢?

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

感谢所有,伟大的网站,伟大的工作! :)

5 个答案:

答案 0 :(得分: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后缀组合在一起的事件,并在您的属性值发生变化时将其提升

答案 1 :(得分: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"));
        }
    }
}

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

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

答案 2 :(得分: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;
        }
    }
}

答案 3 :(得分: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); };
            }
        }
    }

答案 4 :(得分:-1)

我不确定这是否是您想要的,但您可以使用control.Text属性将您包含的任何内容写入Textbox或Label。

textBox1.Text ="Some other Text"

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

为什么要使用数据绑定?它的变化更容易。