我读了一些关于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
感谢所有,伟大的网站,伟大的工作! :)
答案 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;
为什么要使用数据绑定?它的变化更容易。