我写了一些示例代码来演示我的问题。一个绑定到对象,另一个绑定到DataRow:
绑定到DataRow示例:
namespace WindowsFormsApplication1
{
public partial class frmBindExample : Form
{
public frmBindExample()
{
InitializeComponent();
InitForm();
}
private void InitForm()
{
//;; Init the list
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Id"));
dt.Columns.Add(new DataColumn("Name"));
dt.Rows.Add(new string[] { "5476", "Smith" });
dt.Rows.Add(new string[] { "5477", "Marlin" });
Label label1 = new Label() { Top = 130, Left = 10, Text = "Id of Smith is:" };
this.Controls.Add(label1);
//;; Bind two direction with TextBox.
TextBox textbox1 = new TextBox() { Top = 130, Left = 130, Width = 100 };
this.Controls.Add(textbox1);
textbox1.DataBindings.Add("Text", dt.Rows[0], "Id");
//;; The binding system respose changing property value
Button button1 = new Button() { Top = 160, Left = 10, Width = 200, Text = "Set Id=99 Directly by property" };
this.Controls.Add(button1);
button1.Click += (s, e) =>
{
dt.Rows[0]["Id"] = "99";
};
DataGridView dg = new DataGridView() { Top = 200, Left = 10 };
this.Controls.Add(dg);
dg.DataSource = dt;
}
}
}
它看起来像:
如您所见,与TextBox的绑定在下一个示例中不起作用。但是,当我通过按下按钮更新字段时,数据网格立即刷新:
好吧,现在看看如果我绑定对象,那是什么麻麻:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class frmBindExample : Form
{
public frmBindExample()
{
InitializeComponent();
InitForm();
}
private void InitForm()
{
//;; Init the list
List<Person> lst = new List<Person>();
lst.Add(new Person() { Id = "5476", Name = "Smith" });
lst.Add(new Person() { Id = "5477", Name = "Marlin" });
Label label1 = new Label() { Top = 130, Left = 10, Text = "Id of Smith is:" };
this.Controls.Add(label1);
//;; Bind two direction with TextBox.
TextBox textbox1 = new TextBox() { Top = 130, Left = 130, Width = 100 };
this.Controls.Add(textbox1);
textbox1.DataBindings.Add("Text", lst[0], "Id");
//;; The binding system respose changing property value
Button button1 = new Button() { Top = 160, Left = 10, Width = 200, Text = "Set Id=99 Directly by property" };
this.Controls.Add(button1);
button1.Click += (s, e) =>
{
lst[0].Id = "99";
};
DataGridView dg = new DataGridView() { Top = 200, Left = 10 };
this.Controls.Add(dg);
dg.DataSource = lst;
}
}
//;; The person class can bind any his property without any extra call fo change detection
public class Person
{
public string Id { get; set;}
public string Name { get; set; }
}
}
现在,TextBox在显示方面时显示Id值。但是按下“设置”按钮不会刷新DataGrid上的数据。
所以,我的问题是:
答案 0 :(得分:1)
由于在注释中描述此过程可能不是一个好主意,因此下面是放大版本。
List<T>
定义为数据存储对象(我更喜欢BindinList
,但是这里的IList
仍然可以完成工作)。 / li>
定义一个BindingSource,它将提供更改通知和货币管理。它极大地简化了WinForms中控件的绑定。
将BindingSource.DataSource属性设置为提供数据的对象:此处为 BindingList
或 IList
>。
TextBox.Text
属性中添加Binding,该属性将绑定到数据源的属性(例如,数据表的列),并设置将Binding
的{{3}}值设置为 BindingSource
,将 DataMember
值设置为以下属性(或列): TextBox属性绑定到的数据源。在这里,是 Id
类的Inputs
属性。Binding
的DataSource
,以私密方式表示在允许更新数据源之前先验证在TextBox中输入的数据。如果输入的值不符合描述要求(例如,用户输入字母而不是数字),我们可以调用例如Parse event方法来取消数据更新DataGridView.DataSource
设置为BindingSource
。
使用下面显示的代码会发生这种情况:
BindingSource.ResetCurrentItem
注意:
我在这里使用lambda订阅 Parse
事件;如果您需要多次订阅/取消订阅此事件,则可能需要使用单独的处理程序。
internal class Inputs
{
public int Id { get; set; }
public string Name { get; set; }
}
internal List<Inputs> InputData = new List<Inputs>();
internal BindingSource bindingSource;
private void button1_Click(object sender, EventArgs e)
{
bindingSource = new BindingSource();
InputData.AddRange(new [] {
new Inputs() { Id = 5476, Name = "Smith" },
new Inputs() { Id = 5477, Name = "Marlin" }
});
bindingSource.DataSource = InputData;
Binding tboxBind = new Binding("Text", bindingSource, "Id", false, DataSourceUpdateMode.OnPropertyChanged);
tboxBind.Parse += (pObj, pEvt) =>
{
if (!int.TryParse(pEvt.Value.ToString(), out int value))
bindingSource.ResetCurrentItem();
};
textBox1.DataBindings.Add(tboxBind);
dataGridView1.DataSource = bindingSource;
}
答案 1 :(得分:1)
为什么绑定文本框在第一个示例中无法正常工作?
这是因为TypeDescriptor
的{{1}}没有DataRow
属性。请考虑以下规则:
当数据绑定到项目的属性时,该项目的类型描述符应包含具有该名称的属性。
当数据绑定到列表时,列表项类型描述符应包含具有该名称的属性。
是真的吗,自动(无任何额外的do做绑定)从源到控制的传播更新仅发生在DataRow上?
不。这不是因为Id
类型。这是因为DataRow
和INotifyPropertyChanged
。请考虑以下规则:
在将控件绑定到项目时,如果该项目实现了IBindingList
,则UI将在更新项目后立即更新。
在将数据绑定到列表控件时,如果项目实现INotifyPropertyChanged
而列表实现INotifyPropertyChanged
,则在更新项目或列表后立即更新UI。
更多信息
简而言之,您可以在Windows Forms Data Binding中找到详细信息。我建议阅读以下有用的文档: