Bài giảng Lập trình ứng dụng quản lý - Tuần 5: Data Binding
9/29/2019
Lập trình Ứng dụng quản lý
Data Binding
Nội dung
Data Binding
1
9/29/2019
Nội dung
Data Binding
Cơ bản Data Binding
Phần lớn các ứng dụng Winform cung cấp cho
người dùng cá ch thức hiệu quả để làm việc với
dữ liệu. Cá c dữ liệu mà người dùng sử dụng nằm
ở rất nhiều kho dữ liệu, thông dụng là cá c
database và các hệ thống tập tin. Có nhiều kỹ
thuật tương đương để trì nh bày dữ liệu như
ADO.NET, native data access APIs, custom
objects và thậm chí các web service.
Chức năng của các ứng dụng Winform tương
tác với các nguồn dữ liệu này để đọc dữ liệu,
hiển thị nó, cung cấp cá ch thức để chỉnh sửa và
ghi bất kỳ thay đổi nào về data store.
2
9/29/2019
Với rất nhiều data store và cá c data access API,
Winform đơn giản hóa xử lý với khái niệm data
source. Sự trừu tượng hó a này cho phé p
Winform xử lý các data store và các công nghệ
truy cập khá c nhau một cá ch duy nhất và nhất
quá n.
Data source cũng là nền tảng của một kỹ thuật
hiệu quả với mục đích duy nhất là đơn giản hóa
việc tích hợp các ứng dụng Winform với dữ liệu.
Công nghệ này được gọi là Data Binding.
Về logic, data binding là sự liên kết object
properties với control properties được hỗ trợ
bởi data binding engine.
Mô hì nh
3
9/29/2019
Minh họa
Xét đối tượng RaceCarDriver
class RaceCarDriver
{
string _name;
int _wins;
public string Name
{
get => _name; set => _name = value;
}
public int Wins
{
get => _wins; set => _wins = value;
}
}
Hiển thị dữ liệu
public partial class frmRaceCar : Form
{
RaceCarDriver raceCarDriver = new RaceCarDriver {
Name = "M Schumacher", Wins = 500 };
public frmRaceCar()
{
InitializeComponent();
txtName.Text = raceCarDriver.Name;
txtWins.Text = raceCarDriver.Wins.ToString();
}
}
4
9/29/2019
Cập nhật dữ liệu khi sửa đổi trên form
txtName.TextChanged += TxtName_TextChanged;
txtWins.TextChanged += TxtWins_TextChanged;
private void TxtName_TextChanged(object sender, EventArgs e)
{
raceCarDriver.Name = txtName.Text;
}
private void TxtWins_TextChanged(object sender, EventArgs e)
{
raceCarDriver.Wins = int.Parse(txtWins.Text);
}
Thay đổi dữ liệu
btnAddWin.Click += BtnAddWin_Click;
private void BtnAddWin_Click(object sender, EventArgs e)
{
raceCarDriver.Wins++;
// cập nhật hiển thị
txtWins.Text = raceCarDriver.Wins.ToString();
}
Nếu tự bản thân dữ liệu thay đổi không qua tác
động của thành phần hiển thị hiện tại?
5
9/29/2019
INotifyPropertyChanged
Thuộc namespace System.ComponentModel,
INotifyPropertyChanged chỉ có duy nhất một
thành viên là event mang tên PropertyChanged.
class RaceCarDriver : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string _name;
int _wins;
public string Name
{
get => _name;
set {
_name = value;
OnPropertyChanged("Name");
}
}
……
void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(propertyName));
}
}
Xử lý
raceCarDriver.PropertyChanged += RaceCarDriver_PropertyChanged;
private void RaceCarDriver_PropertyChanged(object sender,
PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "Name":
txtName.Text = raceCarDriver.Name;
break;
case "Wins":
txtWins.Text = raceCarDriver.Wins.ToString();
break;
}
}
6
9/29/2019
Quy trình xử lý
7
9/29/2019
Winform Data Binding
Binding object
var nameBinding = new Binding("Text", raceCarDriver,
"Name", true);
txtName.DataBindings.Add(nameBinding);
var winsBinding = new Binding("Text", raceCarDriver,
"Wins", true);
txtWins.DataBindings.Add(winsBinding);
Hầu hết các control property có thể được ràng
buộc (bind) theo cách này và được giữ đồng bộ
với public property của bất kỳ object nào.
Một binding là two-way chỉ khi object kí ch hoạt
INotifyPropertyChanged.PropertyChanged và
nếu public property là read-write
List Data Source
IList<RaceCarDriver> raceCarDrivers = new
List<RaceCarDriver> {
new RaceCarDriver{ Name = "M Schumacher", Wins = 500 },
new RaceCarDriver{ Name = "A. Senna", Wins = 700 },
new RaceCarDriver{ Name = "A. Prost", Wins = 320 },
};
txtName.DataBindings.Add("Text", raceCarDrivers, "Name");
txtWins.DataBindings.Add("Text", raceCarDrivers, "Wins");
8
9/29/2019
Navigation
Sử dụng BindingManager
BindingManagerBase BindingManager
{
get { return BindingContext[raceCarDrivers]; }
}
private void BtnPrev_Click(object sender, EventArgs e)
{
BindingManager.Position--;
}
private void BtnNext_Click(object sender, EventArgs e)
{
BindingManager.Position++;
}
private void BtnLast_Click(object sender, EventArgs e)
{
BindingManager.Position = BindingManager.Count - 1;
}
private void BtnFirst_Click(object sender, EventArgs e)
{
BindingManager.Position = 0;
}
9
9/29/2019
Complex Binding
Complex Binding ràng buộc 1 control property với
1 list data source.
dgv.DataSource = raceCarDrivers;
Thay đổi dữ liệu
private void BtnAdd_Click(object sender, EventArgs e)
{
raceCarDrivers.Add(new RaceCarDriver {
Name = "Nelson Piquet", Wins = 300
});
}
private void BtnDel_Click(object sender, EventArgs e)
{
raceCarDrivers.Remove((RaceCarDriver)BindingManager.Current);
}
Chưa cập nhật được cho phần hiển thị!
10
9/29/2019
Chức năng cần có của binding list data source
Mức độ tối thiểu của chức năng ràng buộc dữ
liệu sử dụng cho các list data source thực sự cần
bao gồm tất cả các yếu tố sau
Hỗ trợ cho cả 2 mô hì nh simple và complex binding.
Khả năng thêm, cập nhật và xóa các item trên cả
control hiển thị được ràng buộc và list data source.
Việc đưa ra các thông báo thay đổi danh sách và
cá c item trong danh sá ch.
Chức năng này và các chức năng liên quan khác
được đóng gói bởi interface ràng buộc dữ liệu
IBindingList
IBindingList
IBindingList là mở rộng của IList với chức năng
ràng buộc dữ liệu cụ thể cho các list data source.
Nếu thông báo thay đổi danh sách được hỗ trợ,
cá c control bị ràng buộc có thể gắn kết vào event
ListChanged để xử lý khi cá c item được thêm
vào, cập nhật hoặc xoá và do đó giữ dữ liệu
được hiển thị đồng bộ với nguồn dữ liệu danh
sá ch.
BindingList<T> là class triển khai IBindingList.
11
9/29/2019
BindingList<T>
Thuộc namespace System.ComponentModel, là
1 generic implementation của IBindingList.
BindingList<RaceCarDriver> raceCarDrivers = new
BindingList<RaceCarDriver> {
new RaceCarDriver{ Name = "M Schumacher", Wins = 500 },
new RaceCarDriver{ Name = "A. Senna", Wins = 700 },
new RaceCarDriver{ Name = "A. Prost", Wins = 320 },
};
private void BtnAddWin_Click(object sender, EventArgs e)
{
int iCurrent = BindingManager.Position;
raceCarDrivers[iCurrent].Wins++;
}
12
9/29/2019
BindingSource
Sử dụng để đóng gói IList có sẵn thành
IBindingList.
BindingSource raceCarDriverBS = new BindingSource();
raceCarDriverBS.DataSource = raceCarDrivers;
dgv.DataSource = raceCarDriverBS;
txtName.DataBindings.Add("Text", raceCarDriverBS, "Name");
txtWins.DataBindings.Add("Text", raceCarDriverBS, "Wins");
BindingManagerBase BindingManager
{
//get { return BindingContext[raceCarDrivers]; }
get { return BindingContext[raceCarDriverBS]; }
}
Formatting bound data
var winsBinding = new Binding("Text", raceCarDriverBS,
"Wins");
winsBinding.Format += WinsBinding_Format;
winsBinding.Parse += WinsBinding_Parse;
txtWins.DataBindings.Add(winsBinding);
13
9/29/2019
private void WinsBinding_Format(object sender, ConvertEventArgs e)
{
if (e.DesiredType == typeof(string))
{
var wins = (int)e.Value;
e.Value = string.Format("finished {0} rounds", wins);
}
}
private void WinsBinding_Parse(object sender, ConvertEventArgs e)
{
if (e.DesiredType == typeof(int))
{
var str = e.Value as string;
str = str.Replace("finished ", "");
str = str.Replace(" rounds", "");
e.Value = int.Parse(str);
}
}
14
9/29/2019
Master-Detail Forms
Bài tập
Với dữ liệu Northwind hãy xây dựng ứng dụng
đơn giản minh họa Master-Detail form [sử dụng
Category và Product] (cho phép duyệt, thêm, xóa,
sửa, thực hiện navigation và có áp dụng data
binding)
15
Bạn đang xem tài liệu "Bài giảng Lập trình ứng dụng quản lý - Tuần 5: Data Binding", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
File đính kèm:
bai_giang_lap_trinh_ung_dung_quan_ly_tuan_5_data_binding.pdf

