假设我们有一个实体类,需要将它的属性绑定到控件的某个属性(如TextBox.Text)上去。绑定会两个情况,单向绑定和双向绑定。
首先我们假定有一个用于数据绑定的实体类:
class Enbox
{
public string Payor { get ;set }
}
然后创建这个对象:
Enbox enbox =new Enbox()
单向绑定是最简单的数据绑定,即将控件的某个属性绑定到实体类的属性上去,只要一条语句就行。
TextBox.DataBindings.Add("Text", enbox, "Payor");
意思是将 TextBox.Text 属性绑定到 enbox.Payor 属性上。结果就是只要 TextBox.Text 属性的值一改变,就会立即被更新到 enbox.Payor 属性上。
顾名思义,就是不但能将控件的某个属性更新到实体类的某个属性上去,同时还能反向将实体类的属性更新到控件的属性上去
要实现双向数据绑定除了上面的绑定语句外,还需在实现类 Enbox 实现一个接口:INotifyPropertyChanged 这是实现双向绑定的关键
这个接口就是一个事件方法。实现代码如下:
class Enbox : INotifyPropertyChanged
{
//属性不能简写了,因为在 set 里还要执行事件
string payor;
public string Payor
{
get { return payor ; }
set { payor = value; OnPropertyChanged(“Payor”); }
}
//实现 INotifyPropertyChanged 接口
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
//上面 set 里的OnPropertyChanged(“Payor”) 可改为OnPropertyChanged(nameof(Payor)) ,在属性名被修改时会自动更新其名字,更方便。
同样,不要忘记了在UI类里加上:TextBox.DataBindings.Add("Text", enbox, "Payor");
以上就实现了控件到数据对象的双向绑定
若按上面代码实现了数据绑定后,我们发现在正常界面上修改控件值时都会更新到数据对象上,但若手动用代码去修改了控件的属性值 则很有可能不会发生对数据对象的更新。这时就要引出这个【大坑】了:数据的更新模式:DataSourceUpdateMode 与 ControlUpdateMode
DataSourceUpdateMode 它是一个枚举,有三个值:
DataSourceUpdateMode.OnPropertyChanged //每当控件属性的值更改时,将更新数据源
DataSourceUpdateMode.OnValidation //当验证控件属性后,更新数据源
DataSourceUpdateMode.Never //不会更新数据源
ControlUpdateMode 它是也一个枚举,有二个值:
ControlUpdateMode.OnValidation //当数据源值更改时,将更新绑定的控件
ControlUpdateMode.Never //当数据源值更改时,永远不会更新绑定的控件
在进行数据绑定时,控件和数据源之间会通过一个Binging类 进行关联,即便你用的是TextBox.DataBindings.Add("Text", enbox, "Payor");方式进行的绑定,在其内部还是生成了Binging对象的,你可以通过控件的Control.DataBindings[index],获取这个对象。
Binging 对象上能找到两个属性:
binging.DataSourceUpdateMode 对应 DataSourceUpdateMode
binging.ControlUpdateMode 对应 ControlUpdateMode
binging.DataSourceUpdateMode 默认的值是 DataSourceUpdateMode.OnValidation
binging.ControlUpdateMode 默认的值是 DataSourceUpdateMode.OnPropertyChanged
看出来区别了吧?是的,就是因为binging.DataSourceUpdateMode 的默认值为DataSourceUpdateMode.OnValidation,它是在当验证控件属性后,才会更新数据源,这里如果你是通过代码修改了控件的值时,那它将不会把值更新到数据源。因为你通过代码修改会绕过控件的数据验证,也就是控件的Validation事件不会发生,所以自然就不会更新数据源了。
将它更改为 binging.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged 即可