Ở ví dụ trứơc đã xem xét tất cả
control DataGrid, đó chỉ là một phần trong thời gian chạy.NET có thể dùng
để hiển thị dữ liệu. Một tiến trình gắn kết một control và một nguồn dữ liệu
được gọi là data binding.
Nếu bạn có những kinh nghiệm với các
ứngdụng lập trình Windows trong MFC. Có lúc nào đó bạn đã sử dụng chức năng Dialog Data Exchange (DDX)để móc các biến thành
viên của một lớp với bộ điều khiển Win32. Bạn sẽ vui sướng khi biết rằng bạn có
thể giấu cửa trên DDX, như nó dễ dàng hơn để móc dữ liệu vào bộ điều khiển trong
.NET. Bạn có thể gắn kết dữ liệu không chỉ đến các bộ điều khiển Window mà còn
với các trang Web ASP.NET.
Gắn kết đơn giản
Một control hỗ trợ việc gắn kết
đơn hiển thị chỉ những giá trị đơn tại một lúc, như là một hộp văn bản hay một
nút chọn. Ví dụ sau chỉ cách gắn kết một cột từ một DataTable đến một hộp
văn bản.
DataSet ds = CreateDataSet();
textBox1.DataBindings.Add("Text", ds , "Products.ProductName");
Sau khi lấy lại vài dữ liệu từ bảng
Products và lưu trữ trong một DataSet được trả về từ phương thức CreateDataSet() như trên, dòng thứ hai gắn kết thuộc tính
Text của control đến cột Products.ProductName. Nếu bạn viết đoạn
mã này từ cơ sở dữ liệu Northwind, bạn sẽ thấy màn hình như bên dưới
đây:
Hộp văn bản hiển thị vài thứ trong
cơ sở dữ liệu. Để kiểm tra rằng nó là cột hay giá trị, bạn sẽ sử dụng công cụ
SQL Server Query Analyzer để kiểm tra nội dung của bảng
Procucttool.
Đối tượng gắn kết dữ liệu
Sơ đồ sau chỉ một thừa kế lớp
cho các đối tượng được sử dụng trong gắn kết dữ liệu. Trong phần này ta bàn luận
về BindingContext, CurrencyManager, và PropertyManager các lớp của System.Windows.Forms, và trình cách chúng tương tác khi
dữ liệu giới hạn trong một hay nhiều control trên một form. Các đối tượng chuyển
màu được dùng trong gắn kết.
Trong ví dụ trước, chúng ta sử
dụng thuộc tính DataBinding của control TextBox để gắn kết một cột
từ một DataSet đến thuộc tính Text của bộ điều khiển. Thuộc tính
DataBindings là một thể hiện của ControlBindingsCollection :
textBox1.DataBindings.Add("Text", ds, "Products.ProductName");
Dòng này thêm một đối tượng gắn kết
từ một đối tượng Binding đến ControlBindingsCollection
Binding Context
Mọi Windows form có một thuộc tính BindingContext. Form được thừa hưởng từ
Control . Một đối tượng BindingContext có một
tập thể hiện BindingManagerBase. Những thể hiện
này được tạo và thêm vào đối tượng quản lý gắn kết khi một control bị giới
hạn:
BindingContext sẽ chứa vài nguồn dữ liệu, được gói trong
một CurrencyManager hay một PropertyManager. Sự quyết định lớp nào được dùng dựa vào
chính nguồn dữ liệu.
Nếu nguồn dữ liệu chứa một dãy item
như là DataTable, DataView, hay bất kỳ đối tượng khác thực thi giao diện
IList thì một CurrencyManager sẽ được dùng,
như nó có thể duy trì vị trí hiện tại bên trong nguồn dữ liệu. Nếu nguồn dữ liệu
chỉ trả về một giá trị đơn thì một PropertyManager sẽ được lưu trữ trong BindingContext.
Một
CurrencyManager hay PropertyManager chỉ được tạo một lần cho một nguồn dữ
liệu. Nếu bạn gắn kết hai hộp văn bản với một hàng từ một DataTable thì
chỉ một currencyManager sẽ được tạo bên trong
binding context.
Mọi control thêm vào một form được
gắn kết với bộ quản lý gắn kết của form, vì thế tất cả control chia sẽ cùng một
thể hiện. Khi một control được tạo thuộc tính BindingContext của nó là
null. Khi control được thêm bộ Control của form thì nó sẽ cài
BindingContext đến bộ đó của form.
Để gắn kết một control với một form,
bạn cần thêm một thực thể vào thuộc tính DataBinding của nó. Đoạn mã bên dưới
tạo một sự gắn kết mới:
textBox1.DataBindings.Add("Text", ds, "Products.ProductName");
Phương thức
Add() của ControlBindingsCollection tạo một thể hiện mới của đối
tượng Binding từ những thông số của phương thưc này và
thêm chúng vào bộ những việc gắn kết
Hình trên trình bày những gì đang
hoạt động khi bạn thêm một Binding đến một Control. Binding gắn kết control với
một nguồn dữ liệu được duy trì bên trong BindingContext của Form. Sự thay
đổi bên trong nguồn dữ liệu được phản ánh vào control như là những thay đổi
trong control đó.
Binding
Lớp này gắn kết một thuộc tính của
control với một thành viên của nguồn dữ liệu. Khi những thành viên này thay đổi
thì những thuộc tính của control được cập nhật để phản ánh sự thay đổi này và
ngược lại
Bindings có thể cài đặt từ bất kỳ cột
nào đến bất kỳ thuộc tính nào của control, vì thế bạn sẽ gắn kết một cột với một
hộp văn bản và có thể gắn kết cột khác với màu hộp văn bản..
Bạn có thể gắn kết các thuôc tính của
một control đến các nguồn dữ liệu khác nhau .
CurrencyManager và PropertyManager
Khi một đối tượng Binding được tạo, một đối tượng CurrencyManager hay PropertyManager sẽ được tạo nếu đó là lần đầu tiên dữ
liệu đó từ nguồn bị giới hạn. Mục đích của lớp này là định nghĩa vị trí của mẫu
tin hiện hành trong nguồn dữ liệu và kết hợp tất cả dãy bindings khi mẫu tin
hiện hành này bị thay đổi.
Ví dụ sau sẽ hiển thị hai trường từ
bảng Product và bao gồm một cách để di chuyển giữa các mẫu tin bằng các
phương tiện của một control TrackBar.
Đoạn mã cho ứng dụng này nằm hoàn
toàn trong thư mục 09_ScrollingDataBinding
using System;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
public class ScrollingDataBinding : System.Windows.Forms.Form
{
private Button retrieveButton;
private TextBox textName;
private TextBox textQuan;
private TrackBar trackBar;
private DataSet ds;
Ứng dụng trên tạo cửa sổ và tất cả
control cho cửa sổ đó bên trong một hàm khởi tạo ScrollingDataBinding:
public ScrollingDataBinding()
{
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(464, 253);
this.Text = "09_ScrollingDataBinding";
this.retrieveButton = new Button();
retrieveButton.Location = new System.Drawing.Point(4, 4);
retrieveButton.Size = new System.Drawing.Size(75, 23);
retrieveButton.TabIndex = 1;
retrieveButton.Anchor = AnchorStyles.Top | AnchorStyles.Left;
retrieveButton.Text = "Retrieve";
retrieveButton.Click += new System.EventHandler
(this.retrieveButton_Click);
this.Controls.Add(this.retrieveButton);
this.textName = new TextBox();
textName.Location = new System.Drawing.Point(4, 31);
textName.Text = "Please click retrieve...";
textName.TabIndex = 2;
textName.Anchor = AnchorStyles.Top | AnchorStyles.Left |
AnchorStyles.Right ;
textName.Size = new System.Drawing.Size(456, 20);
textName.Enabled = false;
this.Controls.Add(this.textName);
this.textQuan = new TextBox();
textQuan.Location = new System.Drawing.Point(4, 55);
textQuan.Text = "";
textQuan.TabIndex = 3;
textQuan.Anchor = AnchorStyles.Top | AnchorStyles.Left |
AnchorStyles.Top;
textQuan.Size = new System.Drawing.Size(456, 20);
textQuan.Enabled = false;
this.Controls.Add(this.textQuan);
this.trackBar = new TrackBar();
trackBar.BeginInit();
trackBar.Dock = DockStyle.Bottom ;
trackBar.Location = new System.Drawing.Point(0, 275);
trackBar.TabIndex = 4;
trackBar.Size = new System.Drawing.Size(504, 42);
trackBar.Scroll += new System.EventHandler(this.trackBar_Scroll);
trackBar.Enabled = false;
this.Controls.Add(this.trackBar);
}
Khi nút Retrieve được click, sự kiện handler chọn tất cả mẫu tin
từ bảng Product và lưu trữ trong Dataset riêng ds:
protected void retrieveButton_Click(object sender, System.EventArgs e)
{
retrieveButton.Enabled = false ;
ds = CreateDataSet();
Tiếp theo là hai control văn bản được
giới hạn
textName.DataBindings.Add("Text" , ds ,
"Products.ProductName");
textQuan.DataBindings.Add("Text" , ds ,
"Products.QuantityPerUnit");
trackBar.Minimum = 0 ;
trackBar.Maximum = this.BindingContext[ds,"Products"].Count – 1;
textName.Enabled = true;
textQuan.Enabled = true;
trackBar.Enabled = true;
}
Ở đây chúng ta có một mẫu tin cuộn để
phản ứng lại với sự di chuyển của TrackBar:
protected void trackBar_Scroll(object sender , System.EventArgs e)
{
this.BindingContext[ds,"Products"].Position = trackBar.Value;
}
private DataSet CreateDataSet()
{
string source = "server=(local)\\NetSDK;" +
"uid=QSUser;pwd=QSPassword;" +
"database=northwind";
string customers = "SELECT * FROM Products";
SqlConnection con = new SqlConnection(source);
SqlDataAdapter da = new SqlDataAdapter(customers , con);
DataSet ds = new DataSet();
da.Fill(ds , "Products");
return ds;
}
static void Main()
{
Application.Run(new ScrollingDataBinding());
}
}
Khi dữ liệu được khôi phục, vị trí
lớn nhất trên track bar được cài là số lượng của mẫu tin. Sau đó, trong phương
thức scroll ở trên, chúng ta cài vị trí của BindingContext cho
DataTable products đến vị trí của scroll bar thumb. Nó thay đổi mẫu tin
hiện hành từ DataTable, vì thế tất cả control giới hạn đến hàng hiện hành